diff --git a/tools/test/topos/opticalUtils.py b/tools/test/topos/opticalUtils.py
index 5b47d53..3315ce6 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, LINCLink, and OpticalSwitch
+such as startOE, stopOE, OpticalLink, 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 LINCLink and OpticalSwitch from this module
+    - import OpticalLink 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=LINCLink
+      to an optical switch with topo.addLink, always specify cls=OpticalLink
     - 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,12 +51,11 @@
 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
@@ -66,127 +65,25 @@
 from mininet.link import Link, Intf
 from mininet.cli import CLI
 
-# Sleep time and timeout values in seconds
-SLEEP_TIME = 2
-TIMEOUT = 60
+class OpticalSwitch( Switch ):
 
-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):
+    def __init__( self, name, dpid=None, allowed=True,
+                  switchType='ROADM', annotations={}, **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.crossConnects = []
-        self.deletedCrossConnects = []
-        self.controller = controller
-        self.lincId = self._get_linc_id()  # use to communicate with LINC
-        self.lincStarted = False
+        self.configDict = {} # dictionary that holds all of the JSON configuration data
 
-    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' ] = 'LINC-OE'
+        self.configDict[ 'annotations' ].setdefault( 'name', self.name )
+        self.configDict[ 'hw' ] = 'OE'
         self.configDict[ 'mfr' ] = 'Linc'
         self.configDict[ 'mac' ] = 'ffffffffffff' + self.dpid[-2] + self.dpid[-1]
         self.configDict[ 'type' ] = self.switchType
@@ -195,441 +92,74 @@
             if intf.name == 'lo':
                 continue
             else:
-                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 dpctl( self, *args ):
-        "Run dpctl command: ignore for now"
-        pass
-
-    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 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')
+                self.configDict[ 'ports' ].append( intf.json() )
 
 
-    @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):
+    def json( self ):
         "return json configuration dictionary for switch"
         return self.configDict
-
-    def terminate(self):
+    
+    def terminate( self ):
         pass
 
-class LINCLink(Link):
-    """
-    LINC link class
-    """
-    def __init__(self, node1, node2, port1=None, port2=None, allowed=True,
+class OpticalLink( Link ):
+
+    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 }
-        # 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)
+        
+        if isinstance( node1, OpticalSwitch ):
+            cls1 = OpticalIntf
         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, LINCSwitch):
-            cls2 = LINCIntf
-            if self.isCrossConnect:
-                node2.crossConnects.append(self)
+        if isinstance( node2, OpticalSwitch ):
+            cls2 = OpticalIntf
         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 LINCIntf(OpticalIntf):
-    """
-    LINC interface class
-    """
-    def __init__(self, name=None, node=None, speed=0,
-                  port=None, link=None, **params):
+class OpticalIntf( Intf ):
+
+    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
@@ -637,34 +167,356 @@
         configDict[ 'type' ] = 'FIBER'
         return configDict
 
-    def config(self, *args, **kwargs):
+    def config( self, *args, **kwargs ):
         "dont configure a dummy interface"
         pass
 
-    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 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
 
 
-class MininetOE(Mininet):
+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 ):
     "Mininet with Linc-OE support (starts and stops linc-oe)"
 
-    def start(self):
-        Mininet.start(self)
-        LINCSwitch.bootOE(self)
+    def start( self ):
+        Mininet.start( self )
+        startOE( self )
 
-    def stop(self):
-        Mininet.stop(self)
-        LINCSwitch.shutdownOE()
+    def stop( self ):
+        Mininet.stop( self )
+        stopOE()
 
-    def addControllers(self, controllers):
+    def addControllers( self, controllers ):
         i = 0
         for ctrl in controllers:
-            self.addController(RemoteController('c%d' % i, ip=ctrl))
-            i += 1
+            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 )
 
 if __name__ == '__main__':
-    pass
+    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()
