diff --git a/apps/oecfg/pom.xml b/apps/oecfg/pom.xml
new file mode 100644
index 0000000..8f595db
--- /dev/null
+++ b/apps/oecfg/pom.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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-apps</artifactId>
+        <version>1.3.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-app-oecfg</artifactId>
+    <packaging>jar</packaging>
+
+    <description>Standalone utility for converting ONOS JSON config to OE-Linc JSON config</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <transformers>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <manifestEntries>
+                                        <Main-Class>org.onosproject.oecfg.OELinkConfig</Main-Class>
+                                    </manifestEntries>
+                                </transformer>
+                            </transformers>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/apps/oecfg/src/main/java/org/onosproject/oecfg/OELinkConfig.java b/apps/oecfg/src/main/java/org/onosproject/oecfg/OELinkConfig.java
new file mode 100644
index 0000000..480640c
--- /dev/null
+++ b/apps/oecfg/src/main/java/org/onosproject/oecfg/OELinkConfig.java
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ */
+package org.onosproject.oecfg;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility program to convert standard ONOS config JSON to format expected
+ * by the OE Link switch.
+ */
+public final class OELinkConfig {
+
+    private ObjectMapper mapper = new ObjectMapper();
+    private Map<String, String> dpidToName = new HashMap<>();
+
+    public static void main(String[] args) {
+        try {
+            OELinkConfig config = new OELinkConfig();
+            JsonNode json = config.convert(System.in);
+            System.out.println(json.toString());
+        } catch (IOException e) {
+            System.err.println("Unable to convert JSON due to: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    private OELinkConfig() {
+    }
+
+    private JsonNode convert(InputStream input) throws IOException {
+        JsonNode json = mapper.readTree(input);
+        ObjectNode result = mapper.createObjectNode();
+        result.set("switchConfig", opticalSwitches(json));
+        result.set("linkConfig", opticalLinks(json));
+        return result;
+    }
+
+    private JsonNode opticalSwitches(JsonNode json) {
+        ArrayNode result = mapper.createArrayNode();
+        for (JsonNode node : json.get("devices")) {
+            String dpid = dpid(node.path("uri"));
+            String name = node.path("name").asText("none");
+            dpidToName.put(dpid, name);
+            if (node.path("type").asText("none").equals("ROADM")) {
+                result.add(opticalSwitch(dpid, name, (ObjectNode) node));
+            }
+        }
+        return result;
+    }
+
+    private ObjectNode opticalSwitch(String dpid, String name, ObjectNode node) {
+        ObjectNode result = mapper.createObjectNode();
+        ObjectNode annot = (ObjectNode) node.path("annotations");
+        result.put("allowed", true).put("type", "Roadm")
+                .put("name", name).put("nodeDpid", dpid)
+                .put("latitude", annot.path("latitude").asDouble(0.0))
+                .put("longitude", annot.path("longitude").asDouble(0.0))
+                .set("params", switchParams(annot));
+        return result;
+    }
+
+    private ObjectNode switchParams(ObjectNode annot) {
+        return mapper.createObjectNode()
+                .put("numRegen", annot.path("optical.regens").asInt(0));
+    }
+
+    private JsonNode opticalLinks(JsonNode json) {
+        ArrayNode result = mapper.createArrayNode();
+        for (JsonNode node : json.get("links")) {
+            if (node.path("type").asText("none").equals("OPTICAL")) {
+                result.add(opticalLink((ObjectNode) node));
+            }
+        }
+        return result;
+    }
+
+    private ObjectNode opticalLink(ObjectNode node) {
+        ObjectNode result = mapper.createObjectNode();
+        ObjectNode annot = (ObjectNode) node.path("annotations");
+        String src = dpid(node.path("src"));
+        String dst = dpid(node.path("dst"));
+        result.put("allowed", true).put("type", linkType(annot))
+                .put("nodeDpid1", src).put("nodeDpid2", dst)
+                .set("params", linkParams(src, dst, node, annot));
+        return result;
+    }
+
+    private String linkType(ObjectNode annot) {
+        return annot.path("optical.type").asText("cross-connect").equals("WDM") ?
+                "wdmLink" : "pktOptLink";
+    }
+
+    private ObjectNode linkParams(String src, String dst,
+                                  ObjectNode node, ObjectNode annot) {
+        ObjectNode result = mapper.createObjectNode()
+                .put("nodeName1", dpidToName.get(src))
+                .put("nodeName2", dpidToName.get(dst))
+                .put("port1", port(node.path("src")))
+                .put("port2", port(node.path("dst")));
+        if (annot.has("bandwidth")) {
+            result.put("bandwidth", annot.path("bandwidth").asInt());
+        }
+        if (annot.has("optical.waves")) {
+            result.put("numWaves", annot.path("optical.waves").asInt());
+        }
+        return result;
+    }
+
+    private String dpid(JsonNode node) {
+        String s = node.asText("of:0000000000000000").substring(3);
+        return s.substring(0, 2) + ":" + s.substring(2, 4) + ":" +
+                s.substring(4, 6) + ":" + s.substring(6, 8) + ":" +
+                s.substring(8, 10) + ":" + s.substring(10, 12) + ":" +
+                s.substring(12, 14) + ":" + s.substring(14, 16);
+    }
+
+    private int port(JsonNode node) {
+        return Integer.parseInt(node.asText("of:0000000000000000/0").substring(20));
+    }
+
+}
diff --git a/apps/pom.xml b/apps/pom.xml
index e08f306..e30973e 100644
--- a/apps/pom.xml
+++ b/apps/pom.xml
@@ -41,6 +41,7 @@
         <module>sdnip</module>
         <module>optical</module>
         <module>metrics</module>
+        <module>oecfg</module>
         <module>routing</module>
         <module>routing-api</module>
         <module>reactive-routing</module>
diff --git a/tools/test/topos/opticalUtils.py b/tools/test/topos/opticalUtils.py
index 3315ce6..5b47d53 100644
--- a/tools/test/topos/opticalUtils.py
+++ b/tools/test/topos/opticalUtils.py
@@ -4,7 +4,7 @@
 Notes:
 
 This file contains classes and methods useful for integrating LincOE with Mininet, 
-such as startOE, stopOE, OpticalLink, and OpticalSwitch
+such as startOE, stopOE, LINCLink, and OpticalSwitch
 
 - $ONOS_ROOT ust be set
 - Need to run with sudo -E to preserve ONOS_ROOT env var
@@ -22,10 +22,10 @@
 
             Usage:
         ------------
-    - import OpticalLink and OpticalSwitch from this module
+    - import LINCLink and OpticalSwitch from this module
     - import startOE and stopOE from this module
     - create topology as you would a normal topology. when 
-      to an optical switch with topo.addLink, always specify cls=OpticalLink
+      to an optical switch with topo.addLink, always specify cls=LINCLink
     - when creating an optical switch, use cls=OpticalSwitch in topo.addSwitch
     - for annotations on links and switches, a dictionary must be passed in as
       the annotations argument
@@ -51,11 +51,12 @@
 Topology configuration file to ONOS.
 
 '''
-
+import sys
 import re
 import json
 import os
 from time import sleep
+import urllib2
 
 from mininet.node import Switch, RemoteController
 from mininet.topo import Topo
@@ -65,25 +66,127 @@
 from mininet.link import Link, Intf
 from mininet.cli import CLI
 
-class OpticalSwitch( Switch ):
+# Sleep time and timeout values in seconds
+SLEEP_TIME = 2
+TIMEOUT = 60
 
-    def __init__( self, name, dpid=None, allowed=True,
-                  switchType='ROADM', annotations={}, **params ):
+class OpticalSwitch(Switch):
+    """
+    For now, same as Switch class.
+    """
+    pass
+
+class OpticalIntf(Intf):
+    """
+    For now,same as Intf class.
+    """
+    pass
+
+class OpticalLink(Link):
+    """
+    For now, same as Link.
+    """
+    pass
+
+class LINCSwitch(OpticalSwitch):
+    """
+    LINCSwitch class
+    """
+    # FIXME:Sometimes LINC doesn't remove pipes and on restart increase the pipe
+    # number from erlang.pipe.1.* to erlang.pipe.2.*, so should read and write
+    # from latest pipe files. For now we are removing all the pipes before
+    # starting LINC.
+    ### User Name ###
+    user = os.getlogin()
+    ### pipes ###
+    readPipe = "/tmp/home/{}/linc-oe/rel/linc/erlang.pipe.1.r".format(user)
+    writePipe = "/tmp/home/{}/linc-oe/rel/linc/erlang.pipe.1.w".format(user)
+    ### sys.config path ###
+    sysConfig = "/home/{}/linc-oe/rel/linc/releases/1.0/sys.config".format(user)
+    ### method, mapping dpid to LINC switchId ###
+    @staticmethod
+    def dpids_to_ids(sysConfig):
+        '''
+        return the dict containing switch dpids as key and LINC switch id as values
+        '''
+        dpids_to_ids = {}
+        fd = None
+        try:
+            with open(sysConfig, 'r', 0) as fd:
+                switch_id = 1
+                for line in fd:
+                    dpid = re.search(r'([0-9A-Fa-f]{2}[:-]){7}([0-9A-Fa-f]{2})+', line, re.I)
+                    if dpid:
+                        dpids_to_ids[dpid.group().replace(':', '')] = switch_id
+                        switch_id += 1
+            return dpids_to_ids     
+        except:
+            print "Error working with {}\nError: {}\n".format(sysConfig, sys.exc_info())
+            fd.close()
+            return None
+    ### dict of containing dpids as key and corresponding LINC switchId as values ###
+    dpidsToLINCSwitchId = dpids_to_ids.__func__(sysConfig)
+    @staticmethod
+    def findDir(directory, userName):
+        "finds and returns the path of any directory in the user's home directory"
+        homeDir = '/home/' + userName
+        Dir = quietRun('find %s -maxdepth 1 -name %s -type d' % (homeDir, directory)).strip('\n')
+        DirList = Dir.split('\n')
+        if not Dir:
+            return None
+        elif len(DirList) > 1 :
+            warn('***WARNING: Found multiple instances of %s; using %s\n'
+                     % (directory, DirList[ 0 ]))
+            return DirList[ 0 ]
+        else:
+            return Dir
+    ### ONOS Directory ###
+    try:
+        onosDir = os.environ[ 'ONOS_ROOT' ]
+    except:
+        onosDir = findDir('onos', user)
+        if not onosDir:
+            error('Please set ONOS_ROOT environment variable!\n')
+        else:
+            os.environ[ 'ONOS_ROOT' ] = onosDir
+    ### LINC-directory
+    lincDir = findDir.__func__('linc-oe', user)
+    if not lincDir:
+        error("***ERROR: Could not find linc-oe in user's home directory\n")
+    ### LINC config generator directory###
+    configGen = findDir.__func__('LINC-config-generator', user)
+    if not configGen:
+        error("***ERROR: Could not find LINC-config-generator in user's home directory\n")
+    # list of all the controllers
+    controllers = None
+    def __init__(self, name, dpid=None, allowed=True,
+                  switchType='ROADM', topo=None, annotations={}, controller=None, **params):
         params[ 'inNamespace' ] = False
-        Switch.__init__( self, name, dpid=dpid, **params )
+        Switch.__init__(self, name, dpid=dpid, **params)
         self.name = name
         self.annotations = annotations
         self.allowed = allowed
         self.switchType = switchType
-        self.configDict = {} # dictionary that holds all of the JSON configuration data
+        self.configDict = {}  # dictionary that holds all of the JSON configuration data
+        self.crossConnects = []
+        self.deletedCrossConnects = []
+        self.controller = controller
+        self.lincId = self._get_linc_id()  # use to communicate with LINC
+        self.lincStarted = False
 
-    def start( self, *opts, **params ):
+    def start(self, *opts, **params):
         '''Instead of starting a virtual switch, we build the JSON
            dictionary for the emulated optical switch'''
+        # TODO:Once LINC has the ability to spawn network element dynamically
+        # we need to use this method to spawn new logical LINC switch rather then
+        # bulding JSON.
+        # if LINC is started then we can start and stop logical switches else create JSON
+        if self.lincStarted:
+            return self.start_oe()
         self.configDict[ 'uri' ] = 'of:' + self.dpid
         self.configDict[ 'annotations' ] = self.annotations
-        self.configDict[ 'annotations' ].setdefault( 'name', self.name )
-        self.configDict[ 'hw' ] = 'OE'
+        self.configDict[ 'annotations' ].setdefault('name', self.name)
+        self.configDict[ 'hw' ] = 'LINC-OE'
         self.configDict[ 'mfr' ] = 'Linc'
         self.configDict[ 'mac' ] = 'ffffffffffff' + self.dpid[-2] + self.dpid[-1]
         self.configDict[ 'type' ] = self.switchType
@@ -92,74 +195,441 @@
             if intf.name == 'lo':
                 continue
             else:
-                self.configDict[ 'ports' ].append( intf.json() )
+                self.configDict[ 'ports' ].append(intf.json())
+        self.lincStarted = True
 
+    def stop(self, deleteIntfs=False):
+        '''
+        stop the existing switch
+        '''
+        # TODO:Add support for deleteIntf
+        self.stop_oe()
 
-    def json( self ):
-        "return json configuration dictionary for switch"
-        return self.configDict
-    
-    def terminate( self ):
+    def dpctl( self, *args ):
+        "Run dpctl command: ignore for now"
         pass
 
-class OpticalLink( Link ):
+    def write_to_cli(self, command):
+        '''
+        send command to LINC
+        '''
+        fd = None
+        try:
+            fd = open(self.writePipe, 'w', 0)
+            fd.write(command)
+            fd.close()
+        except:
+            print "Error working with {}\nError: {}\n".format(self.writePipe, sys.exc_info())
+            if fd:
+                fd.close()
 
-    def __init__( self, node1, node2, port1=None, port2=None, allowed=True,
+    def read_from_cli(self):
+        '''
+        read the output from the LINC CLI
+        '''
+        response = None
+        fd = None
+        try:
+            fd = open(self.readPipe, 'r', 0)
+            fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK)  # for non-blocking read
+            # FIXME:Due to non-blocking read most for the time we read nothing
+            response = fd.read()
+            fd.close()
+        except :
+            # print "Error working with {}\nError: {}\n".format(self.readPipe, sys.exc_info())
+            if fd:
+                fd.close()
+        return response
+
+    def _get_linc_id(self):
+        '''
+        return the corresponding LINC switchId.
+        '''
+        return LINCSwitch.dpidsToLINCSwitchId.get(self.dpid)
+    #--------------------------------------------------------------------------
+    # LINC CLI commands
+    #--------------------------------------------------------------------------
+    def start_oe(self):
+        '''
+        start the existing LINC switch
+        '''
+        #starting Switch
+        cmd = "linc:start_switch({}).\r\n".format(self.lincId)
+        self.write_to_cli(cmd)
+        #hanlding taps interfaces related to the switch
+        crossConnectJSON = {}
+        linkConfig = []
+        for i in range(0,len(self.deletedCrossConnects)):
+            crossConnect = self.deletedCrossConnects.pop()
+            tap = None
+            if isinstance(crossConnect.intf1.node, LINCSwitch):
+                intf = crossConnect.intf2
+                tapPort = crossConnect.intf1.port
+            else:
+                intf = crossConnect.intf1
+                tapPort = crossConnect.intf2.port
+            tap = LINCSwitch.findTap(self, tapPort)
+            if tap:
+                LINCSwitch.setupInts([tap])
+                intf.node.attach(tap)
+            self.crossConnects.append(crossConnect)
+            linkConfig.append(crossConnect.json())
+        #Sending crossConnect info to the ONOS.
+        crossConnectJSON['links'] = linkConfig
+        with open("crossConnect.json", 'w') as fd:
+            json.dump(crossConnectJSON, fd, indent=4, separators=(',', ': '))
+        info('*** Pushing crossConnect.json to ONOS\n')
+        output = quietRun('%s/tools/test/bin/onos-topo-cfg %s\
+         Topology.json' % (self.onosDir, self.controllers[ 0 ].ip), shell=True)
+
+    def stop_oe(self):
+        '''
+        stop the existing LINC switch
+        '''
+        cmd = "linc:stop_switch({}).\r\n".format(self.lincId)
+        self.write_to_cli(cmd)
+        #handling taps if any
+        for i in range(0, len(self.crossConnects)):
+            crossConnect = self.crossConnects.pop()
+            if isinstance(crossConnect.intf1.node, LINCSwitch):
+                intf = crossConnect.intf2
+                tapPort = crossConnect.intf1.port
+            else:
+                intf = crossConnect.intf1
+                tapPort = crossConnect.intf2.port
+            intf.node.detach(LINCSwitch.findTap(self, tapPort))
+            self.deletedCrossConnects.append(crossConnect)
+
+    def w_port_up(self, port):
+        '''
+        port_up
+        '''
+        cmd = "linc:port_up({},{}).\r\n".format(self.lincId, port)
+        self.write_to_cli(cmd)
+
+    def w_port_down(self, port):
+        '''
+        port_down
+        '''
+        cmd = "linc:port_down({},{}).\r\n".format(self.lincId, port)
+        self.write_to_cli(cmd)
+
+    # helper functions
+    @staticmethod
+    def switchJSON(switch):
+        "Returns the json configuration for a packet switch"
+        configDict = {}
+        configDict[ 'uri' ] = 'of:' + switch.dpid
+        configDict[ 'mac' ] = quietRun('cat /sys/class/net/%s/address' % switch.name).strip('\n').translate(None, ':')
+        configDict[ 'hw' ] = 'PK'  # FIXME what about OVS?
+        configDict[ 'mfr' ] = 'Linc'  # FIXME what about OVS?
+        configDict[ 'type' ] = 'SWITCH'  # FIXME what about OVS?
+        annotations = switch.params.get('annotations', {})
+        annotations.setdefault('name', switch.name)
+        configDict[ 'annotations' ] = annotations
+        ports = []
+        for port, intf in switch.intfs.items():
+            if intf.name == 'lo':
+                continue
+            portDict = {}
+            portDict[ 'port' ] = port
+            portDict[ 'type' ] = 'FIBER' if isinstance(intf.link, LINCLink) else 'COPPER'
+            intfList = [ intf.link.intf1, intf.link.intf2 ]
+            intfList.remove(intf)
+            portDict[ 'speed' ] = intfList[ 0 ].speed if isinstance(intf.link, LINCLink) else 0
+            ports.append(portDict)
+        configDict[ 'ports' ] = ports
+        return configDict
+
+    @staticmethod
+    def bootOE(net):
+        "Start the LINC optical emulator within a mininet instance"
+        opticalJSON = {}
+        linkConfig = []
+        devices = []
+        #setting up the controllers for LINCSwitch class
+        LINCSwitch.controllers = net.controllers
+
+        for switch in net.switches:
+            if isinstance(switch, OpticalSwitch):
+                devices.append(switch.json())
+            else:
+                devices.append(LINCSwitch.switchJSON(switch))
+        opticalJSON[ 'devices' ] = devices
+
+        for link in net.links:
+            if isinstance(link, LINCLink) :
+                linkConfig.append(link.json())
+        opticalJSON[ 'links' ] = linkConfig
+
+        info('*** Writing Topology.json file\n')
+        with open('Topology.json', 'w') as outfile:
+            json.dump(opticalJSON, outfile, indent=4, separators=(',', ': '))
+
+        info('*** Converting Topology.json to linc-oe format (TopoConfig.json) file\n')
+        output = quietRun('%s/tools/test/bin/onos-oecfg ./Topology.json > TopoConfig.json' % LINCSwitch.onosDir, shell=True)
+        if output:
+            error('***ERROR: Error creating topology file: %s ' % output + '\n')
+            return False
+
+        info('*** Creating sys.config...\n')
+        output = quietRun('%s/config_generator TopoConfig.json %s/sys.config.template %s %s'
+                        % (LINCSwitch.configGen, LINCSwitch.configGen, LINCSwitch.controllers[ 0 ].ip, LINCSwitch.controllers[ 0 ].port), shell=True)
+        if output:
+            error('***ERROR: Error creating sys.config file: %s\n' % output)
+            return False
+
+        info ('*** Setting multiple controllers in sys.config...\n')
+        searchStr = '\[{"Switch.*$'
+        ctrlStr = ''
+        for index in range(len(LINCSwitch.controllers)):
+            ctrlStr += '{"Switch%d-Controller","%s",%d,tcp},' % (index, net.controllers[index].ip, net.controllers[index].port)
+        replaceStr = '[%s]},' % ctrlStr[:-1]  # Cut off last comma
+        sedCmd = 'sed -i \'s/%s/%s/\' sys.config' % (searchStr, replaceStr)
+        output = quietRun(sedCmd, shell=True)
+
+        info('*** Copying sys.config to linc-oe directory: ', output + '\n')
+        output = quietRun('cp -v sys.config %s/rel/linc/releases/1.0/' % LINCSwitch.lincDir, shell=True).strip('\n')
+        info(output + '\n')
+
+        info('*** Adding taps and bringing them up...\n')
+        LINCSwitch.setupInts(LINCSwitch.getTaps())
+
+        info('*** removing pipes if any \n')
+        quietRun('rm /tmp/home/%s/linc-oe/rel/linc/*' % LINCSwitch.user, shell=True)
+
+        info('*** Starting linc OE...\n')
+        output = quietRun('%s/rel/linc/bin/linc start' % LINCSwitch.lincDir, shell=True)
+        if output:
+            error('***ERROR: LINC-OE: %s' % output + '\n')
+            quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True)
+            return False
+
+        info('*** Waiting for linc-oe to start...\n')
+        LINCSwitch.waitStarted(net)
+
+        info('*** Adding cross-connect (tap) interfaces to packet switches...\n')
+        for link in net.links:
+            if isinstance(link, LINCLink):
+                if link.annotations[ 'optical.type' ] == 'cross-connect':
+                    for intf in [ link.intf1, link.intf2 ]:
+                        if not isinstance(intf, LINCIntf):
+                            intfList = [ intf.link.intf1, intf.link.intf2 ]
+                            intfList.remove(intf)
+                            intf2 = intfList[ 0 ]
+                            intf.node.attach(LINCSwitch.findTap(intf2.node, intf2.node.ports[ intf2 ]))
+
+        info('*** Waiting for all devices to be available in ONOS...\n')
+        url = 'http://%s:8181/onos/v1/devices' % LINCSwitch.controllers[0].ip
+        time = 0
+        while True:
+            response = json.load(urllib2.urlopen(url))
+            devs = response.get('devices')
+
+            # Wait for all devices to be registered
+            if (len(devices) != len(devs)):
+                continue
+
+            # Wait for all devices to available
+            available = True
+            for d in devs:
+                available &= d['available']
+            if available:
+                break
+
+            if (time >= TIMEOUT):
+                error('***ERROR: ONOS did not register devices within %s seconds\n' % TIMEOUT)
+                break
+
+            time += SLEEP_TIME
+            sleep(SLEEP_TIME)
+
+        info('*** Pushing Topology.json to ONOS\n')
+        for index in range(len(LINCSwitch.controllers)):
+            output = quietRun('%s/tools/test/bin/onos-topo-cfg %s Topology.json &' % (LINCSwitch.onosDir, LINCSwitch.controllers[ index ].ip), shell=True)
+            # successful output contains the two characters '{}'
+            # if there is more output than this, there is an issue
+            if output.strip('{}'):
+                warn('***WARNING: Could not push topology file to ONOS: %s\n' % output)
+
+    @staticmethod
+    def waitStarted(net, timeout=TIMEOUT):
+        "wait until all tap interfaces are available"
+        tapCount = 0
+        time = 0
+        for link in net.links:
+            if isinstance(link, LINCLink):
+                if link.annotations[ 'optical.type' ] == 'cross-connect':
+                    tapCount += 1
+
+        while True:
+            if str(tapCount) == quietRun('ip addr | grep tap | wc -l', shell=True).strip('\n'):
+                return True
+            if timeout:
+                if time >= TIMEOUT:
+                    error('***ERROR: LINC OE did not start within %s seconds\n' % TIMEOUT)
+                    return False
+                time += SLEEP_TIME
+            sleep(SLEEP_TIME)
+
+    @staticmethod
+    def shutdownOE():
+        "stop the optical emulator"
+        info('*** Stopping linc OE...\n')
+        quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True)
+
+    @staticmethod
+    def setupInts(intfs):
+        '''
+        add taps and bring them up.
+        '''
+        for i in intfs:
+            quietRun('ip tuntap add dev %s mode tap' % i)
+            quietRun('ip link set dev %s up' % i)
+            info('*** Intf %s set\n' % i)
+
+    @staticmethod
+    def getTaps(path=None):
+        '''
+        return list of all the tops in sys.config
+        '''
+        if path is None:
+            path = '%s/rel/linc/releases/1.0/sys.config' % LINCSwitch.lincDir
+        fd = open(path, 'r', 0)
+        sys_data = fd.read()
+        taps = re.findall('tap\d+', sys_data)
+        fd.close()
+        return taps
+
+    @staticmethod
+    def findUser():
+        "Try to return logged-in (usually non-root) user"
+        try:
+            # If we're running sudo
+            return os.environ[ 'SUDO_USER' ]
+        except:
+            try:
+                # Logged-in user (if we have a tty)
+                return quietRun('who am i').split()[ 0 ]
+            except:
+                # Give up and return effective user
+                return quietRun('whoami')
+
+
+    @staticmethod
+    def findTap(node, port, path=None):
+        '''utility function to parse through a sys.config
+           file to find tap interfaces for a switch'''
+        switch = False
+        portLine = ''
+        intfLines = []
+
+        if path is None:
+            path = '%s/rel/linc/releases/1.0/sys.config' % LINCSwitch.lincDir
+
+        with open(path) as f:
+            for line in f:
+                if 'tap' in line:
+                    intfLines.append(line)
+                if node.dpid in line.translate(None, ':'):
+                    switch = True
+                    continue
+                if switch:
+                    if 'switch' in line:
+                        switch = False
+                    if 'port_no,%s}' % port in line:
+                        portLine = line
+                        break
+
+        if portLine:
+            m = re.search('port,\d+', portLine)
+            port = m.group(0).split(',')[ 1 ]
+        else:
+            error('***ERROR: Could not find any ports in sys.config\n')
+            return
+
+        for intfLine in intfLines:
+            if 'port,%s' % port in intfLine:
+                return re.findall('tap\d+', intfLine)[ 0 ]
+
+    def json(self):
+        "return json configuration dictionary for switch"
+        return self.configDict
+
+    def terminate(self):
+        pass
+
+class LINCLink(Link):
+    """
+    LINC link class
+    """
+    def __init__(self, node1, node2, port1=None, port2=None, allowed=True,
                   intfName1=None, intfName2=None, linkType='OPTICAL',
-                  annotations={}, speed1=0, speed2=0, **params ):
+                  annotations={}, speed1=0, speed2=0, **params):
         "Creates a dummy link without a virtual ethernet pair."
         self.allowed = allowed
         self.annotations = annotations
         self.linkType = linkType
+        self.port1 = port1
+        self.port2 = port2
         params1 = { 'speed': speed1 }
         params2 = { 'speed': speed2 }
-        
-        if isinstance( node1, OpticalSwitch ):
-            cls1 = OpticalIntf
+        # self.isCrossConnect = True if self.annotations.get('optical.type') == 'cross-connect' else False
+        if isinstance(node1, LINCSwitch) and isinstance(node2, LINCSwitch):
+            self.isCrossConnect = False
+        else:
+            self.isCrossConnect = True
+        if isinstance(node1, LINCSwitch):
+            cls1 = LINCIntf
+            if self.isCrossConnect:
+                node1.crossConnects.append(self)
         else:
             cls1 = Intf
             # bad hack to stop error message from appearing when we try to set up intf in a packet switch, 
             # and there is no interface there( because we do not run makeIntfPair ). This way, we just set lo up
             intfName1 = 'lo'
-        if isinstance( node2, OpticalSwitch ):
-            cls2 = OpticalIntf
+        if isinstance(node2, LINCSwitch):
+            cls2 = LINCIntf
+            if self.isCrossConnect:
+                node2.crossConnects.append(self)
         else:
             cls2 = Intf
             intfName2 = 'lo'
-        Link.__init__( self, node1, node2, port1=port1, port2=port2,
+        Link.__init__(self, node1, node2, port1=port1, port2=port2,
                        intfName1=intfName1, intfName2=intfName2, cls1=cls1,
-                       cls2=cls2, params1=params1, params2=params2 )
-        
+                       cls2=cls2, params1=params1, params2=params2)
 
     @classmethod
-    def makeIntfPair( _cls, intfName1, intfName2, *args, **kwargs ):
+    def makeIntfPair(_cls, intfName1, intfName2, *args, **kwargs):
         pass
 
-    def json( self ):
+    def json(self):
         "build and return the json configuration dictionary for this link"
         configData = {}
-        configData[ 'src' ] = ( 'of:' +  self.intf1.node.dpid + 
-                                '/%s' % self.intf1.node.ports[ self.intf1 ] )
-        configData[ 'dst' ] = ( 'of:' +  self.intf2.node.dpid +
-                                '/%s' % self.intf2.node.ports[ self.intf2 ] )
+        configData[ 'src' ] = ('of:' + self.intf1.node.dpid +
+                                '/%s' % self.intf1.node.ports[ self.intf1 ])
+        configData[ 'dst' ] = ('of:' + self.intf2.node.dpid +
+                                '/%s' % self.intf2.node.ports[ self.intf2 ])
         configData[ 'type' ] = self.linkType
         configData[ 'annotations' ] = self.annotations
         return configData
 
-class OpticalIntf( Intf ):
-
-    def __init__( self, name=None, node=None, speed=0, 
-                  port=None, link=None, **params ):
+class LINCIntf(OpticalIntf):
+    """
+    LINC interface class
+    """
+    def __init__(self, name=None, node=None, speed=0,
+                  port=None, link=None, **params):
         self.node = node
         self.speed = speed
         self.port = port
         self.link = link
         self.name = name
-        node.addIntf( self, port=port )
+        node.addIntf(self, port=port)
         self.params = params
         self.ip = None
 
-    def json( self ):
+    def json(self):
         "build and return the JSON information for this interface( not used right now )"
         configDict = {}
         configDict[ 'port' ] = self.port
@@ -167,356 +637,34 @@
         configDict[ 'type' ] = 'FIBER'
         return configDict
 
-    def config( self, *args, **kwargs ):
+    def config(self, *args, **kwargs):
         "dont configure a dummy interface"
         pass
 
-def switchJSON( switch ):
-    "Returns the json configuration for a packet switch"
-    configDict = {}
-    configDict[ 'uri' ] = 'of:' + switch.dpid
-    configDict[ 'mac' ] = quietRun( 'cat /sys/class/net/%s/address' % switch.name ).strip( '\n' ).translate( None, ':' )
-    configDict[ 'hw' ] = 'PK' # FIXME what about OVS?
-    configDict[ 'mfr' ] = 'Linc' # FIXME what about OVS?
-    configDict[ 'type' ] = 'SWITCH' # FIXME what about OVS?
-    annotations = switch.params.get( 'annotations', {} )
-    annotations.setdefault( 'name', switch.name )
-    configDict[ 'annotations' ] = annotations
-    ports = []
-    for port, intf in switch.intfs.items():
-        if intf.name == 'lo':
-            continue
-        portDict = {}
-        portDict[ 'port' ] = port
-        portDict[ 'type' ] = 'FIBER' if isinstance( intf.link, OpticalLink ) else 'COPPER'
-        intfList = [ intf.link.intf1, intf.link.intf2 ]
-        intfList.remove( intf )
-        portDict[ 'speed' ] = intfList[ 0 ].speed if isinstance( intf.link, OpticalLink ) else 0
-        ports.append( portDict )
-    configDict[ 'ports' ] = ports
-    return configDict
+    def ifconfig(self, status):
+        "configure the status"
+        if status == "up":
+            return self.node.w_port_up(self.port)
+        elif status == "down":
+            return self.node.w_port_down(self.port)
 
 
-def startOE( net ):
-    "Start the LINC optical emulator within a mininet instance"
-    opticalJSON = {}
-    linkConfig = []
-    devices = []
-    
-    for switch in net.switches:
-        if isinstance( switch, OpticalSwitch ):
-            devices.append( switch.json() )
-        else:
-            devices.append( switchJSON( switch ) )
-    opticalJSON[ 'devices' ] = devices
-
-    for link in net.links:
-        if isinstance( link, OpticalLink ) :
-            linkConfig.append( link.json() )
-
-    opticalJSON[ 'links' ] = linkConfig
-
-    try:
-        onosDir = os.environ[ 'ONOS_ROOT' ]
-    except:
-        onosDir = findDir( 'onos' )
-        if not onosDir:
-            error( 'Please set ONOS_ROOT environment variable!\n' )
-            return False
-        else:
-            os.environ[ 'ONOS_ROOT' ] = onosDir
-
-    info( '*** Writing Topology.json file\n' )
-    with open( 'Topology.json', 'w' ) as outfile:
-        json.dump( opticalJSON, outfile, indent=4, separators=(',', ': ') )
-
-    info( '*** Converting Topology.json to linc-oe format (TopoConfig.json) file (not using oecfg) \n' )
-    
-    topoConfigJson = {};
-    newLinkConfig = [];
-    switchConfig = [];
-    dpIdToName = {};
-
-    #Iterate through all switches and convert the ROADM switches to linc-oe format
-    for switch in opticalJSON["devices"]:
-        if switch["type"] == "ROADM":
-            builtSwitch = {}
-
-            #set basic switch params based on annotations
-            builtSwitch["allowed"] = True;
-            builtSwitch["latitude"] = switch["annotations"]["latitude"];
-            builtSwitch["longitude"] = switch["annotations"]["longitude"];
-
-            nodeId = switch["uri"]
-
-            #convert the nodeId to linc-oe format
-            nodeDpid = dpId(nodeId);
-
-            if "name" in switch:
-                builtSwitch["name"] = switch["name"]
-            else:
-                builtSwitch["name"] = "none"
-
-            #keep track of the name corresponding to each switch dpid
-            dpIdToName[nodeDpid] = builtSwitch["name"];
-
-            builtSwitch["nodeDpid"] = nodeDpid
-
-            #set switch params and type
-            builtSwitch["params"] = {};
-            builtSwitch["params"]["numregens"] = switch["annotations"]["optical.regens"];
-            builtSwitch["type"] = "Roadm"
-
-            #append to list of switches
-            switchConfig.append(builtSwitch);
-
-    topoConfigJson["switchConfig"] = switchConfig;
-
-    #Iterate through all optical links and convert them to linc-oe format
-    for link in opticalJSON["links"]:
-        if link["type"] == "OPTICAL":
-            builtLink = {}
-
-            #set basic link params for src and dst
-            builtLink["allowed"] = True;
-            builtLink["nodeDpid1"] = dpId(link["src"])
-            builtLink["nodeDpid2"] = dpId(link["dst"])
-
-            #set more params such as name/bandwidth/port/waves if they exist
-            params = {}
-            params["nodeName1"] = dpIdToName.get(builtLink["nodeDpid1"], "none")
-            params["nodeName2"] = dpIdToName.get(builtLink["nodeDpid2"], "none")
-            if "bandwidth" in link["annotations"]:
-                params["bandwidth"] = link["annotations"]["bandwidth"]
-            params["port1"] = int(link["src"].split("/")[1])
-            params["port2"]  = int(link["dst"].split("/")[1])
-
-            if "optical.waves" in link["annotations"]:
-                params["numWaves"] = link["annotations"]["optical.waves"]
-            builtLink["params"] = params
-
-            #set type of link (WDM or pktOpt)
-            if link["annotations"]["optical.type"] == "WDM":
-                builtLink["type"] = "wdmLink"
-            else:
-                builtLink["type"] = "pktOptLink"
-
-            newLinkConfig.append(builtLink);
-
-    topoConfigJson["linkConfig"] = newLinkConfig;
-
-    #Writing to TopoConfig.json
-    with open( 'TopoConfig.json', 'w' ) as outfile:
-            json.dump( topoConfigJson, outfile, indent=4, separators=(',', ': ') )
-
-    info( '*** Creating sys.config...\n' )
-    configGen = findDir( 'LINC-config-generator' )
-    if not configGen:
-        error( "***ERROR: Could not find LINC-config-generator in user's home directory\n" )
-        return False
-    output = quietRun( '%s/config_generator TopoConfig.json %s/sys.config.template %s %s'
-                    % ( configGen, configGen, net.controllers[ 0 ].ip, net.controllers[ 0 ].port ), shell=True )
-    if output:
-        error( '***ERROR: Error creating sys.config file: %s\n' % output )
-        return False
-
-    info ('*** Setting multiple controllers in sys.config...\n' )
-    searchStr = '{controllers,.*$'
-    ctrlStr = ''
-    for index in range(len(net.controllers)):
-        ctrlStr += '{"Switch%d-Controller","%s",%d,tcp},' % (index, net.controllers[index].ip, net.controllers[index].port)
-    replaceStr = '{controllers,[%s]},' % ctrlStr[:-1]         # Cut off last comma
-    sedCmd = 'sed -i \'s/%s/%s/\' sys.config' % (searchStr, replaceStr)
-    output = quietRun( sedCmd, shell=True )
-
-    info( '*** Copying sys.config to linc-oe directory: ', output + '\n' )
-    lincDir = findDir( 'linc-oe' )
-    if not lincDir:
-        error( "***ERROR: Could not find linc-oe in user's home directory\n" )
-        return False
-    output = quietRun( 'cp -v sys.config %s/rel/linc/releases/1.0/' % lincDir, shell=True ).strip( '\n' )
-    info( output + '\n' )
-
-    info( '*** Starting linc OE...\n' )
-    output = quietRun( '%s/rel/linc/bin/linc start' % lincDir, shell=True )
-    if output:
-        error( '***ERROR: LINC-OE: %s' % output + '\n' )
-        quietRun( '%s/rel/linc/bin/linc stop' % lincDir, shell=True )
-        return False
-    
-    info( '*** Waiting for linc-oe to start...\n' )
-    waitStarted( net )
-    
-    info( '*** Adding cross-connect (tap) interfaces to packet switches...\n' )
-    for link in net.links:
-        if isinstance( link, OpticalLink ):
-            if link.annotations[ 'optical.type' ] == 'cross-connect':
-                for intf in [ link.intf1, link.intf2 ]:
-                    if not isinstance( intf, OpticalIntf ):
-                        intfList = [ intf.link.intf1, intf.link.intf2 ]
-                        intfList.remove( intf )
-                        intf2 = intfList[ 0 ]
-                        intf.node.attach( findTap( intf2.node, intf2.node.ports[ intf2 ] ) )
-
-    info( '*** Press ENTER to push Topology.json to onos...\n' )
-    raw_input() # FIXME... we should eventually remove this
-    info( '*** Pushing Topology.json to ONOS\n' )
-    output = quietRun( '%s/tools/test/bin/onos-topo-cfg %s Topology.json' % ( onosDir, net.controllers[ 0 ].ip ), shell=True )
-    # successful output contains the two characters '{}'
-    # if there is more output than this, there is an issue
-    if output.strip( '{}' ):
-        warn( '***WARNING: Could not push topology file to ONOS: %s' % output )
-
-#converts node ids to linc-oe format, with colons every two chars
-def dpId(id):
-    nodeDpid = ""
-    id = id.split("/", 1)[0]
-    for i in range(3, len(id) - 1, 2):
-        nodeDpid += (id[i:(i + 2):]) + ":"
-    return nodeDpid[0:(len(nodeDpid) - 1)];
-        
-def waitStarted( net, timeout=None ):
-    "wait until all tap interfaces are available"
-    tapCount = 0
-    time = 0
-    for link in net.links:
-        if isinstance( link, OpticalLink ):
-            if link.annotations[ 'optical.type' ] == 'cross-connect':
-                tapCount += 1
-    
-    while True:
-        if str( tapCount ) == quietRun( 'ip addr | grep tap | wc -l', shell=True ).strip( '\n' ):
-            return True
-        if timeout:
-            if time >= timeout:
-                error( '***ERROR: Linc OE did not start within %s seconds' % timeout )
-                return False
-            time += .5
-        sleep( .5 )
-
-def stopOE():
-    "stop the optical emulator"
-    info( '*** Stopping linc OE...\n' )
-    lincDir = findDir( 'linc-oe' )
-    quietRun( '%s/rel/linc/bin/linc stop' % lincDir, shell=True )
-
-def findDir( directory ):
-    "finds and returns the path of any directory in the user's home directory"
-    user = findUser()
-    homeDir = '/home/' + user
-    Dir = quietRun( 'find %s -maxdepth 1 -name %s -type d' % ( homeDir, directory ) ).strip( '\n' )
-    DirList = Dir.split( '\n' )
-    if not Dir:
-        return None
-    elif len( DirList ) > 1 :
-        warn( '***WARNING: Found multiple instances of %s; using %s\n'
-                 % ( directory, DirList[ 0 ] ) )
-        return DirList[ 0 ]
-    else:
-        return Dir
-
-def findUser():
-    "Try to return logged-in (usually non-root) user"
-    try:
-        # If we're running sudo
-        return os.environ[ 'SUDO_USER' ]
-    except:
-        try:
-            # Logged-in user (if we have a tty)
-            return quietRun( 'who am i' ).split()[ 0 ]
-        except:
-            # Give up and return effective user
-            return quietRun( 'whoami' )
-
-
-def findTap( node, port, path=None ):
-    '''utility function to parse through a sys.config
-       file to find tap interfaces for a switch'''
-    switch=False
-    portLine = ''
-    intfLines = []
-
-    if path is None:
-        lincDir = findDir( 'linc-oe' )
-        if not lincDir:
-            error( '***ERROR: Could not find linc-oe in users home directory\n' )
-            return None
-        path = '%s/rel/linc/releases/1.0/sys.config' % lincDir
-
-    with open( path ) as f:
-        for line in f:
-            if 'tap' in line:
-                intfLines.append( line )
-            if node.dpid in line.translate( None, ':' ):
-                switch=True
-                continue
-            if switch:
-                if 'switch' in line:
-                    switch = False
-                if 'port_no,%s}' % port in line:
-                    portLine = line
-                    break 
-
-    if portLine:
-        m = re.search( 'port,\d+', portLine )
-        port = m.group( 0 ).split( ',' )[ 1 ]
-    else:
-        error( '***ERROR: Could not find any ports in sys.config\n' )
-        return
-
-    for intfLine in intfLines:
-        if 'port,%s' % port in intfLine:
-            return re.findall( 'tap\d+', intfLine )[ 0 ]
-
-
-class MininetOE( Mininet ):
+class MininetOE(Mininet):
     "Mininet with Linc-OE support (starts and stops linc-oe)"
 
-    def start( self ):
-        Mininet.start( self )
-        startOE( self )
+    def start(self):
+        Mininet.start(self)
+        LINCSwitch.bootOE(self)
 
-    def stop( self ):
-        Mininet.stop( self )
-        stopOE()
+    def stop(self):
+        Mininet.stop(self)
+        LINCSwitch.shutdownOE()
 
-    def addControllers( self, controllers ):
+    def addControllers(self, controllers):
         i = 0
         for ctrl in controllers:
-            self.addController( RemoteController( 'c%d' % i, ip=ctrl ) )
-
-
-class OpticalTestTopo( Topo ):
-
-    def build( self ):
-        opticalAnn = { 'optical.waves': 80, 'optical.type': "WDM", 'durable': True }
-        switchAnn = { 'bandwidth': 100000, 'optical.type': 'cross-connect', 'durable': True }
-        h1 = self.addHost( 'h1' )
-        h2 = self.addHost( 'h2' )
-        s1 = self.addSwitch( 's1' )
-        s2 = self.addSwitch( 's2' )
-        O4 = self.addSwitch( 'O4', cls=OpticalSwitch )
-        O5 = self.addSwitch( 'O5', cls=OpticalSwitch )
-        O6 = self.addSwitch( 'O6', cls=OpticalSwitch )
-        self.addLink( O4, O5, cls=OpticalLink, annotations=opticalAnn )
-        self.addLink( O5, O6, cls=OpticalLink, annotations=opticalAnn )
-        self.addLink( s1, O4, cls=OpticalLink, annotations=switchAnn )
-        self.addLink( s2, O6, cls=OpticalLink, annotations=switchAnn )
-        self.addLink( h1, s1 )
-        self.addLink( h2, s2 )
+            self.addController(RemoteController('c%d' % i, ip=ctrl))
+            i += 1
 
 if __name__ == '__main__':
-    import sys
-    if len( sys.argv ) >= 2:
-        controllers = sys.argv[1:]
-    else:
-        print 'Usage: ./opticalUtils.py (<Controller IP>)+'
-        print 'Using localhost...\n'
-        controllers = [ '127.0.0.1' ]
-
-    setLogLevel( 'info' )
-    net = MininetOE( topo=OpticalTestTopo(), controller=None, autoSetMacs=True )
-    net.addControllers( controllers )
-    net.start()
-    CLI( net )
-    net.stop()
+    pass
