diff --git a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java
index d65a15f..0d28a50 100644
--- a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java
+++ b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java
@@ -11,24 +11,12 @@
 import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFErrorMsg;
-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.OFPortDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFPortOptical;
 import org.projectfloodlight.openflow.protocol.OFStatsReply;
 import org.projectfloodlight.openflow.protocol.OFStatsType;
-import org.projectfloodlight.openflow.protocol.action.OFAction;
-import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmInPort;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigid;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigtype;
-import org.projectfloodlight.openflow.types.CircuitSignalID;
-import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.types.U8;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -131,12 +119,6 @@
                             (OFCircuitPortsReply) m);
                     driverHandshakeComplete.set(true);
                 }
-                /*try {
-                    testMA();
-                    testReverseMA();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }*/
                 break;
             default:
                 log.warn("Received message {} during switch-driver " +
@@ -190,7 +172,6 @@
         this.write(Collections.<OFMessage>singletonList(circuitPortsRequest));
     }
 
-
     @Override
     public List<OFPortDesc> getPorts() {
         List<OFPortDesc> portEntries = new ArrayList<>();
@@ -201,358 +182,6 @@
         return Collections.unmodifiableList(portEntries);
     }
 
-
-    public static final U8 SIGNAL_TYPE = U8.of((short) 10);
-    private void testMA() throws IOException {
-        log.debug("LINC OE *** Testing MA ");
-        short lambda = 1;
-        if (getId() == 0x0000ffffffffff01L) {
-            final int inport = 10;
-            final int outport = 20;
-            //Circuit signal id
-            CircuitSignalID sigID = getSignalID(lambda);
-
-            OFOxmOchSigidBasic ofOxmOchSigidBasic =
-                    factory().oxms().ochSigidBasic(sigID);
-
-
-            //Match Port
-            OFOxmInPort fieldPort = factory().oxms()
-                                                .inPort(OFPort.of(inport));
-            OFMatchV3 matchPort =
-                    factory()
-                            .buildMatchV3().
-                            setOxmList(OFOxmList.of(fieldPort)).build();
-
-
-            // Set Action outport ,sigType and sigID
-            List<OFAction> actionList = new ArrayList<>();
-            OFAction actionOutPort =
-                    factory().actions().output(OFPort.of(outport),
-                                                  0xffff);
-
-            OFActionCircuit actionCircuit = factory()
-                    .actions()
-                    .circuit(ofOxmOchSigidBasic);
-
-            actionList.add(actionCircuit);
-            actionList.add(actionOutPort);
-
-            OFInstruction instructionAction =
-                    factory().instructions().buildApplyActions()
-                                .setActions(actionList)
-                                .build();
-            List<OFInstruction> instructions =
-                    Collections.singletonList(instructionAction);
-
-            OFMessage opticalFlowEntry =
-                    factory().buildFlowAdd()
-                                .setMatch(matchPort)
-                                .setPriority(100)
-                                .setInstructions(instructions)
-                                .setXid(getNextTransactionId())
-                                .build();
-            log.debug("Adding optical flow in sw {}", getStringId());
-            List<OFMessage> msglist = new ArrayList<>(1);
-            msglist.add(opticalFlowEntry);
-            write(msglist);
-            sendBarrier(true);
-        } else if (getId() == 0x0000ffffffffff03L) {
-            final int inport = 30;
-            final int outport = 31;
-            //Circuit signal id
-            CircuitSignalID sigID = getSignalID(lambda);
-
-            OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
-            OFOxmOchSigtype fieldSigType = factory()
-                    .oxms()
-                    .ochSigtype(SIGNAL_TYPE);
-
-            OFOxmOchSigidBasic ofOxmOchSigidBasic =
-                    factory().oxms().ochSigidBasic(sigID);
-
-            //Match Port,SigType,SigID
-            OFOxmInPort fieldPort = factory()
-                    .oxms()
-                    .inPort(OFPort.of(inport));
-            OFMatchV3 matchPort = factory()
-                    .buildMatchV3()
-                    .setOxmList(OFOxmList.of(fieldPort,
-                                             fieldSigIDMatch,
-                                             fieldSigType
-                    ))
-                    .build();
-
-            // Set Action outport ,SigType, sigID
-            List<OFAction> actionList = new ArrayList<>();
-            OFAction actionOutPort =
-                    factory().actions().output(OFPort.of(outport),
-                                                  0xffff);
-
-            OFActionCircuit actionCircuit = factory()
-                    .actions()
-                    .circuit(ofOxmOchSigidBasic);
-
-
-
-            //actionList.add(setActionSigType);
-            actionList.add(actionCircuit);
-            actionList.add(actionOutPort);
-
-            OFInstruction instructionAction =
-                    factory().instructions().buildApplyActions()
-                                .setActions(actionList)
-                                .build();
-            List<OFInstruction> instructions =
-                    Collections.singletonList(instructionAction);
-
-            OFMessage opticalFlowEntry =
-                    factory().buildFlowAdd()
-                                .setMatch(matchPort)
-                                .setPriority(100)
-                                .setInstructions(instructions)
-                                .setXid(getNextTransactionId())
-                                .build();
-            log.debug("Adding optical flow in sw {}", getStringId());
-            List<OFMessage> msglist = new ArrayList<>(1);
-            msglist.add(opticalFlowEntry);
-            write(msglist);
-            sendBarrier(true);
-
-        } else if (getId() == 0x0000ffffffffff02L) {
-            final int inport = 21;
-            final int outport = 11;
-            //Circuit signal id
-            CircuitSignalID sigID = getSignalID(lambda);
-
-            OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
-            OFOxmOchSigtype fieldSigType = factory()
-                    .oxms()
-                    .ochSigtype(SIGNAL_TYPE);
-
-
-            //Match Port, sig type and sig id
-            OFOxmInPort fieldPort = factory()
-                    .oxms()
-                    .inPort(OFPort.of(inport));
-            OFMatchV3 matchPort =
-                    factory().buildMatchV3()
-                                .setOxmList(OFOxmList.of(fieldPort,
-                                                         fieldSigIDMatch,
-                                                         fieldSigType
-                                ))
-                                .build();
-
-            // Set Action outport
-            List<OFAction> actionList = new ArrayList<>();
-            OFAction actionOutPort =
-                    factory().actions().output(OFPort.of(outport),
-                                                  0xffff);
-
-            actionList.add(actionOutPort);
-
-            OFInstruction instructionAction =
-                    factory().instructions().buildApplyActions()
-                                .setActions(actionList)
-                                .build();
-            List<OFInstruction> instructions =
-                    Collections.singletonList(instructionAction);
-
-            OFMessage opticalFlowEntry =
-                    factory().buildFlowAdd()
-                                .setMatch(matchPort)
-                                .setPriority(100)
-                                .setInstructions(instructions)
-                                .setXid(getNextTransactionId())
-                                .build();
-            log.debug("Adding optical flow in sw {}", getStringId());
-            List<OFMessage> msglist = new ArrayList<>(1);
-            msglist.add(opticalFlowEntry);
-            write(msglist);
-            sendBarrier(true);
-        }
-
-    }
-    private void testReverseMA() throws IOException {
-        log.debug("LINC OE *** Testing MA ");
-        short lambda = 1;
-        if (getId() == 0x0000ffffffffff02L) {
-            final int inport = 11;
-            final int outport = 21;
-            //Circuit signal id
-            CircuitSignalID sigID = getSignalID(lambda);
-
-            OFOxmOchSigidBasic ofOxmOchSigidBasic =
-                    factory().oxms().ochSigidBasic(sigID);
-
-            //Match Port
-            OFOxmInPort fieldPort = factory().oxms()
-                                                .inPort(OFPort.of(inport));
-            OFMatchV3 matchPort =
-                    factory()
-                            .buildMatchV3().
-                            setOxmList(OFOxmList.of(fieldPort)).build();
-
-
-            // Set Action outport ,sigType and sigID
-            List<OFAction> actionList = new ArrayList<>();
-            OFAction actionOutPort =
-                    factory().actions().output(OFPort.of(outport),
-                                                  0xffff);
-
-            OFActionCircuit actionCircuit = factory()
-                    .actions()
-                    .circuit(ofOxmOchSigidBasic);
-            actionList.add(actionCircuit);
-            actionList.add(actionOutPort);
-
-            OFInstruction instructionAction =
-                    factory().instructions().buildApplyActions()
-                                .setActions(actionList)
-                                .build();
-            List<OFInstruction> instructions =
-                    Collections.singletonList(instructionAction);
-
-            OFMessage opticalFlowEntry =
-                    factory().buildFlowAdd()
-                                .setMatch(matchPort)
-                                .setPriority(100)
-                                .setInstructions(instructions)
-                                .setXid(getNextTransactionId())
-                                .build();
-            log.debug("Adding optical flow in sw {}", getStringId());
-            List<OFMessage> msglist = new ArrayList<>(1);
-            msglist.add(opticalFlowEntry);
-            write(msglist);
-            sendBarrier(true);
-        } else if (getId() == 0x0000ffffffffff03L) {
-            final int inport = 31;
-            final int outport = 30;
-            //Circuit signal id
-            CircuitSignalID sigID = getSignalID(lambda);
-
-            OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
-            OFOxmOchSigtype fieldSigType = factory()
-                    .oxms()
-                    .ochSigtype(SIGNAL_TYPE);
-
-            OFOxmOchSigidBasic ofOxmOchSigidBasic =
-                    factory().oxms().ochSigidBasic(sigID);
-
-            //Match Port,SigType,SigID
-            OFOxmInPort fieldPort = factory()
-                    .oxms()
-                    .inPort(OFPort.of(inport));
-            OFMatchV3 matchPort = factory()
-                    .buildMatchV3()
-                    .setOxmList(OFOxmList.of(fieldPort,
-                                             fieldSigIDMatch,
-                                             fieldSigType
-                    ))
-                    .build();
-
-            // Set Action outport ,SigType, sigID
-            List<OFAction> actionList = new ArrayList<>();
-            OFAction actionOutPort =
-                    factory().actions().output(OFPort.of(outport),
-                                                  0xffff);
-            OFActionCircuit actionCircuit = factory()
-                    .actions()
-                    .circuit(ofOxmOchSigidBasic);
-
-            actionList.add(actionCircuit);
-            actionList.add(actionOutPort);
-
-            OFInstruction instructionAction =
-                    factory().instructions().buildApplyActions()
-                                .setActions(actionList)
-                                .build();
-            List<OFInstruction> instructions =
-                    Collections.singletonList(instructionAction);
-
-            OFMessage opticalFlowEntry =
-                    factory().buildFlowAdd()
-                                .setMatch(matchPort)
-                                .setPriority(100)
-                                .setInstructions(instructions)
-                                .setXid(getNextTransactionId())
-                                .build();
-            log.debug("Adding optical flow in sw {}", getStringId());
-            List<OFMessage> msglist = new ArrayList<>(1);
-            msglist.add(opticalFlowEntry);
-            write(msglist);
-            sendBarrier(true);
-
-        } else if (getId() == 0x0000ffffffffff01L) {
-            final int inport = 20;
-            final int outport = 10;
-            //Circuit signal id
-            CircuitSignalID sigID = getSignalID(lambda);
-
-            OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
-            OFOxmOchSigtype fieldSigType = factory()
-                    .oxms()
-                    .ochSigtype(SIGNAL_TYPE);
-
-
-            //Match Port, sig type and sig id
-            OFOxmInPort fieldPort = factory()
-                    .oxms()
-                    .inPort(OFPort.of(inport));
-            OFMatchV3 matchPort =
-                    factory().buildMatchV3()
-                                .setOxmList(OFOxmList.of(fieldPort,
-                                                         fieldSigIDMatch,
-                                                         fieldSigType
-                                ))
-                                .build();
-
-            // Set Action outport
-            List<OFAction> actionList = new ArrayList<>();
-            OFAction actionOutPort =
-                    factory().actions().output(OFPort.of(outport),
-                                                  0xffff);
-
-            actionList.add(actionOutPort);
-
-            OFInstruction instructionAction =
-                    factory().instructions().buildApplyActions()
-                                .setActions(actionList)
-                                .build();
-            List<OFInstruction> instructions =
-                    Collections.singletonList(instructionAction);
-
-            OFMessage opticalFlowEntry =
-                    factory().buildFlowAdd()
-                                .setMatch(matchPort)
-                                .setPriority(100)
-                                .setInstructions(instructions)
-                                .setXid(getNextTransactionId())
-                                .build();
-            log.debug("Adding optical flow in sw {}", getStringId());
-            List<OFMessage> msglist = new ArrayList<>(1);
-            msglist.add(opticalFlowEntry);
-            write(msglist);
-            sendBarrier(true);
-        }
-
-    }
-
-
-    // Todo remove - for testing purpose only
-    private static CircuitSignalID getSignalID(short lambda) {
-        byte myGrid = 1;
-        byte myCs = 2;
-        short myCn = lambda;
-        short mySw = 1;
-
-        CircuitSignalID signalID = new CircuitSignalID(myGrid,
-                                                       myCs,
-                                                       myCn,
-                                                       mySw);
-        return signalID;
-    }
-
     private void sendBarrier(boolean finalBarrier) throws IOException {
         int xid = getNextTransactionId();
         if (finalBarrier) {
