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
