Merge "Basic Platform test suite using onos docker images; test  activate and deactivate apps"
diff --git a/TestON/drivers/common/api/controller/onosrestdriver.py b/TestON/drivers/common/api/controller/onosrestdriver.py
index 046de84..c10079f 100644
--- a/TestON/drivers/common/api/controller/onosrestdriver.py
+++ b/TestON/drivers/common/api/controller/onosrestdriver.py
@@ -1095,39 +1095,14 @@
             main.cleanup()
             main.exit()
 
-    def addFlow( self,
-                 deviceId,
-                 appId=0,
-                 ingressPort="",
-                 egressPort="",
-                 ethType="",
-                 ethSrc="",
-                 ethDst="",
-                 bandwidth="",
-                 lambdaAlloc=False,
-                 ipProto="",
-                 ipSrc="",
-                 ipDst="",
-                 tcpSrc="",
-                 tcpDst="",
-                 ip="DEFAULT",
-                 port="DEFAULT" ):
+    def sendFlow( self, deviceId, flowJson, ip="DEFAULT", port="DEFAULT", debug=False ):
         """
         Description:
-            Creates a single flow in the specified device
+            Sends a single flow to the specified device. This function exists
+            so you can bypass the addFLow driver and send your own custom flow.
         Required:
-            * deviceId: id of the device
-        Optional:
-            * ingressPort: port ingress device
-            * egressPort: port  of egress device
-            * ethType: specify ethType
-            * ethSrc: specify ethSrc ( i.e. src mac addr )
-            * ethDst: specify ethDst ( i.e. dst mac addr )
-            * ipProto: specify ip protocol
-            * ipSrc: specify ip source address with mask eg. ip#/24
-            * ipDst: specify ip destination address eg. ip#/24
-            * tcpSrc: specify tcp source port
-            * tcpDst: specify tcp destination port
+            * The flow in json
+            * the device id to add the flow to
         Returns:
             Returns main.TRUE for successful requests; Returns main.FALSE
             if error on requests;
@@ -1136,63 +1111,9 @@
             The ip and port option are for the requests input's ip and port
             of the ONOS node
         """
+
         try:
-            flowJson = { "priority":100,
-                           "isPermanent":"true",
-                           "timeout":0,
-                           "deviceId":deviceId,
-                           "treatment":{"instructions":[]},
-                           "selector": {"criteria":[]}}
-            if appId:
-                flowJson[ "appId" ] = appId
-            if egressPort:
-                flowJson[ 'treatment' ][ 'instructions' ].append(
-                                                       { "type":"OUTPUT",
-                                                         "port":egressPort } )
-            if ingressPort:
-                flowJson[ 'selector' ][ 'criteria' ].append(
-                                                       { "type":"IN_PORT",
-                                                         "port":ingressPort } )
-            if ethType == "IPV4":
-                flowJson[ 'selector' ][ 'criteria' ].append( {
-                                                         "type":"ETH_TYPE",
-                                                         "ethType":2048 } )
-            elif ethType:
-                flowJson[ 'selector' ][ 'criteria' ].append( {
-                                                         "type":"ETH_TYPE",
-                                                         "ethType":ethType } )
-            if ethSrc:
-                flowJson[ 'selector' ][ 'criteria' ].append(
-                                                       { "type":"ETH_SRC",
-                                                         "mac":ethSrc } )
-            if ethDst:
-                flowJson[ 'selector' ][ 'criteria' ].append(
-                                                       { "type":"ETH_DST",
-                                                         "mac":ethDst } )
-            if ipSrc:
-                flowJson[ 'selector' ][ 'criteria' ].append(
-                                                       { "type":"IPV4_SRC",
-                                                         "ip":ipSrc } )
-            if ipDst:
-                flowJson[ 'selector' ][ 'criteria' ].append(
-                                                       { "type":"IPV4_DST",
-                                                         "ip":ipDst } )
-            if tcpSrc:
-                flowJson[ 'selector' ][ 'criteria' ].append(
-                                                       { "type":"TCP_SRC",
-                                                         "tcpPort": tcpSrc } )
-            if tcpDst:
-                flowJson[ 'selector' ][ 'criteria' ].append(
-                                                       { "type":"TCP_DST",
-                                                         "tcpPort": tcpDst } )
-            if ipProto:
-                flowJson[ 'selector' ][ 'criteria' ].append(
-                                                       { "type":"IP_PROTO",
-                                                         "protocol": ipProto } )
-            if bandwidth or lambdaAlloc:
-                # TODO: Bandwidth and Lambda will be implemented if needed
-                raise NotImplementedError
-            main.log.debug( "Adding flow: " + self.pprint( flowJson ) )
+            if debug: main.log.debug( "Adding flow: " + self.pprint( flowJson ) )
             output = None
             if ip == "DEFAULT":
                 main.log.warn( "No ip given, reverting to ip from topo file" )
@@ -1226,6 +1147,113 @@
             main.cleanup()
             main.exit()
 
+    def addFlow( self,
+                 deviceId,
+                 appId=0,
+                 ingressPort="",
+                 egressPort="",
+                 ethType="",
+                 ethSrc="",
+                 ethDst="",
+                 vlan="",
+                 ipProto="",
+                 ipSrc=(),
+                 ipDst=(),
+                 tcpSrc="",
+                 tcpDst="",
+                 ip="DEFAULT",
+                 port="DEFAULT",
+                 debug=False ):
+        """
+        Description:
+            Creates a single flow in the specified device
+        Required:
+            * deviceId: id of the device
+        Optional:
+            * ingressPort: port ingress device
+            * egressPort: port  of egress device
+            * ethType: specify ethType
+            * ethSrc: specify ethSrc ( i.e. src mac addr )
+            * ethDst: specify ethDst ( i.e. dst mac addr )
+            * ipProto: specify ip protocol
+            * ipSrc: specify ip source address with mask eg. ip#/24
+                as a tuple (type, ip#)
+            * ipDst: specify ip destination address eg. ip#/24
+                as a tuple (type, ip#)
+            * tcpSrc: specify tcp source port
+            * tcpDst: specify tcp destination port
+        Returns:
+            Returns main.TRUE for successful requests; Returns main.FALSE
+            if error on requests;
+            Returns None for exceptions
+        NOTE:
+            The ip and port option are for the requests input's ip and port
+            of the ONOS node
+        """
+        try:
+            flowJson = { "priority":100,
+                           "isPermanent":"true",
+                           "timeout":0,
+                           "deviceId":deviceId,
+                           "treatment":{"instructions":[]},
+                           "selector": {"criteria":[]}}
+            if appId:
+                flowJson[ "appId" ] = appId
+            if egressPort:
+                flowJson[ 'treatment' ][ 'instructions' ].append( {
+                                                        "type":"OUTPUT",
+                                                        "port":egressPort } )
+            if ingressPort:
+                flowJson[ 'selector' ][ 'criteria' ].append( {
+                                                        "type":"IN_PORT",
+                                                        "port":ingressPort } )
+            if ethType:
+                flowJson[ 'selector' ][ 'criteria' ].append( {
+                                                        "type":"ETH_TYPE",
+                                                        "ethType":ethType } )
+            if ethSrc:
+                flowJson[ 'selector' ][ 'criteria' ].append( {
+                                                        "type":"ETH_SRC",
+                                                        "mac":ethSrc } )
+            if ethDst:
+                flowJson[ 'selector' ][ 'criteria' ].append( {
+                                                        "type":"ETH_DST",
+                                                        "mac":ethDst } )
+            if vlan:
+                flowJson[ 'selector' ][ 'criteria' ].append( {
+                                                        "type":"VLAN_VID",
+                                                        "vlanId":vlan } )
+            if ipSrc:
+                flowJson[ 'selector' ][ 'criteria' ].append( {
+                                                        "type":ipSrc[0],
+                                                        "ip":ipSrc[1] } )
+            if ipDst:
+                flowJson[ 'selector' ][ 'criteria' ].append( {
+                                                        "type":ipDst[0],
+                                                        "ip":ipDst[1] } )
+            if tcpSrc:
+                flowJson[ 'selector' ][ 'criteria' ].append( {
+                                                        "type":"TCP_SRC",
+                                                        "tcpPort": tcpSrc } )
+            if tcpDst:
+                flowJson[ 'selector' ][ 'criteria' ].append( {
+                                                        "type":"TCP_DST",
+                                                        "tcpPort": tcpDst } )
+            if ipProto:
+                flowJson[ 'selector' ][ 'criteria' ].append( {
+                                                        "type":"IP_PROTO",
+                                                        "protocol": ipProto } )
+
+            return self.sendFlow( deviceId=deviceId, flowJson=flowJson, debug=debug )
+
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
     def removeFlow( self, deviceId, flowId,
                        ip="DEFAULT", port="DEFAULT" ):
         """
diff --git a/TestON/drivers/common/cli/emulator/lincoemininetdriver.py b/TestON/drivers/common/cli/emulator/lincoemininetdriver.py
new file mode 100644
index 0000000..9372a54
--- /dev/null
+++ b/TestON/drivers/common/cli/emulator/lincoemininetdriver.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+"""
+
+    TestON is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 2 of the License, or
+    ( at your option ) any later version.
+
+    TestON is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+
+LincOEMininetDriver is an extension of the mininetclidriver to handle linc oe
+"""
+import pexpect
+import re
+import sys
+import os
+from drivers.common.cli.emulator.mininetclidriver import MininetCliDriver
+
+
+class LincOEMininetDriver( MininetCliDriver ):
+    def runOpticalMnScript( self,onosDirectory = 'onos', ctrllerIP = None ):
+        import time
+        import types
+        """
+            Description:
+                This function is only meant for Packet Optical.
+                It runs python script "opticalTest.py" to create the
+                packet layer( mn ) and optical topology
+            Optional:
+                name - Name of onos directory. (ONOS | onos)
+            Required:
+                ctrllerIP = Controller(s) IP address
+            TODO: If no ctrllerIP is provided, a default
+                $OC1 can be accepted
+        """
+        try:
+            if ctrllerIP == None:
+                main.log.error( "You need to specify the IP" )
+                return main.FALSE
+            else:
+                controller = ''
+                if isinstance( ctrllerIP, types.ListType ):
+                    for i in xrange( len( ctrllerIP ) ):
+                        controller += ctrllerIP[i] + ' '
+                    main.log.info( "Mininet topology is being loaded with " +
+                                   "controllers: " + controller )
+                elif isinstance( ctrllerIP, types.StringType ):
+                    controller = ctrllerIP
+                    main.log.info( "Mininet topology is being loaded with " +
+                                   "controller: " + controller )
+                else:
+                    main.log.info( "You need to specify a valid IP" )
+                    return main.FALSE
+                topoFile = "~/{0}/tools/test/topos/opticalTest.py".format( onosDirectory )
+                cmd = "sudo -E python {0} {1}".format( topoFile, controller )
+                main.log.info( self.name + ": cmd = " + cmd )
+                self.handle.sendline( cmd )
+                lincStart = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ],timeout=120 )
+                if lincStart == 1:
+                    self.handle.sendline( "\x03" )
+                    self.handle.sendline( "sudo mn -c" )
+                    self.handle.sendline( cmd )
+                    lincStart = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ],timeout=120 )
+                if lincStart == 1:
+                    main.log.error( "OpticalTest.py failed to start." )
+                    return main.FALSE
+                return main.TRUE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":     " + self.handle.before )
+            return main.FALSE
+
+    def pingHostOptical( self, **pingParams ):
+        """
+        This function is only for Packet Optical related ping
+        Use the next pingHost() function for all normal scenarios )
+        Ping from one mininet host to another
+        Currently the only supported Params: SRC and TARGET
+        """
+        args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
+        command = args[ "SRC" ] + " ping " + \
+            args[ "TARGET" ] + " -c 1 -i 1 -W 8"
+        try:
+            main.log.warn( "Sending: " + command )
+            self.handle.sendline( command )
+            i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
+            if i == 1:
+                main.log.error(
+                    self.name +
+                    ": timeout when waiting for response from mininet" )
+                main.log.error( "response: " + str( self.handle.before ) )
+            i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
+            if i == 1:
+                main.log.error(
+                    self.name +
+                    ": timeout when waiting for response from mininet" )
+                main.log.error( "response: " + str( self.handle.before ) )
+            response = self.handle.before
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":     " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        main.log.info( self.name + ": Ping Response: " + response )
+        if re.search( ',\s0\%\spacket\sloss', response ):
+            main.log.info( self.name + ": no packets lost, host is reachable" )
+            main.lastResult = main.TRUE
+            return main.TRUE
+        else:
+            main.log.error(
+                self.name +
+                ": PACKET LOST, HOST IS NOT REACHABLE" )
+            main.lastResult = main.FALSE
+            return main.FALSE
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index f20589e..ff14fbe 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -3124,7 +3124,7 @@
             main.cleanup()
             main.exit()
 
-    def sendPacket( self, packet=None, timeout=1 ):
+    def sendPacket( self, iface=None, packet=None, timeout=1 ):
         """
         Send a packet with either the given scapy packet command, or use the
         packet saved in the variable 'packet'.
@@ -3147,6 +3147,9 @@
                 sendCmd += packet
             else:
                 sendCmd += "packet"
+            if iface:
+                sendCmd += ", iface='{}'".format( iface )
+
             sendCmd += ', timeout=' + str( timeout ) + ')'
             self.handle.sendline( sendCmd )
             self.handle.expect( self.scapyPrompt )
diff --git a/TestON/tests/CHOtest/CHOtest.params b/TestON/tests/CHOtest/CHOtest.params
index 5f8c205..834179c 100644
--- a/TestON/tests/CHOtest/CHOtest.params
+++ b/TestON/tests/CHOtest/CHOtest.params
@@ -18,7 +18,7 @@
     # 19X. IPv6 ping across Point,Multi-single,Single-Multi Intents
 
 <testcases>
-1,20,3,[40,5,140,60,160,70,170,80,180,10,5,90,190,71,171,81,181,10,5]*50,21,3,[41,5,141,61,161,72,172,82,182,10,5,91,191,73,173,83,183,10,5]*50,22,3,[42,5,142,62,162,74,174,84,184,10,5,92,192,75,175,85,185,10,5]*50
+1,20,3,[40,5,140,60,160,70,170,80,180,10,5,90,190,71,171,81,181,10,5]*10,21,3,[41,5,141,61,161,72,172,82,182,10,5,91,191,73,173,83,183,10,5]*10,22,3,[42,5,142,62,162,74,174,84,184,10,5,92,192,75,175,85,185,10,5]*10
 </testcases>
 
     <GIT>
diff --git a/TestON/tests/FUNCflow/Dependency/topo-flow.py b/TestON/tests/FUNCflow/Dependency/topo-flow.py
index 2299d9e..f9d58c1 100755
--- a/TestON/tests/FUNCflow/Dependency/topo-flow.py
+++ b/TestON/tests/FUNCflow/Dependency/topo-flow.py
@@ -14,24 +14,47 @@
 from mininet.util import dumpNodeConnections
 from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
 
+class VLANHost( Host ):
+    def config( self, vlan=100, **params ):
+        r = super( Host, self ).config( **params )
+        intf = self.defaultIntf()
+        self.cmd( 'ifconfig %s inet 0' % intf )
+        self.cmd( 'vconfig add %s %d' % ( intf, vlan ) )
+        self.cmd( 'ifconfig %s.%d inet %s' % ( intf, vlan, params['ip'] ) )
+        newName = '%s.%d' % ( intf, vlan )
+        intf.name = newName
+        self.nameToIntf[ newName ] = intf
+        return r
+
+class IPv6Host( Host ):
+    def config( self, v6Addr='1000:1/64', **params ):
+        r = super( Host, self ).config( **params )
+        intf = self.defaultIntf()
+        self.cmd( 'ifconfig %s inet 0' % intf )
+        self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) )
+        return r
+
 class MyTopo( Topo ):
 
-    def __init__( self ):
+    def __init__( self, **opts ):
         # Initialize topology
-        Topo.__init__( self )
-        # Switch S5 Hosts
-        host1=self.addHost( 'h1', ip='10.1.0.1/24' )
-        host2=self.addHost( 'h2', ip='10.1.0.2/24' )
-        #host3=self.addHost( 'h3', ip='10.1.0.3/24', v6Addr='1000::3/64' )
-        #host4=self.addHost( 'h4', ip='10.1.0.4/24', v6Addr='1000::4/64' )
+        Topo.__init__( self, **opts)
+
+        # IPv4 hosts
+        host1=self.addHost( 'h1', ip='10.0.0.1/24' )
+        host2=self.addHost( 'h2', ip='10.0.0.2/24' )
+
+        # VLAN hosts
+        host3=self.addHost( 'h3', ip='10.0.0.3/24', cls=VLANHost, vlan=10 )
+        host4=self.addHost( 'h4', ip='10.0.0.4/24', cls=VLANHost, vlan=10 )
+
 
         s1 = self.addSwitch( 's1' )
-        #s2 = self.addSwitch( 's2' )
 
         self.addLink(s1, host1)
         self.addLink(s1, host2)
-        #self.addLink(s1, host3)
-        #self.addLink(s1, host4)
+        self.addLink(s1, host3)
+        self.addLink(s1, host4)
 
 
         topos = { 'mytopo': ( lambda: MyTopo() ) }
@@ -39,7 +62,7 @@
 def setupNetwork():
     "Create network"
     topo = MyTopo()
-    network = Mininet(topo=topo, autoSetMacs=True, controller=None)
+    network = Mininet(topo=topo, autoSetMacs=True, autoStaticArp=True, controller=None)
     network.start()
     CLI( network )
     network.stop()
diff --git a/TestON/tests/FUNCflow/FUNCflow.params b/TestON/tests/FUNCflow/FUNCflow.params
index 0aa8e89..7353e69 100755
--- a/TestON/tests/FUNCflow/FUNCflow.params
+++ b/TestON/tests/FUNCflow/FUNCflow.params
@@ -1,16 +1,19 @@
 
 <PARAMS>
     # CASE - Descritpion
+    # 1,2,10,1000,1100,2000,1200,2000,100
     # 1 - Variable initialization and optional pull and build ONOS package
     # 2 - install ONOS
     # 8 - Compare topology
     # 9 - Report logs
-    # 10 - Start mininet and assign switches to controller
+    # 10 - Start mininet and verify topology
     # 66 - Testing Scapy
-    # 1000 - Add flows
-    # 2000 - Verify flows are in the ADDED state
-    # 3000 - Delete flows
-    <testcases>1,2,10,11,1000,2000,[66]*3,3000</testcases>
+    # 1000 - Add flows with MAC selectors
+    # 1100 - Add flows with IPv4 selectors
+    # 1200 - Add flows with vlan selector
+    # 2000 - Delete flows
+
+    <testcases>1,2,10,1000,2,1100,2,1200,100</testcases>
 
     <SCALE>
         <max>1</max>
@@ -23,19 +26,6 @@
         <topology>topo-flow.py</topology>
     </DEPENDENCY>
 
-
-    <TOPO>
-        <numSwitches>1</numSwitches>
-        <numHosts>2</numHosts>
-        <numLinks>0</numLinks>
-    </TOPO>
-
-    <MININET>
-        <deviceId>of:0000000000000001</deviceId>
-        <hostMac1>00:00:00:00:00:01</hostMac1>
-        <hostMac2>00:00:00:00:00:02</hostMac2>
-    </MININET>
-
     <ENV>
         <cellName>productionCell</cellName>
         <cellApps>drivers,openflow</cellApps>
@@ -50,8 +40,19 @@
         <port>6653</port>
     </CTRL>
 
+    <TEST>
+        <vlan>10</vlan>
+        <ip4Type>2048</ip4Type>
+        <ip6Type>34525</ip6Type>
+        <vlanType>33024</vlanType>
+        <swDPID>of:0000000000000001</swDPID>
+    </TEST>
+
     <SLEEP>
         <startup>15</startup>
+        <startMN>5</startMN>
+        <addFlow>10</addFlow>
+        <delFlow>10</delFlow>
     </SLEEP>
 
 </PARAMS>
diff --git a/TestON/tests/FUNCflow/FUNCflow.py b/TestON/tests/FUNCflow/FUNCflow.py
index 89a7e32..0fa77a2 100644
--- a/TestON/tests/FUNCflow/FUNCflow.py
+++ b/TestON/tests/FUNCflow/FUNCflow.py
@@ -27,24 +27,24 @@
         main.cellName = main.params[ 'ENV' ][ 'cellName' ]
         main.apps = main.params[ 'ENV' ][ 'cellApps' ]
         gitBranch = main.params[ 'GIT' ][ 'branch' ]
+        gitPull = main.params[ 'GIT' ][ 'pull' ]
+        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
         main.dependencyPath = main.testOnDirectory + \
                               main.params[ 'DEPENDENCY' ][ 'path' ]
-        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
-        main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
-        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
-        main.numSwitches = int( main.params[ 'TOPO' ][ 'numSwitches' ] )
-        main.numHosts = int( main.params[ 'TOPO' ][ 'numHosts' ] )
-        main.numLinks = int( main.params[ 'TOPO' ][ 'numLinks' ] )
         wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
         wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+        main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
         main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
-        gitPull = main.params[ 'GIT' ][ 'pull' ]
+        main.startMNSleep = int( main.params[ 'SLEEP' ][ 'startMN' ] )
+        main.addFlowSleep = int( main.params[ 'SLEEP' ][ 'addFlow' ] )
+        main.delFlowSleep = int( main.params[ 'SLEEP' ][ 'delFlow' ] )
+        main.swDPID = main.params[ 'TEST' ][ 'swDPID' ]
         main.cellData = {} # for creating cell file
         main.CLIs = []
         main.ONOSip = []
 
         main.ONOSip = main.ONOSbench.getOnosIps()
-        print main.ONOSip
 
         # Assigning ONOS cli handles to a list
         for i in range( 1,  main.maxNodes + 1 ):
@@ -207,49 +207,33 @@
         '''
             Start Mininet
         '''
-        main.case( "Setup mininet and assign switches to controllers" )
+        import json
+
+        main.case( "Setup mininet and compare ONOS topology view to Mininet topology" )
+        main.caseExplanation = "Start mininet with custom topology and compare topology " +\
+                "elements between Mininet and ONOS"
+
         main.step( "Setup Mininet Topology" )
         topology = main.Mininet1.home + '/custom/' + main.topology
-        mnCmd = 'mn --custom ' + topology + ' --mac --arp'
-        stepResult1 = main.Mininet1.startNet( mnCmd=mnCmd )
+        stepResult = main.Mininet1.startNet( topoFile=topology )
 
         utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult1,
+                                 actual=stepResult,
                                  onpass="Successfully loaded topology",
                                  onfail="Failed to load topology" )
 
-        main.step( "Assign switches to controllers" )
-        for i in range( main.numSwitches ):
-            stepResult2 = main.Mininet1.assignSwController(
-                                            sw="s" + str( i+1 ),
-                                            ip=main.ONOSip )
-            if not stepResult2:
-                break
+        main.step( "Assign switch to controller" )
+        stepResult = main.Mininet1.assignSwController( "s1", main.ONOSip[0] )
 
         utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult2,
-                                 onpass="Controller assignment successfull",
-                                 onfail="Controller assignment failed" )
+                                 actual=stepResult,
+                                 onpass="Successfully assigned switch to controller",
+                                 onfail="Failed to assign switch to controller" )
 
-        time.sleep(5)
+        time.sleep( main.startMNSleep )
 
-        caseResult = stepResult1 and stepResult2
-        if not caseResult:
-            main.cleanup()
-            main.exit()
-
-    def CASE11( self, main ):
-        '''
-            Compare topology
-        '''
-        import json
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology elements between Mininet" +\
-                                " and ONOS"
-
-        main.step( "Gathering topology information" )
-        # TODO: add a paramaterized sleep here
+        main.step( "Conmparing MN topology to ONOS topology" )
+        main.log.info( "Gathering topology information" )
         devicesResults = main.TRUE
         linksResults = main.TRUE
         hostsResults = main.TRUE
@@ -263,7 +247,6 @@
         mnLinks = main.Mininet1.getLinks()
         mnHosts = main.Mininet1.getHosts()
 
-        main.step( "Conmparing MN topology to ONOS topology" )
         for controller in range( main.numCtrls ):
             controllerStr = str( controller + 1 )
             if devices[ controller ] and ports[ controller ] and\
@@ -309,7 +292,6 @@
                                             " hosts don't match Mininet")
 
 
-
     def CASE66( self, main ):
         '''
         Testing scapy
@@ -380,75 +362,301 @@
 
     def CASE1000( self, main ):
         '''
-            Add flows
+            Add flows with MAC selectors and verify the flows
         '''
+        import json
+        import time
 
-        main.step("Add flows through rest")
+        main.case( "Verify flow MAC selectors are correctly compiled" )
+        main.caseExplanation = "Install two flows with only MAC selectors " +\
+                "specified, then verify flows are added in ONOS, finally "+\
+                "send a packet that only specifies the MAC src and dst."
 
-        deviceId = main.params['MININET']['deviceId']
-        host1_mac = main.params['MININET']['hostMac1']
-        host2_mac = main.params['MININET']['hostMac2']
+        main.step( "Add flows with MAC addresses as the only selectors" )
 
-        # Add flows that connects host1 to host 2
-        stepResult = main.ONOSrest.addFlow( deviceId=deviceId,
-                                            egressPort=2,
-                                            ingressPort=1,
-                                            ethSrc=host1_mac,
-                                            ethDst=host2_mac)
+        main.log.info( "Creating host components" )
+        main.Mininet1.createHostComponent( "h1" )
+        main.Mininet1.createHostComponent( "h2" )
+        hosts = [main.h1, main.h2]
+        stepResult = main.TRUE
+        for host in hosts:
+            host.startHostCli()
+            host.startScapy()
+            host.updateSelf()
 
-        stepResult = stepResult and main.ONOSrest.addFlow( deviceId=deviceId,
-                                                           egressPort=1,
-                                                           ingressPort=2,
-                                                           ethSrc=host2_mac,
-                                                           ethDst=host1_mac)
+        # Add a flow that connects host1 on port1 to host2 on port2
+        # send output on port2
+        # recieve input on port1
+        egress = 2
+        ingress = 1
+
+        # Add flows that sends packets from port1 to port2 with correct
+        # MAC src and dst addresses
+        main.log.info( "Adding flow with MAC selectors" )
+        stepResult = main.ONOSrest.addFlow( deviceId=main.swDPID,
+                                            egressPort=egress,
+                                            ingressPort=ingress,
+                                            ethSrc=main.h1.hostMac,
+                                            ethDst=main.h2.hostMac,
+                                            debug=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="Successfully added flows",
                                  onfail="Failed add flows" )
 
-    def CASE2000( self, main ):
-        '''
-            Check flows are ADDED
-        '''
-        import json
-        main.step("Check flows  are in the ADDED state")
-        main.log.info("Check only the flows added through REST")
+        # Giving ONOS time to add the flows
+        time.sleep( main.addFlowSleep )
 
+        main.step( "Check flows are in the ADDED state" )
+
+        #TODO: We should check mininet if flows are added as well
+        main.log.info( "Get the flows from ONOS" )
         flows = json.loads( main.ONOSrest.flows() )
 
         stepResult = main.TRUE
         for f in flows:
             if "rest" in f.get("appId"):
-                if "ADDED" in f.get("state"):
-                    stepResult = stepResult and main.ONOSrest.removeFlow( deviceId, flowId )
+                if "ADDED" not in f.get("state"):
+                    stepResult = main.FALSE
+                    main.log.error( "Flow: %s in state: %s" % (f.get("id"), f.get("state")) )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="All flows are in the ADDED state",
-                                 onfail="All flows are in the ADDED state" )
+                                 onfail="All flows are NOT in the ADDED state" )
 
-    def CASE3000( self, main ):
+        main.step( "Send a packet to verify the flows are correct" )
+
+        # Specify the src and dst MAC addr
+        main.log.info( "Constructing packet" )
+        main.h1.buildEther( src=main.h1.hostMac, dst=main.h2.hostMac )
+
+        # Filter for packets with the correct host name. Otherwise,
+        # the filter we catch any packet that is sent to host2
+        # NOTE: I believe it doesn't matter which host name it is,
+        # as long as its host1 or host2
+        main.log.info( "Starting filter on host2" )
+        main.h2.startFilter( pktFilter="ether host %s" % main.h1.hostMac)
+
+        main.log.info( "Sending packet to host2" )
+        main.h1.sendPacket()
+
+        main.log.info( "Checking filter for our packet" )
+        stepResult = main.h2.checkFilter()
+        if stepResult:
+            main.log.info( "Packet: %s" % main.h2.readPackets() )
+        else: main.h2.killFilter()
+
+        main.log.info( "Clean up host components" )
+        for host in hosts:
+            host.stopScapy()
+        main.Mininet1.removeHostComponent("h1")
+        main.Mininet1.removeHostComponent("h2")
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully sent a packet",
+                                 onfail="Failed to send a packet" )
+
+    def CASE1100( self, main ):
         '''
-            Delete flows that were added through REST
+            Add flows with IPv4 selectors and verify the flows
         '''
         import json
-        main.step("Remove flows")
-        main.log.info("Remove the flows that were added through rest")
+        import time
 
+        main.case( "Verify flow IP selectors are correctly compiled" )
+        main.caseExplanation = "Install two flows with only IP selectors " +\
+                "specified, then verify flows are added in ONOS, finally "+\
+                "send a packet that only specifies the IP src and dst."
+
+        main.step( "Add flows with IPv4 addresses as the only selectors" )
+
+        main.log.info( "Creating host components" )
+        main.Mininet1.createHostComponent( "h1" )
+        main.Mininet1.createHostComponent( "h2" )
+        hosts = [main.h1, main.h2]
+        stepResult = main.TRUE
+        for host in hosts:
+            host.startHostCli()
+            host.startScapy()
+            host.updateSelf()
+
+        # Add a flow that connects host1 on port1 to host2 on port2
+        # send output on port2
+        # recieve input on port1
+        egress = 2
+        ingress = 1
+        # IPv4 etherType = 0x800
+        IPv4=2048
+
+        # Add flows that connects host1 to host2
+        main.log.info( "Add flow with port ingress 1 to port egress 2" )
+        stepResult = main.ONOSrest.addFlow( deviceId=main.swDPID,
+                                            egressPort=egress,
+                                            ingressPort=ingress,
+                                            ethType=IPv4,
+                                            ipSrc=("IPV4_SRC", main.h1.hostIp+"/32"),
+                                            ipDst=("IPV4_DST", main.h2.hostIp+"/32"),
+                                            debug=True )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully added flows",
+                                 onfail="Failed add flows" )
+
+        # Giving ONOS time to add the flow
+        time.sleep( main.addFlowSleep )
+
+        main.step( "Check flow is in the ADDED state" )
+
+        main.log.info( "Get the flows from ONOS" )
         flows = json.loads( main.ONOSrest.flows() )
 
         stepResult = main.TRUE
         for f in flows:
             if "rest" in f.get("appId"):
-                flowId = f.get("id")
-                deviceId = f.get("deviceId")
-                stepResult = stepResult and main.ONOSrest.removeFlow( deviceId, flowId )
+                if "ADDED" not in f.get("state"):
+                    stepResult = main.FALSE
+                    main.log.error( "Flow: %s in state: %s" % (f.get("id"), f.get("state")) )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="Successfully removed all rest flows",
-                                 onfail="Failed to remove rest flows" )
+                                 onpass="All flows are in the ADDED state",
+                                 onfail="All flows are NOT in the ADDED state" )
+
+        main.step( "Send a packet to verify the flow is correct" )
+
+        main.log.info( "Constructing packet" )
+        # No need for the MAC src dst
+        main.h1.buildEther( dst=main.h2.hostMac )
+        main.h1.buildIP( src=main.h1.hostIp, dst=main.h2.hostIp )
+
+        main.log.info( "Starting filter on host2" )
+        # Defaults to ip
+        main.h2.startFilter()
+
+        main.log.info( "Sending packet to host2" )
+        main.h1.sendPacket()
+
+        main.log.info( "Checking filter for our packet" )
+        stepResult = main.h2.checkFilter()
+        if stepResult:
+            main.log.info( "Packet: %s" % main.h2.readPackets() )
+        else: main.h2.killFilter()
+
+        main.log.info( "Clean up host components" )
+        for host in hosts:
+            host.stopScapy()
+        main.Mininet1.removeHostComponent("h1")
+        main.Mininet1.removeHostComponent("h2")
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully sent a packet",
+                                 onfail="Failed to send a packet" )
+
+    def CASE1200( self, main ):
+        '''
+            Add flow with VLAN selector and verify the flow
+        '''
+        import json
+        import time
+
+        main.case( "Verify VLAN selector is correctly compiled" )
+        main.caseExplanation = "Install one flow with only the VLAN selector " +\
+                "specified, then verify the flow is added in ONOS, and finally "+\
+                "broadcast a packet with the correct VLAN tag."
+
+        # We do this here to utilize the hosts information
+        main.log.info( "Creating host components" )
+        main.Mininet1.createHostComponent( "h3" )
+        main.Mininet1.createHostComponent( "h4" )
+        hosts = [main.h3, main.h4]
+        stepResult = main.TRUE
+        for host in hosts:
+            host.startHostCli()
+            host.startScapy()
+            host.updateSelf()
+
+
+        main.step( "Add a flow with the VLAN tag as the only selector" )
+
+        # Add flows that connects the two vlan hosts h3 and h4
+        # Host 3 is on port 3 and host 4 is on port 4
+        vlan = main.params[ 'TEST' ][ 'vlan' ]
+        egress = 4
+        ingress = 3
+        # VLAN ethType = 0x8100
+        ethType = 33024
+
+        # Add only one flow because we don't need a response
+        main.log.info( "Add flow with port ingress 1 to port egress 2" )
+        stepResult = main.ONOSrest.addFlow( deviceId=main.swDPID,
+                                            egressPort=egress,
+                                            ingressPort=ingress,
+                                            ethType=ethType,
+                                            vlan=vlan,
+                                            debug=True )
+
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully added flow",
+                                 onfail="Failed add flows" )
+
+        # Giving ONOS time to add the flows
+        time.sleep( main.addFlowSleep )
+
+        main.step( "Check flows  are in the ADDED state" )
+
+        main.log.info( "Get the flows from ONOS" )
+        flows = json.loads( main.ONOSrest.flows() )
+
+        stepResult = main.TRUE
+        for f in flows:
+            if "rest" in f.get("appId"):
+                if "ADDED" not in f.get("state"):
+                    stepResult = main.FALSE
+                    main.log.error( "Flow: %s in state: %s" % (f.get("id"), f.get("state")) )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="All flows are in the ADDED state",
+                                 onfail="All flows are NOT in the ADDED state" )
+
+        main.step( "Send a packet to verify the flow are correct" )
+
+        # The receiving interface
+        recIface = "{}-eth0.{}".format(main.h4.name, vlan)
+        main.log.info( "Starting filter on host2" )
+        # Filter is setup to catch any packet on the vlan interface with the correct vlan tag
+        main.h4.startFilter( ifaceName=recIface, pktFilter="" )
+
+        # Broadcast the packet on the vlan interface. We only care if the flow forwards
+        # the packet with the correct vlan tag, not if the mac addr is correct
+        BROADCAST = "FF:FF:FF:FF:FF:FF"
+        sendIface = "{}-eth0.{}".format(main.h3.name, vlan)
+        main.log.info( "Broadcasting the packet with a vlan tag" )
+        main.h3.sendPacket( iface=sendIface, packet="Ether(dst='{}')/Dot1Q(vlan={})".format(BROADCAST, vlan))
+
+        main.log.info( "Checking filter for our packet" )
+        stepResult = main.h4.checkFilter()
+        if stepResult:
+            main.log.info( "Packet: %s" % main.h4.readPackets() )
+        else: main.h4.killFilter()
+
+        main.log.info( "Clean up host components" )
+        for host in hosts:
+            host.stopScapy()
+        main.Mininet1.removeHostComponent("h3")
+        main.Mininet1.removeHostComponent("h4")
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully sent a packet",
+                                 onfail="Failed to send a packet" )
 
     def CASE100( self, main ):
         '''
diff --git a/TestON/tests/FUNCoptical/Dependency/FuncIntentFunction.py b/TestON/tests/FUNCoptical/Dependency/FuncIntentFunction.py
new file mode 100644
index 0000000..377fd20
--- /dev/null
+++ b/TestON/tests/FUNCoptical/Dependency/FuncIntentFunction.py
@@ -0,0 +1,1631 @@
+"""
+    Wrapper functions for FuncIntent
+    This functions include Onosclidriver and Mininetclidriver driver functions
+    Author: kelvin@onlab.us
+"""
+import time
+import copy
+import json
+
+def __init__( self ):
+    self.default = ''
+
+def hostIntent( main,
+                name,
+                host1,
+                host2,
+                onosNode=0,
+                host1Id="",
+                host2Id="",
+                mac1="",
+                mac2="",
+                vlan1="-1",
+                vlan2="-1",
+                sw1="",
+                sw2="",
+                expectedLink=0 ):
+    """
+    Description:
+        Verify add-host-intent
+    Steps:
+        - Discover hosts
+        - Add host intents
+        - Check intents
+        - Verify flows
+        - Ping hosts
+        - Reroute
+            - Link down
+            - Verify flows
+            - Check topology
+            - Ping hosts
+            - Link up
+            - Verify flows
+            - Check topology
+            - Ping hosts
+        - Remove intents
+    Required:
+        name - Type of host intent to add eg. IPV4 | VLAN | Dualstack
+        host1 - Name of first host
+        host2 - Name of second host
+    Optional:
+        onosNode - ONOS node to install the intents in main.CLIs[ ]
+                   0 by default so that it will always use the first
+                   ONOS node
+        host1Id - ONOS id of the first host eg. 00:00:00:00:00:01/-1
+        host2Id - ONOS id of the second host
+        mac1 - Mac address of first host
+        mac2 - Mac address of the second host
+        vlan1 - Vlan tag of first host, defaults to -1
+        vlan2 - Vlan tag of second host, defaults to -1
+        sw1 - First switch to bring down & up for rerouting purpose
+        sw2 - Second switch to bring down & up for rerouting purpose
+        expectedLink - Expected link when the switches are down, it should
+                       be two links lower than the links before the two
+                       switches are down
+    Return:
+        Returns main.TRUE if all verification passed, otherwise return
+        main.FALSE; returns main.FALSE if there is a key error
+    """
+
+    # Assert variables
+    assert main, "There is no main variable"
+    assert name, "variable name is empty"
+    assert host1 and host2, "You must specify hosts"
+
+    global itemName
+    itemName = name
+    h1Id = host1Id
+    h2Id = host2Id
+    h1Mac = mac1
+    h2Mac = mac2
+    vlan1 = vlan1
+    vlan2 = vlan2
+    hostNames = [ host1 , host2 ]
+    intentsId = []
+    stepResult = main.TRUE
+    pingResult = main.TRUE
+    intentResult = main.TRUE
+    removeIntentResult = main.TRUE
+    flowResult = main.TRUE
+    topoResult = main.TRUE
+    linkDownResult = main.TRUE
+    linkUpResult = main.TRUE
+    onosNode = int( onosNode )
+
+    try:
+        if main.hostsData:
+            if not h1Mac:
+                h1Mac = main.hostsData[ host1 ][ 'mac' ]
+            if not h2Mac:
+                h2Mac = main.hostsData[ host2 ][ 'mac' ]
+            if main.hostsData[ host1 ].get( 'vlan' ):
+                vlan1 = main.hostsData[ host1 ][ 'vlan' ]
+            if main.hostsData[ host1 ].get( 'vlan' ):
+                vlan2 = main.hostsData[ host2 ][ 'vlan' ]
+            if not h1Id:
+                h1Id = main.hostsData[ host1 ][ 'id' ]
+            if not h2Id:
+                h2Id = main.hostsData[ host2 ][ 'id' ]
+
+        assert h1Id and h2Id, "You must specify host IDs"
+        if not ( h1Id and h2Id ):
+            main.log.info( "There are no host IDs" )
+            return main.FALSE
+
+    except KeyError:
+        main.log.error( itemName + ": Key error Exception" )
+        return main.FALSE
+
+    # Discover hosts using arping incase pingall discovery failed
+    main.log.info( itemName + ": Discover host using arping" )
+    main.Mininet1.arping( srcHost=host1, dstHost=host2 )
+    main.Mininet1.arping( srcHost=host2, dstHost=host1 )
+    host1 = main.CLIs[ 0 ].getHost( mac=h1Mac )
+    host2 = main.CLIs[ 0 ].getHost( mac=h2Mac )
+
+    # Check flows count in each node
+    checkFlowsCount( main )
+
+    # Adding host intents
+    main.log.info( itemName + ": Adding host intents" )
+    intent1 = main.CLIs[ onosNode ].addHostIntent( hostIdOne=h1Id,
+                                                   hostIdTwo=h2Id )
+    intentsId.append( intent1 )
+
+    # Check intents state
+    time.sleep( main.checkIntentSleep )
+    intentResult = checkIntentState( main, intentsId )
+    checkFlowsCount( main )
+
+    # Check intents state again if first check fails...
+    if not intentResult:
+        intentResult = checkIntentState( main, intentsId )
+
+    # Check flows count in each node
+    checkFlowsCount( main )
+    # Verify flows
+    checkFlowsState( main )
+
+    # Ping hosts
+    firstPingResult = pingallHosts( main, hostNames )
+    if not firstPingResult:
+        main.log.debug( "First ping failed, there must be" +
+                       " something wrong with ONOS performance" )
+
+    # Ping hosts again...
+    pingTemp = pingallHosts( main, hostNames )
+    pingResult = pingResult and pingTemp
+    if pingTemp:
+        main.assertReturnString += 'Initial Pingall Passed\n'
+    else:
+        main.assertReturnString += 'Initial Pingall Failed\n'
+
+    # Test rerouting if these variables exist
+    if sw1 and sw2 and expectedLink:
+        # Link down
+        linkDownResult = link( main, sw1, sw2, "down" )
+
+        if linkDownResult:
+            main.assertReturnString += 'Link Down Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Failed\n'
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, expectedLink )
+        if topoResult:
+            main.assertReturnString += 'Link Down Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Topology State Failed\n'
+
+        # Ping hosts
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+
+        if pingTemp:
+            main.assertReturnString += 'Link Down Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Pingall Failed\n'
+
+        # Check intent states
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
+
+        # Checks ONOS state in link down
+        if linkDownResult and topoResult and pingResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link down" )
+        else:
+            main.log.error( itemName + ": Failed to bring link down" )
+
+        # Link up
+        linkUpResult = link( main, sw1, sw2, "up" )
+        time.sleep( main.rerouteSleep )
+
+        if linkUpResult:
+            main.assertReturnString += 'Link Up Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Failed\n'
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, main.numLinks )
+
+        if topoResult:
+            main.assertReturnString += 'Link Up Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Topology State Failed\n'
+
+        # Ping hosts
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+
+        if pingTemp:
+            main.assertReturnString += 'Link Up Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Pingall Failed\n'
+
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Up Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Intent State Failed\n'
+
+        # Checks ONOS state in link up
+        if linkUpResult and topoResult and pingResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link back up" )
+        else:
+            main.log.error( itemName + ": Failed to bring link back up" )
+
+    # Remove all intents
+    removeIntentResult = removeAllIntents( main, intentsId )
+
+    if removeIntentResult:
+        main.assertReturnString += 'Remove Intents Passed'
+    else:
+        main.assertReturnString += 'Remove Intents Failed'
+
+    stepResult = pingResult and linkDownResult and linkUpResult \
+                 and intentResult and removeIntentResult
+
+    return stepResult
+
+def pointIntent( main,
+                 name,
+                 host1,
+                 host2,
+                 onosNode=0,
+                 deviceId1="",
+                 deviceId2="",
+                 port1="",
+                 port2="",
+                 ethType="",
+                 mac1="",
+                 mac2="",
+                 bandwidth="",
+                 lambdaAlloc=False,
+                 ipProto="",
+                 ip1="",
+                 ip2="",
+                 tcp1="",
+                 tcp2="",
+                 sw1="",
+                 sw2="",
+                 expectedLink=0 ):
+
+    """
+    Description:
+        Verify add-point-intent
+    Steps:
+        - Get device ids | ports
+        - Add point intents
+        - Check intents
+        - Verify flows
+        - Ping hosts
+        - Reroute
+            - Link down
+            - Verify flows
+            - Check topology
+            - Ping hosts
+            - Link up
+            - Verify flows
+            - Check topology
+            - Ping hosts
+        - Remove intents
+    Required:
+        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
+        host1 - Name of first host
+        host2 - Name of second host
+    Optional:
+        onosNode - ONOS node to install the intents in main.CLIs[ ]
+                   0 by default so that it will always use the first
+                   ONOS node
+        deviceId1 - ONOS device id of the first switch, the same as the
+                    location of the first host eg. of:0000000000000001/1,
+                    located at device 1 port 1
+        deviceId2 - ONOS device id of the second switch
+        port1 - The port number where the first host is attached
+        port2 - The port number where the second host is attached
+        ethType - Ethernet type eg. IPV4, IPV6
+        mac1 - Mac address of first host
+        mac2 - Mac address of the second host
+        bandwidth - Bandwidth capacity
+        lambdaAlloc - Allocate lambda, defaults to False
+        ipProto - IP protocol
+        ip1 - IP address of first host
+        ip2 - IP address of second host
+        tcp1 - TCP port of first host
+        tcp2 - TCP port of second host
+        sw1 - First switch to bring down & up for rerouting purpose
+        sw2 - Second switch to bring down & up for rerouting purpose
+        expectedLink - Expected link when the switches are down, it should
+                       be two links lower than the links before the two
+                       switches are down
+    """
+
+    assert main, "There is no main variable"
+    assert name, "variable name is empty"
+    assert host1 and host2, "You must specify hosts"
+
+    global itemName
+    itemName = name
+    host1 = host1
+    host2 = host2
+    hostNames = [ host1, host2 ]
+    intentsId = []
+
+    pingResult = main.TRUE
+    intentResult = main.TRUE
+    removeIntentResult = main.TRUE
+    flowResult = main.TRUE
+    topoResult = main.TRUE
+    linkDownResult = main.TRUE
+    linkUpResult = main.TRUE
+    onosNode = int( onosNode )
+
+    # Adding bidirectional point  intents
+    main.log.info( itemName + ": Adding point intents" )
+    intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
+                                             egressDevice=deviceId2,
+                                             portIngress=port1,
+                                             portEgress=port2,
+                                             ethType=ethType,
+                                             ethSrc=mac1,
+                                             ethDst=mac2,
+                                             bandwidth=bandwidth,
+                                             lambdaAlloc=lambdaAlloc,
+                                             ipProto=ipProto,
+                                             ipSrc=ip1,
+                                             ipDst=ip2,
+                                             tcpSrc=tcp1,
+                                             tcpDst=tcp2 )
+
+    intentsId.append( intent1 )
+    intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
+                                             egressDevice=deviceId1,
+                                             portIngress=port2,
+                                             portEgress=port1,
+                                             ethType=ethType,
+                                             ethSrc=mac2,
+                                             ethDst=mac1,
+                                             bandwidth=bandwidth,
+                                             lambdaAlloc=lambdaAlloc,
+                                             ipProto=ipProto,
+                                             ipSrc=ip2,
+                                             ipDst=ip1,
+                                             tcpSrc=tcp2,
+                                             tcpDst=tcp1 )
+    intentsId.append( intent2 )
+
+    # Check intents state
+    time.sleep( main.checkIntentSleep )
+    intentResult = checkIntentState( main, intentsId )
+    # Check flows count in each node
+    checkFlowsCount( main )
+
+    # Check intents state again if first check fails...
+    if not intentResult:
+        intentResult = checkIntentState( main, intentsId )
+
+    # Check flows count in each node
+    checkFlowsCount( main )
+    # Verify flows
+    checkFlowsState( main )
+
+    # Ping hosts
+    pingTemp = pingallHosts( main, hostNames )
+    pingResult = pingResult and pingTemp
+    if pingTemp:
+        main.assertReturnString += 'Initial Pingall Passed\n'
+    else:
+        main.assertReturnString += 'Initial Pingall Failed\n'
+
+    # Test rerouting if these variables exist
+    if sw1 and sw2 and expectedLink:
+        # link down
+        linkDownResult = link( main, sw1, sw2, "down" )
+
+        if linkDownResult:
+            main.assertReturnString += 'Link Down Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Failed\n'
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, expectedLink )
+        if topoResult:
+            main.assertReturnString += 'Link Down Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Topology State Failed\n'
+
+        # Ping hosts
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+        if pingTemp:
+            main.assertReturnString += 'Link Down Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Pingall Failed\n'
+
+        # Check intent state
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
+
+        # Checks ONOS state in link down
+        if linkDownResult and topoResult and pingResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link down" )
+        else:
+            main.log.error( itemName + ": Failed to bring link down" )
+
+        # link up
+        linkUpResult = link( main, sw1, sw2, "up" )
+        if linkUpResult:
+            main.assertReturnString += 'Link Up Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Failed\n'
+
+        time.sleep( main.rerouteSleep )
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, main.numLinks )
+        if topoResult:
+            main.assertReturnString += 'Link Up Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Topology State Failed\n'
+
+        # Ping hosts
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+
+        if pingTemp:
+            main.assertReturnString += 'Link Up Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Pingall Failed\n'
+
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Up Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Intent State Failed\n'
+
+        # Checks ONOS state in link up
+        if linkUpResult and topoResult and pingResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link back up" )
+        else:
+            main.log.error( itemName + ": Failed to bring link back up" )
+
+    # Remove all intents
+    removeIntentResult = removeAllIntents( main, intentsId )
+    if removeIntentResult:
+        main.assertReturnString += 'Remove Intents Passed'
+    else:
+        main.assertReturnString += 'Remove Intents Failed'
+
+    stepResult = pingResult and linkDownResult and linkUpResult \
+                 and intentResult and removeIntentResult
+
+    return stepResult
+
+def pointIntentTcp( main,
+                    name,
+                    host1,
+                    host2,
+                    onosNode=0,
+                    deviceId1="",
+                    deviceId2="",
+                    port1="",
+                    port2="",
+                    ethType="",
+                    mac1="",
+                    mac2="",
+                    bandwidth="",
+                    lambdaAlloc=False,
+                    ipProto="",
+                    ip1="",
+                    ip2="",
+                    tcp1="",
+                    tcp2="",
+                    sw1="",
+                    sw2="",
+                    expectedLink=0 ):
+
+    """
+    Description:
+        Verify add-point-intent only for TCP
+    Steps:
+        - Get device ids | ports
+        - Add point intents
+        - Check intents
+        - Verify flows
+        - Ping hosts
+        - Reroute
+            - Link down
+            - Verify flows
+            - Check topology
+            - Ping hosts
+            - Link up
+            - Verify flows
+            - Check topology
+            - Ping hosts
+        - Remove intents
+    Required:
+        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
+        host1 - Name of first host
+        host2 - Name of second host
+    Optional:
+        onosNode - ONOS node to install the intents in main.CLIs[ ]
+                   0 by default so that it will always use the first
+                   ONOS node
+        deviceId1 - ONOS device id of the first switch, the same as the
+                    location of the first host eg. of:0000000000000001/1,
+                    located at device 1 port 1
+        deviceId2 - ONOS device id of the second switch
+        port1 - The port number where the first host is attached
+        port2 - The port number where the second host is attached
+        ethType - Ethernet type eg. IPV4, IPV6
+        mac1 - Mac address of first host
+        mac2 - Mac address of the second host
+        bandwidth - Bandwidth capacity
+        lambdaAlloc - Allocate lambda, defaults to False
+        ipProto - IP protocol
+        ip1 - IP address of first host
+        ip2 - IP address of second host
+        tcp1 - TCP port of first host
+        tcp2 - TCP port of second host
+        sw1 - First switch to bring down & up for rerouting purpose
+        sw2 - Second switch to bring down & up for rerouting purpose
+        expectedLink - Expected link when the switches are down, it should
+                       be two links lower than the links before the two
+                       switches are down
+    """
+
+    assert main, "There is no main variable"
+    assert name, "variable name is empty"
+    assert host1 and host2, "You must specify hosts"
+
+    global itemName
+    itemName = name
+    host1 = host1
+    host2 = host2
+    hostNames = [ host1, host2 ]
+    intentsId = []
+
+    iperfResult = main.TRUE
+    intentResult = main.TRUE
+    removeIntentResult = main.TRUE
+    flowResult = main.TRUE
+    topoResult = main.TRUE
+    linkDownResult = main.TRUE
+    linkUpResult = main.TRUE
+    onosNode = int( onosNode )
+
+    # Adding bidirectional point  intents
+    main.log.info( itemName + ": Adding point intents" )
+    intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
+                                                    egressDevice=deviceId2,
+                                                    portIngress=port1,
+                                                    portEgress=port2,
+                                                    ethType=ethType,
+                                                    ethSrc=mac1,
+                                                    ethDst=mac2,
+                                                    bandwidth=bandwidth,
+                                                    lambdaAlloc=lambdaAlloc,
+                                                    ipProto=ipProto,
+                                                    ipSrc=ip1,
+                                                    ipDst=ip2,
+                                                    tcpSrc=tcp1,
+                                                    tcpDst="" )
+
+    intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
+                                                    egressDevice=deviceId1,
+                                                    portIngress=port2,
+                                                    portEgress=port1,
+                                                    ethType=ethType,
+                                                    ethSrc=mac2,
+                                                    ethDst=mac1,
+                                                    bandwidth=bandwidth,
+                                                    lambdaAlloc=lambdaAlloc,
+                                                    ipProto=ipProto,
+                                                    ipSrc=ip2,
+                                                    ipDst=ip1,
+                                                    tcpSrc=tcp2,
+                                                    tcpDst="" )
+
+    intent3 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
+                                                    egressDevice=deviceId2,
+                                                    portIngress=port1,
+                                                    portEgress=port2,
+                                                    ethType=ethType,
+                                                    ethSrc=mac1,
+                                                    ethDst=mac2,
+                                                    bandwidth=bandwidth,
+                                                    lambdaAlloc=lambdaAlloc,
+                                                    ipProto=ipProto,
+                                                    ipSrc=ip1,
+                                                    ipDst=ip2,
+                                                    tcpSrc="",
+                                                    tcpDst=tcp2 )
+
+    intent4 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
+                                                    egressDevice=deviceId1,
+                                                    portIngress=port2,
+                                                    portEgress=port1,
+                                                    ethType=ethType,
+                                                    ethSrc=mac2,
+                                                    ethDst=mac1,
+                                                    bandwidth=bandwidth,
+                                                    lambdaAlloc=lambdaAlloc,
+                                                    ipProto=ipProto,
+                                                    ipSrc=ip2,
+                                                    ipDst=ip1,
+                                                    tcpSrc="",
+                                                    tcpDst=tcp1 )
+    intentsId.append( intent1 )
+    intentsId.append( intent2 )
+    intentsId.append( intent3 )
+    intentsId.append( intent4 )
+
+    # Check intents state
+    time.sleep( main.checkIntentSleep )
+    intentResult = checkIntentState( main, intentsId )
+    # Check flows count in each node
+    checkFlowsCount( main )
+
+    # Check intents state again if first check fails...
+    if not intentResult:
+        intentResult = checkIntentState( main, intentsId )
+
+    # Check flows count in each node
+    checkFlowsCount( main )
+
+    # Verify flows
+    checkFlowsState( main )
+
+    # Run iperf to both host
+    iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
+    iperfResult = iperfResult and iperfTemp
+    if iperfTemp:
+        main.assertReturnString += 'Initial Iperf Passed\n'
+    else:
+        main.assertReturnString += 'Initial Iperf Failed\n'
+
+    # Test rerouting if these variables exist
+    if sw1 and sw2 and expectedLink:
+        # link down
+        linkDownResult = link( main, sw1, sw2, "down" )
+
+        if linkDownResult:
+            main.assertReturnString += 'Link Down Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Failed\n'
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, expectedLink )
+        if topoResult:
+            main.assertReturnString += 'Link Down Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Topology State Failed\n'
+
+        # Run iperf to both host
+        iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
+        iperfResult = iperfResult and iperfTemp
+        if iperfTemp:
+            main.assertReturnString += 'Link Down Iperf Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Iperf Failed\n'
+
+        # Check intent state
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
+
+        # Checks ONOS state in link down
+        if linkDownResult and topoResult and iperfResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link down" )
+        else:
+            main.log.error( itemName + ": Failed to bring link down" )
+
+        # link up
+        linkUpResult = link( main, sw1, sw2, "up" )
+        if linkUpTemp:
+            main.assertReturnString += 'Link Up Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Failed\n'
+
+        time.sleep( main.rerouteSleep )
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, main.numLinks )
+
+        if topoResult:
+            main.assertReturnString += 'Link Up Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Topology State Failed\n'
+
+        # Run iperf to both host
+        iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
+        iperfResult = iperfResult and iperfTemp
+        if iperfTemp:
+            main.assertReturnString += 'Link Up Iperf Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Iperf Failed\n'
+
+        # Check intent state
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
+
+        # Checks ONOS state in link up
+        if linkUpResult and topoResult and iperfResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link back up" )
+        else:
+            main.log.error( itemName + ": Failed to bring link back up" )
+
+    # Remove all intents
+    removeIntentResult = removeAllIntents( main, intentsId )
+    if removeIntentResult:
+        main.assertReturnString += 'Remove Intents Passed'
+    else:
+        main.assertReturnString += 'Remove Intents Failed'
+
+    stepResult = iperfResult and linkDownResult and linkUpResult \
+                 and intentResult and removeIntentResult
+
+    return stepResult
+
+def singleToMultiIntent( main,
+                         name,
+                         hostNames,
+                         onosNode=0,
+                         devices="",
+                         ports=None,
+                         ethType="",
+                         macs=None,
+                         bandwidth="",
+                         lambdaAlloc=False,
+                         ipProto="",
+                         ipAddresses="",
+                         tcp="",
+                         sw1="",
+                         sw2="",
+                         expectedLink=0 ):
+    """
+    Verify Single to Multi Point intents
+    NOTE:If main.hostsData is not defined, variables data should be passed
+    in the same order index wise. All devices in the list should have the same
+    format, either all the devices have its port or it doesn't.
+    eg. hostName = [ 'h1', 'h2' ,..  ]
+        devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
+        ports = [ '1', '1', ..]
+        ...
+    Description:
+        Verify add-single-to-multi-intent iterates through the list of given
+        host | devices and add intents
+    Steps:
+        - Get device ids | ports
+        - Add single to multi point intents
+        - Check intents
+        - Verify flows
+        - Ping hosts
+        - Reroute
+            - Link down
+            - Verify flows
+            - Check topology
+            - Ping hosts
+            - Link up
+            - Verify flows
+            - Check topology
+            - Ping hosts
+        - Remove intents
+    Required:
+        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
+        hostNames - List of host names
+    Optional:
+        onosNode - ONOS node to install the intents in main.CLIs[ ]
+                   0 by default so that it will always use the first
+                   ONOS node
+        devices - List of device ids in the same order as the hosts
+                  in hostNames
+        ports - List of port numbers in the same order as the device in
+                devices
+        ethType - Ethernet type eg. IPV4, IPV6
+        macs - List of hosts mac address in the same order as the hosts in
+               hostNames
+        bandwidth - Bandwidth capacity
+        lambdaAlloc - Allocate lambda, defaults to False
+        ipProto - IP protocol
+        ipAddresses - IP addresses of host in the same order as the hosts in
+                      hostNames
+        tcp - TCP ports in the same order as the hosts in hostNames
+        sw1 - First switch to bring down & up for rerouting purpose
+        sw2 - Second switch to bring down & up for rerouting purpose
+        expectedLink - Expected link when the switches are down, it should
+                       be two links lower than the links before the two
+                       switches are down
+    """
+
+    assert main, "There is no main variable"
+    assert hostNames, "You must specify hosts"
+    assert devices or main.hostsData, "You must specify devices"
+
+    global itemName
+    itemName = name
+    tempHostsData = {}
+    intentsId = []
+    onosNode = int( onosNode )
+
+    macsDict = {}
+    ipDict = {}
+    if hostNames and devices:
+        if len( hostNames ) != len( devices ):
+            main.log.debug( "hosts and devices does not have the same length" )
+            #print "len hostNames = ", len( hostNames )
+            #print "len devices = ", len( devices )
+            return main.FALSE
+        if ports:
+            if len( ports ) != len( devices ):
+                main.log.error( "Ports and devices does " +
+                                "not have the same length" )
+                #print "len devices = ", len( devices )
+                #print "len ports = ", len( ports )
+                return main.FALSE
+        else:
+            main.log.info( "Device Ports are not specified" )
+        if macs:
+            for i in range( len( devices ) ):
+                macsDict[ devices[ i ] ] = macs[ i ]
+
+    elif hostNames and not devices and main.hostsData:
+        devices = []
+        main.log.info( "singleToMultiIntent function is using main.hostsData" )
+        for host in hostNames:
+               devices.append( main.hostsData.get( host ).get( 'location' ) )
+               macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
+                           main.hostsData.get( host ).get( 'mac' )
+               ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
+                           main.hostsData.get( host ).get( 'ipAddresses' )
+        #print main.hostsData
+
+    #print 'host names = ', hostNames
+    #print 'devices = ', devices
+    #print "macsDict = ", macsDict
+
+    pingResult = main.TRUE
+    intentResult = main.TRUE
+    removeIntentResult = main.TRUE
+    flowResult = main.TRUE
+    topoResult = main.TRUE
+    linkDownResult = main.TRUE
+    linkUpResult = main.TRUE
+
+    devicesCopy = copy.copy( devices )
+    if ports:
+        portsCopy = copy.copy( ports )
+    main.log.info( itemName + ": Adding single point to multi point intents" )
+
+    # Check flows count in each node
+    checkFlowsCount( main )
+
+    # Adding bidirectional point  intents
+    for i in range( len( devices ) ):
+        ingressDevice = devicesCopy[ i ]
+        egressDeviceList = copy.copy( devicesCopy )
+        egressDeviceList.remove( ingressDevice )
+        if ports:
+            portIngress = portsCopy[ i ]
+            portEgressList = copy.copy( portsCopy )
+            del portEgressList[ i ]
+        else:
+            portIngress = ""
+            portEgressList = None
+        if not macsDict:
+            srcMac = ""
+        else:
+            srcMac = macsDict[ ingressDevice ]
+            if srcMac == None:
+                main.log.debug( "There is no MAC in device - " + ingressDevice )
+                srcMac = ""
+
+        intentsId.append(
+                        main.CLIs[ onosNode ].addSinglepointToMultipointIntent(
+                                            ingressDevice=ingressDevice,
+                                            egressDeviceList=egressDeviceList,
+                                            portIngress=portIngress,
+                                            portEgressList=portEgressList,
+                                            ethType=ethType,
+                                            ethSrc=srcMac,
+                                            bandwidth=bandwidth,
+                                            lambdaAlloc=lambdaAlloc,
+                                            ipProto=ipProto,
+                                            ipSrc="",
+                                            ipDst="",
+                                            tcpSrc="",
+                                            tcpDst="" ) )
+
+    # Wait some time for the flow to go through when using multi instance
+    pingTemp = pingallHosts( main, hostNames )
+
+    # Check intents state
+    time.sleep( main.checkIntentSleep )
+    intentResult = checkIntentState( main, intentsId )
+
+    # Check intents state again if first check fails...
+    if not intentResult:
+        intentResult = checkIntentState( main, intentsId )
+
+    # Check flows count in each node
+    checkFlowsCount( main )
+    # Verify flows
+    checkFlowsState( main )
+
+    pingTemp = pingallHosts( main, hostNames )
+    pingResult = pingResult and pingTemp
+    if pingTemp:
+        main.assertReturnString += 'Initial Pingall Passed\n'
+    else:
+        main.assertReturnString += 'Initial Pingall Failed\n'
+
+    # Test rerouting if these variables exist
+    if sw1 and sw2 and expectedLink:
+        # link down
+        linkDownResult = link( main, sw1, sw2, "down" )
+
+        if linkDownResult:
+            main.assertReturnString += 'Link Down Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Failed\n'
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, expectedLink )
+        if topoResult:
+            main.assertReturnString += 'Link Down Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Topology State Failed\n'
+
+        # Ping hosts
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+        if pingTemp:
+            main.assertReturnString += 'Link Down Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Pingall Failed\n'
+
+        # Check intent state
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
+
+        # Checks ONOS state in link down
+        if linkDownResult and topoResult and pingResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link down" )
+        else:
+            main.log.error( itemName + ": Failed to bring link down" )
+
+        # link up
+        linkUpResult = link( main, sw1, sw2, "up" )
+        if linkUpResult:
+            main.assertReturnString += 'Link Up Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Failed\n'
+
+        time.sleep( main.rerouteSleep )
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, main.numLinks )
+        if topoResult:
+            main.assertReturnString += 'Link Up Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Topology State Failed\n'
+
+        # Ping hosts
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+        if pingTemp:
+            main.assertReturnString += 'Link Up Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Pingall Failed\n'
+
+        # Check Intents
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Up Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Intent State Failed\n'
+
+        # Checks ONOS state in link up
+        if linkUpResult and topoResult and pingResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link back up" )
+        else:
+            main.log.error( itemName + ": Failed to bring link back up" )
+
+    # Remove all intents
+    removeIntentResult = removeAllIntents( main, intentsId )
+    if removeIntentResult:
+        main.assertReturnString += 'Remove Intents Passed'
+    else:
+        main.assertReturnString += 'Remove Intents Failed'
+
+    stepResult = pingResult and linkDownResult and linkUpResult \
+                 and intentResult and removeIntentResult
+
+    return stepResult
+
+def multiToSingleIntent( main,
+                         name,
+                         hostNames,
+                         onosNode=0,
+                         devices="",
+                         ports=None,
+                         ethType="",
+                         macs=None,
+                         bandwidth="",
+                         lambdaAlloc=False,
+                         ipProto="",
+                         ipAddresses="",
+                         tcp="",
+                         sw1="",
+                         sw2="",
+                         expectedLink=0 ):
+    """
+    Verify Single to Multi Point intents
+    NOTE:If main.hostsData is not defined, variables data should be passed in the
+    same order index wise. All devices in the list should have the same
+    format, either all the devices have its port or it doesn't.
+    eg. hostName = [ 'h1', 'h2' ,..  ]
+        devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
+        ports = [ '1', '1', ..]
+        ...
+    Description:
+        Verify add-multi-to-single-intent
+    Steps:
+        - Get device ids | ports
+        - Add multi to single point intents
+        - Check intents
+        - Verify flows
+        - Ping hosts
+        - Reroute
+            - Link down
+            - Verify flows
+            - Check topology
+            - Ping hosts
+            - Link up
+            - Verify flows
+            - Check topology
+            - Ping hosts
+        - Remove intents
+    Required:
+        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
+        hostNames - List of host names
+    Optional:
+        onosNode - ONOS node to install the intents in main.CLIs[ ]
+                   0 by default so that it will always use the first
+                   ONOS node
+        devices - List of device ids in the same order as the hosts
+                  in hostNames
+        ports - List of port numbers in the same order as the device in
+                devices
+        ethType - Ethernet type eg. IPV4, IPV6
+        macs - List of hosts mac address in the same order as the hosts in
+               hostNames
+        bandwidth - Bandwidth capacity
+        lambdaAlloc - Allocate lambda, defaults to False
+        ipProto - IP protocol
+        ipAddresses - IP addresses of host in the same order as the hosts in
+                      hostNames
+        tcp - TCP ports in the same order as the hosts in hostNames
+        sw1 - First switch to bring down & up for rerouting purpose
+        sw2 - Second switch to bring down & up for rerouting purpose
+        expectedLink - Expected link when the switches are down, it should
+                       be two links lower than the links before the two
+                       switches are down
+    """
+
+    assert main, "There is no main variable"
+    assert hostNames, "You must specify hosts"
+    assert devices or main.hostsData, "You must specify devices"
+
+    global itemName
+    itemName = name
+    tempHostsData = {}
+    intentsId = []
+    onosNode = int( onosNode )
+
+    macsDict = {}
+    ipDict = {}
+    if hostNames and devices:
+        if len( hostNames ) != len( devices ):
+            main.log.debug( "hosts and devices does not have the same length" )
+            #print "len hostNames = ", len( hostNames )
+            #print "len devices = ", len( devices )
+            return main.FALSE
+        if ports:
+            if len( ports ) != len( devices ):
+                main.log.error( "Ports and devices does " +
+                                "not have the same length" )
+                #print "len devices = ", len( devices )
+                #print "len ports = ", len( ports )
+                return main.FALSE
+        else:
+            main.log.info( "Device Ports are not specified" )
+        if macs:
+            for i in range( len( devices ) ):
+                macsDict[ devices[ i ] ] = macs[ i ]
+    elif hostNames and not devices and main.hostsData:
+        devices = []
+        main.log.info( "multiToSingleIntent function is using main.hostsData" )
+        for host in hostNames:
+               devices.append( main.hostsData.get( host ).get( 'location' ) )
+               macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
+                           main.hostsData.get( host ).get( 'mac' )
+               ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
+                           main.hostsData.get( host ).get( 'ipAddresses' )
+        #print main.hostsData
+
+    #print 'host names = ', hostNames
+    #print 'devices = ', devices
+    #print "macsDict = ", macsDict
+
+    pingResult = main.TRUE
+    intentResult = main.TRUE
+    removeIntentResult = main.TRUE
+    flowResult = main.TRUE
+    topoResult = main.TRUE
+    linkDownResult = main.TRUE
+    linkUpResult = main.TRUE
+
+    devicesCopy = copy.copy( devices )
+    if ports:
+        portsCopy = copy.copy( ports )
+    main.log.info( itemName + ": Adding multi point to single point intents" )
+
+    # Check flows count in each node
+    checkFlowsCount( main )
+
+    # Adding bidirectional point  intents
+    for i in range( len( devices ) ):
+        egressDevice = devicesCopy[ i ]
+        ingressDeviceList = copy.copy( devicesCopy )
+        ingressDeviceList.remove( egressDevice )
+        if ports:
+            portEgress = portsCopy[ i ]
+            portIngressList = copy.copy( portsCopy )
+            del portIngressList[ i ]
+        else:
+            portEgress = ""
+            portIngressList = None
+        if not macsDict:
+            dstMac = ""
+        else:
+            dstMac = macsDict[ egressDevice ]
+            if dstMac == None:
+                main.log.debug( "There is no MAC in device - " + egressDevice )
+                dstMac = ""
+
+        intentsId.append(
+                        main.CLIs[ onosNode ].addMultipointToSinglepointIntent(
+                                            ingressDeviceList=ingressDeviceList,
+                                            egressDevice=egressDevice,
+                                            portIngressList=portIngressList,
+                                            portEgress=portEgress,
+                                            ethType=ethType,
+                                            ethDst=dstMac,
+                                            bandwidth=bandwidth,
+                                            lambdaAlloc=lambdaAlloc,
+                                            ipProto=ipProto,
+                                            ipSrc="",
+                                            ipDst="",
+                                            tcpSrc="",
+                                            tcpDst="" ) )
+
+    pingTemp = pingallHosts( main, hostNames )
+
+    # Check intents state
+    time.sleep( main.checkIntentSleep )
+    intentResult = checkIntentState( main, intentsId )
+
+    # Check intents state again if first check fails...
+    if not intentResult:
+        intentResult = checkIntentState( main, intentsId )
+
+    # Check flows count in each node
+    checkFlowsCount( main )
+    # Verify flows
+    checkFlowsState( main )
+
+    # Ping hosts
+    pingTemp = pingallHosts( main, hostNames )
+
+    # Ping hosts again...
+    pingTemp = pingallHosts( main, hostNames )
+    pingResult = pingResult and pingTemp
+    if pingTemp:
+        main.assertReturnString += 'Initial Pingall Passed\n'
+    else:
+        main.assertReturnString += 'Initial Pingall Failed\n'
+
+    # Test rerouting if these variables exist
+    if sw1 and sw2 and expectedLink:
+        # link down
+        linkDownResult = link( main, sw1, sw2, "down" )
+
+        if linkDownResult:
+            main.assertReturnString += 'Link Down Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Failed\n'
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, expectedLink )
+        if topoResult:
+            main.assertReturnString += 'Link Down Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Topology State Failed\n'
+
+        # Ping hosts
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+        if pingTemp:
+            main.assertReturnString += 'Link Down Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Pingall Failed\n'
+
+        # Check intent state
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
+
+        # Checks ONOS state in link down
+        if linkDownResult and topoResult and pingResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link down" )
+        else:
+            main.log.error( itemName + ": Failed to bring link down" )
+
+        # link up
+        linkUpResult = link( main, sw1, sw2, "up" )
+        if linkUpResult:
+            main.assertReturnString += 'Link Up Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Failed\n'
+
+        time.sleep( main.rerouteSleep )
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, main.numLinks )
+        if topoResult:
+            main.assertReturnString += 'Link Up Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Topology State Failed\n'
+
+        # Ping hosts
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+        if pingTemp:
+            main.assertReturnString += 'Link Up Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Pingall Failed\n'
+
+        # Check Intents
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Up Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Intent State Failed\n'
+
+        # Checks ONOS state in link up
+        if linkUpResult and topoResult and pingResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link back up" )
+        else:
+            main.log.error( itemName + ": Failed to bring link back up" )
+
+    # Remove all intents
+    removeIntentResult = removeAllIntents( main, intentsId )
+    if removeIntentResult:
+        main.assertReturnString += 'Remove Intents Passed'
+    else:
+        main.assertReturnString += 'Remove Intents Failed'
+
+    stepResult = pingResult and linkDownResult and linkUpResult \
+                 and intentResult and removeIntentResult
+
+    return stepResult
+
+def pingallHosts( main, hostList ):
+    # Ping all host in the hosts list variable
+    main.log.info( "Pinging: " + str( hostList ) )
+    return main.Mininet1.pingallHosts( hostList )
+
+def getHostsData( main ):
+    """
+        Use fwd app and pingall to discover all the hosts
+    """
+
+    activateResult = main.TRUE
+    appCheck = main.TRUE
+    getDataResult = main.TRUE
+    main.log.info( "Activating reactive forwarding app " )
+    activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
+    time.sleep( main.fwdSleep )
+
+    for i in range( main.numCtrls ):
+        appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
+        if appCheck != main.TRUE:
+            main.log.warn( main.CLIs[ i ].apps() )
+            main.log.warn( main.CLIs[ i ].appIDs() )
+
+    pingResult = main.Mininet1.pingall( timeout = 600 )
+    hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
+    hosts = main.Mininet1.getHosts().keys()
+    # TODO: Make better use of new getHosts function
+    for host in hosts:
+        main.hostsData[ host ] = {}
+        main.hostsData[ host ][ 'mac' ] =  \
+            main.Mininet1.getMacAddress( host ).upper()
+        for hostj in hostsJson:
+            if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
+                main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
+                main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
+                main.hostsData[ host ][ 'location' ] = \
+                            hostj[ 'location' ][ 'elementId' ] + '/' + \
+                            hostj[ 'location' ][ 'port' ]
+                main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
+
+    main.log.info( "Deactivating reactive forwarding app " )
+    deactivateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
+    if activateResult and deactivateResult and main.hostsData:
+        main.log.info( "Successfully used fwd app to discover hosts " )
+        getDataResult = main.TRUE
+    else:
+        main.log.info( "Failed to use fwd app to discover hosts " )
+        getDataResult = main.FALSE
+
+    print main.hostsData
+
+    return getDataResult
+
+def checkTopology( main, expectedLink ):
+    statusResult = main.TRUE
+    # Check onos topology
+    main.log.info( itemName + ": Checking ONOS topology " )
+
+    for i in range( main.numCtrls ):
+        topologyResult = main.CLIs[ i ].topology()
+        statusResult = main.ONOSbench.checkStatus( topologyResult,
+                                                   main.numSwitch,
+                                                   expectedLink )\
+                       and statusResult
+    if not statusResult:
+        main.log.error( itemName + ": Topology mismatch" )
+    else:
+        main.log.info( itemName + ": Topology match" )
+    return statusResult
+
+def checkIntentState( main, intentsId ):
+    """
+        This function will check intent state to make sure all the intents
+        are in INSTALLED state
+    """
+
+    intentResult = main.TRUE
+    results = []
+
+    main.log.info( itemName + ": Checking intents state" )
+    # First check of intents
+    for i in range( main.numCtrls ):
+        tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
+        results.append( tempResult )
+
+    expectedState = [ 'INSTALLED', 'INSTALLING' ]
+
+    if all( result == main.TRUE for result in results ):
+        main.log.info( itemName + ": Intents are installed correctly" )
+    else:
+        # Wait for at least 5 second before checking the intents again
+        time.sleep( 5 )
+        results = []
+        # Second check of intents since some of the intents may be in
+        # INSTALLING state, they should be in INSTALLED at this time
+        for i in range( main.numCtrls ):
+            tempResult = main.CLIs[ i ].checkIntentState(
+                                                        intentsId=intentsId )
+            results.append( tempResult )
+        if all( result == main.TRUE for result in results ):
+            main.log.info( itemName + ": Intents are installed correctly" )
+        else:
+            main.log.error( itemName + ": Intents are NOT installed correctly" )
+            intentResult = main.FALSE
+
+    return intentResult
+
+def checkFlowsState( main ):
+
+    main.log.info( itemName + ": Check flows state" )
+    checkFlowsResult = main.CLIs[ 0 ].checkFlowsState()
+    return checkFlowsResult
+
+def link( main, sw1, sw2, option):
+
+    # link down
+    main.log.info( itemName + ": Bring link " + option + "between " +
+                       sw1 + " and " + sw2 )
+    linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
+    return linkResult
+
+def removeAllIntents( main, intentsId ):
+    """
+        Remove all intents in the intentsId
+    """
+
+    onosSummary = []
+    removeIntentResult = main.TRUE
+    # Remove intents
+    for intent in intentsId:
+        main.CLIs[ 0 ].removeIntent( intentId=intent, purge=True )
+
+    time.sleep( main.removeIntentSleep )
+
+    # If there is remianing intents then remove intents should fail
+    for i in range( main.numCtrls ):
+        onosSummary.append( json.loads( main.CLIs[ i ].summary() ) )
+
+    for summary in onosSummary:
+        if summary.get( 'intents' ) != 0:
+            main.log.warn( itemName + ": There are " +
+                           str( summary.get( 'intents' ) ) +
+                           " intents remaining in node " +
+                           str( summary.get( 'node' ) ) +
+                           ", failed to remove all the intents " )
+            removeIntentResult = main.FALSE
+
+    if removeIntentResult:
+        main.log.info( itemName + ": There are no more intents remaining, " +
+                       "successfully removed all the intents." )
+
+    return removeIntentResult
+
+def checkFlowsCount( main ):
+    """
+        Check flows count in each node
+    """
+
+    flowsCount = []
+    main.log.info( itemName + ": Checking flows count in each ONOS node" )
+    for i in range( main.numCtrls ):
+        summaryResult = main.CLIs[ i ].summary()
+        if not summaryResult:
+            main.log.error( itemName + ": There is something wrong with " +
+                            "summary command" )
+            return main.FALSE
+        else:
+            summaryJson = json.loads( summaryResult )
+            flowsCount.append( summaryJson.get( 'flows' ) )
+
+    if flowsCount:
+        if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
+            main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
+                           " flows in all ONOS node" )
+        else:
+            for i in range( main.numCtrls ):
+                main.log.debug( itemName + ": ONOS node " + str( i ) + " has " +
+                                str( flowsCount[ i ] ) + " flows" )
+    else:
+        main.log.error( "Checking flows count failed, check summary command" )
+        return main.FALSE
+
+    return main.TRUE
+
+def checkLeaderChange( leaders1, leaders2 ):
+    """
+        Checks for a change in intent partition leadership.
+
+        Takes the output of leaders -c in json string format before and after
+        a potential change as input
+
+        Returns main.TRUE if no mismatches are detected
+        Returns main.FALSE if there is a mismatch or on error loading the input
+    """
+    try:
+        leaders1 = json.loads( leaders1 )
+        leaders2 = json.loads( leaders2 )
+    except ( AttributeError, TypeError):
+        main.log.exception( self.name + ": Object not as expected" )
+        return main.FALSE
+    except Exception:
+        main.log.exception( self.name + ": Uncaught exception!" )
+        main.cleanup()
+        main.exit()
+    main.log.info( "Checking Intent Paritions for Change in Leadership" )
+    mismatch = False
+    for dict1 in leaders1:
+        if "intent" in dict1.get( "topic", [] ):
+            for dict2 in leaders2:
+                if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
+                    dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
+                    mismatch = True
+                    main.log.error( "{0} changed leader from {1} to {2}".\
+                        format( dict1.get( "topic", "no-topic" ),\
+                            dict1.get( "leader", "no-leader" ),\
+                            dict2.get( "leader", "no-leader" ) ) )
+    if mismatch:
+        return main.FALSE
+    else:
+        return main.TRUE
+
+def report( main ):
+    """
+    Report errors/warnings/exceptions
+    """
+
+    main.ONOSbench.logReport( main.ONOSip[ 0 ],
+                              [ "INFO",
+                                "FOLLOWER",
+                                "WARN",
+                                "flow",
+                                "ERROR",
+                                "Except" ],
+                              "s" )
+
+    main.log.info( "ERROR report: \n" )
+    for i in range( main.numCtrls ):
+        main.ONOSbench.logReport( main.ONOSip[ i ],
+                [ "ERROR" ],
+                "d" )
+
+    main.log.info( "EXCEPTIONS report: \n" )
+    for i in range( main.numCtrls ):
+        main.ONOSbench.logReport( main.ONOSip[ i ],
+                [ "Except" ],
+                "d" )
+
+    main.log.info( "WARNING report: \n" )
+    for i in range( main.numCtrls ):
+        main.ONOSbench.logReport( main.ONOSip[ i ],
+                [ "WARN" ],
+                "d" )
diff --git a/TestON/tests/FUNCoptical/Dependency/startUp.py b/TestON/tests/FUNCoptical/Dependency/startUp.py
new file mode 100644
index 0000000..bf2a2b6
--- /dev/null
+++ b/TestON/tests/FUNCoptical/Dependency/startUp.py
@@ -0,0 +1,38 @@
+"""
+    This wrapper function is use for starting up onos instance
+"""
+
+import time
+import os
+import json
+
+def onosBuild( main, gitBranch ):
+    """
+        This includes pulling ONOS and building it using maven install
+    """
+
+    buildResult = main.FALSE
+
+    # Git checkout a branch of ONOS
+    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
+    # Does the git pull on the branch that was checked out
+    if not checkOutResult:
+        main.log.warn( "Failed to checked out " + gitBranch +
+                                           " branch")
+    else:
+        main.log.info( "Successfully checked out " + gitBranch +
+                                           " branch")
+    gitPullResult = main.ONOSbench.gitPull()
+    if gitPullResult == main.ERROR:
+        main.log.error( "Error pulling git branch" )
+    else:
+        main.log.info( "Successfully pulled " + gitBranch + " branch" )
+
+    # Maven clean install
+    buildResult = main.ONOSbench.cleanInstall()
+
+    return buildResult
+
+
+
+
diff --git a/TestON/tests/FUNCoptical/Dependency/topo.py b/TestON/tests/FUNCoptical/Dependency/topo.py
new file mode 100644
index 0000000..b44e3fc
--- /dev/null
+++ b/TestON/tests/FUNCoptical/Dependency/topo.py
@@ -0,0 +1,100 @@
+"""
+    These functions can be used for topology comparisons
+"""
+
+import time
+import os
+import json
+
+def getAllDevices( main ):
+    """
+        Return a list containing the devices output from each ONOS node
+    """
+    devices = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].devices,
+                         name="devices-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        devices.append( t.result )
+    return devices
+
+def getAllHosts( main ):
+    """
+        Return a list containing the hosts output from each ONOS node
+    """
+    hosts = []
+    ipResult = main.TRUE
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].hosts,
+                         name="hosts-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        hosts.append( t.result )
+    return hosts
+
+def getAllPorts( main ):
+    """
+        Return a list containing the ports output from each ONOS node
+    """
+    ports = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].ports,
+                         name="ports-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        ports.append( t.result )
+    return ports
+
+def getAllLinks( main ):
+    """
+        Return a list containing the links output from each ONOS node
+    """
+    links = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].links,
+                         name="links-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        links.append( t.result )
+    return links
+
+def getAllClusters( main ):
+    """
+        Return a list containing the clusters output from each ONOS node
+    """
+    clusters = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].clusters,
+                         name="clusters-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        clusters.append( t.result )
+    return clusters
+
+
diff --git a/TestON/tests/FUNCoptical/FUNCoptical.params b/TestON/tests/FUNCoptical/FUNCoptical.params
new file mode 100644
index 0000000..2d8df50
--- /dev/null
+++ b/TestON/tests/FUNCoptical/FUNCoptical.params
@@ -0,0 +1,56 @@
+<PARAMS>
+    # CASE - Description
+    # 1 - Variable initialization and optional pull and build ONOS package
+    # 2 - Install ONOS
+    # 10 - Start Mininet opticalTest Topology
+    # 14 - Stop Mininet
+    # 21 - Run pingall to discover all hosts
+    # 22 - Send arpings to discover all hosts
+    # 23 - Compare ONOS Topology to Mininet Topology
+    # 31 - Add and test bidirectional point intents
+    # 32 - Add and test bidirectional host intents
+
+    <testcases>1,2,10,21,22,23,31,32,14,2,10,21,22,23,31,32,14</testcases>
+
+    <SCALE>
+        <size>1,3</size>
+    </SCALE>
+
+    <DEPENDENCY>
+        <path>/tests/FUNCoptical/Dependency/</path>
+        <wrapper1>startUp</wrapper1>
+        <wrapper2>FuncIntentFunction</wrapper2>
+        <wrapper3>topo</wrapper3>
+    </DEPENDENCY>
+
+    <ENV>
+        <cellApps>drivers,openflow,proxyarp,mobility,optical,fwd</cellApps>
+    </ENV>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
+
+    <SLEEP>
+        <startup>15</startup>
+        <reroute>5</reroute>
+        <removeintent>10</removeintent>
+        <checkintent>5</checkintent>
+        <fwd>10</fwd>
+        <topoAttempts>3</topoAttempts>
+    </SLEEP>
+
+    <MININET>
+        <switch>7</switch>
+        <links>20</links>
+    </MININET>
+
+    # Intent tests params
+    <SDNIP>
+        <tcpProto>6</tcpProto>
+        <icmpProto>1</icmpProto>
+        <srcPort>5001</srcPort>
+        <dstPort>5001</dstPort>
+    </SDNIP>
+
+</PARAMS>
diff --git a/TestON/tests/FUNCoptical/FUNCoptical.py b/TestON/tests/FUNCoptical/FUNCoptical.py
new file mode 100644
index 0000000..b5ca189
--- /dev/null
+++ b/TestON/tests/FUNCoptical/FUNCoptical.py
@@ -0,0 +1,600 @@
+# Testing the basic intent functionality of ONOS
+
+class FUNCoptical:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        import time
+        import imp
+        import re
+
+        """
+        - Construct tests variables
+        - GIT ( optional )
+            - Checkout ONOS master branch
+            - Pull latest ONOS code
+        - Building ONOS ( optional )
+            - Install ONOS package
+            - Build ONOS package
+        """
+
+        main.case( "Constructing test variables and building ONOS package" )
+        main.step( "Constructing test variables" )
+        main.caseExplanation = "This test case is mainly for loading " +\
+                               "from params file, and pull and build the " +\
+                               " latest ONOS package"
+        stepResult = main.FALSE
+
+        # Test variables
+        try:
+            main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            gitBranch = main.params[ 'GIT' ][ 'branch' ]
+            main.dependencyPath = main.testOnDirectory + \
+                                  main.params[ 'DEPENDENCY' ][ 'path' ]
+            main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
+            if main.ONOSbench.maxNodes:
+                main.maxNodes = int( main.ONOSbench.maxNodes )
+            else:
+                main.maxNodes = 0
+            wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+            wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+            wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.checkIntentSleep = int( main.params[ 'SLEEP' ][ 'checkintent' ] )
+            main.removeIntentSleep = int( main.params[ 'SLEEP' ][ 'removeintent' ] )
+            main.rerouteSleep = int( main.params[ 'SLEEP' ][ 'reroute' ] )
+            main.fwdSleep = int( main.params[ 'SLEEP' ][ 'fwd' ] )
+            main.checkTopoAttempts = int( main.params[ 'SLEEP' ][ 'topoAttempts' ] )
+            gitPull = main.params[ 'GIT' ][ 'pull' ]
+            main.numSwitch = int( main.params[ 'MININET' ][ 'switch' ] )
+            main.numLinks = int( main.params[ 'MININET' ][ 'links' ] )
+            main.cellData = {} # For creating cell file
+            main.hostsData = {}
+            main.CLIs = []
+            main.ONOSip = []  # List of IPs of active ONOS nodes. CASE 2
+            main.activeONOSip = []
+            main.assertReturnString = ''  # Assembled assert return string
+
+            main.ONOSip = main.ONOSbench.getOnosIps()
+
+            # Assigning ONOS cli handles to a list
+            for i in range( 1,  main.maxNodes + 1 ):
+                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+
+            # -- INIT SECTION, ONLY RUNS ONCE -- #
+            main.startUp = imp.load_source( wrapperFile1,
+                                            main.dependencyPath +
+                                            wrapperFile1 +
+                                            ".py" )
+
+            main.intentFunction = imp.load_source( wrapperFile2,
+                                            main.dependencyPath +
+                                            wrapperFile2 +
+                                            ".py" )
+
+            main.topo = imp.load_source( wrapperFile3,
+                                         main.dependencyPath +
+                                         wrapperFile3 +
+                                         ".py" )
+
+            if main.CLIs:
+                stepResult = main.TRUE
+            else:
+                main.log.error( "Did not properly created list of ONOS CLI handle" )
+                stepResult = main.FALSE
+        except Exception as e:
+            main.log.exception(e)
+            main.cleanup()
+            main.exit()
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully construct " +
+                                        "test variables ",
+                                 onfail="Failed to construct test variables" )
+
+        if gitPull == 'True':
+            main.step( "Building ONOS in " + gitBranch + " branch" )
+            onosBuildResult = main.startUp.onosBuild( main, gitBranch )
+            stepResult = onosBuildResult
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=stepResult,
+                                     onpass="Successfully compiled " +
+                                            "latest ONOS",
+                                     onfail="Failed to compile " +
+                                            "latest ONOS" )
+        else:
+            main.log.warn( "Did not pull new code so skipping mvn " +
+                           "clean install" )
+        main.ONOSbench.getVersion( report=True )
+
+    def CASE2( self, main ):
+        """
+        - Set up cell
+            - Create cell file
+            - Set cell file
+            - Verify cell file
+        - Kill ONOS process
+        - Uninstall ONOS cluster
+        - Verify ONOS start up
+        - Install ONOS cluster
+        - Connect to cli
+        """
+
+        # main.scale[ 0 ] determines the current number of ONOS controller
+        main.numCtrls = int( main.scale[ 0 ] )
+
+        main.case( "Starting up " + str( main.numCtrls ) +
+                   " node(s) ONOS cluster" )
+        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
+                                " node(s) ONOS cluster"
+
+
+
+        #kill off all onos processes
+        main.log.info( "Safety check, killing all ONOS processes" +
+                       " before initiating enviornment setup" )
+
+        for i in range( main.maxNodes ):
+            main.ONOSbench.onosDie( main.ONOSip[ i ] )
+
+        print "NODE COUNT = ", main.numCtrls
+
+        tempOnosIp = []
+        for i in range( main.numCtrls ):
+            tempOnosIp.append( main.ONOSip[i] )
+
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+                                       "temp", main.Mininet1.ip_address,
+                                       main.apps, tempOnosIp )
+
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( "temp" )
+        verifyResult = main.ONOSbench.verifyCell()
+        stepResult = cellResult and verifyResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully applied cell to " + \
+                                        "environment",
+                                 onfail="Failed to apply cell to environment " )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()
+        stepResult = packageResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully created ONOS package",
+                                 onfail="Failed to create ONOS package" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Uninstalling ONOS package" )
+        onosUninstallResult = main.TRUE
+        for ip in main.ONOSip:
+            onosUninstallResult = onosUninstallResult and \
+                    main.ONOSbench.onosUninstall( nodeIp=ip )
+        stepResult = onosUninstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully uninstalled ONOS package",
+                                 onfail="Failed to uninstall ONOS package" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Installing ONOS package" )
+        onosInstallResult = main.TRUE
+        for i in range( main.numCtrls ):
+            onosInstallResult = onosInstallResult and \
+                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
+            # Populate activeONOSip
+            main.activeONOSip.append( main.ONOSip[ i ] )
+        stepResult = onosInstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully installed ONOS package",
+                                 onfail="Failed to install ONOS package" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Starting ONOS service" )
+        stopResult = main.TRUE
+        startResult = main.TRUE
+        onosIsUp = main.TRUE
+
+        for i in range( main.numCtrls ):
+            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
+        if onosIsUp == main.TRUE:
+            main.log.report( "ONOS instance is up and ready" )
+        else:
+            main.log.report( "ONOS instance may not be up, stop and " +
+                             "start ONOS again " )
+
+            for i in range( main.numCtrls ):
+                stopResult = stopResult and \
+                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
+            for i in range( main.numCtrls ):
+                startResult = startResult and \
+                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
+        stepResult = onosIsUp and stopResult and startResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="ONOS service is ready",
+                                 onfail="ONOS service did not start properly" )
+
+        main.step( "Start ONOS cli" )
+        cliResult = main.TRUE
+        for i in range( main.numCtrls ):
+            cliResult = cliResult and \
+                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
+        stepResult = cliResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully start ONOS cli",
+                                 onfail="Failed to start ONOS cli" )
+
+        # Remove the first element in main.scale list
+        main.scale.remove( main.scale[ 0 ] )
+
+        main.intentFunction.report( main )
+
+
+    def CASE10( self, main ):
+        """
+            Start Mininet opticalTest Topology
+        """
+        main.case( "Mininet with Linc-OE startup")
+        main.caseExplanation = "Start opticalTest.py topology included with ONOS"
+        main.step( "Starting mininet and LINC-OE" )
+        topoResult = main.TRUE
+        time.sleep( 10 )
+        controllerIPs = ' '.join( main.activeONOSip )
+        opticalMnScript = main.LincOE.runOpticalMnScript(ctrllerIP = controllerIPs)
+        topoResult = opticalMnScript
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=topoResult,
+            onpass="Started the topology successfully ",
+            onfail="Failed to start the topology")
+
+        # Exit if topology did not load properly
+        if not topoResult:
+            main.cleanup()
+            main.exit()
+
+    
+
+
+    def CASE14( self, main ):
+        """
+            Stop mininet
+        """
+        main.log.report( "Stop Mininet topology" )
+        main.case( "Stop Mininet topology" )
+        main.caseExplanation = "Stopping the current mininet topology " +\
+                                "to start up fresh"
+
+        main.step( "Stopping Mininet Topology" )
+        topoResult = main.LincOE.stopNet( timeout=180 )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=topoResult,
+                                 onpass="Successfully stopped mininet",
+                                 onfail="Failed to stopped mininet" )
+        # Exit if topology did not load properly
+        if not topoResult:
+            main.cleanup()
+            main.exit()
+
+    def CASE21( self,main ):
+        """
+            Run pingall to discover all hosts
+        """
+        main.case( "Running Pingall" )
+        main.caseExplanation = "Use pingall to discover all hosts. Pingall is expected to fail."
+        main.step( "Discover Hosts through Pingall" )
+        pingResult = main.LincOE.pingall( timeout = 600 )
+
+        utilities.assert_equals( expect=main.FALSE,
+                                 actual=pingResult,
+                                 onpass="Pingall Completed",
+                                 onfail="Pingall did not complete or did not return fales" )
+
+    def CASE22( self,main ):
+        """
+            Send arpings to discover all hosts
+        """
+        main.case( "Discover Hosts with arping" )
+        main.caseExplanation = "Send arpings between all the hosts to discover and verify them"
+
+        main.step( "Send arping between all hosts" )
+
+        hosts = [ "h1","h2","h3","h4","h5","h6" ]
+
+        arpingHostResults = main.TRUE
+        for host in hosts:
+            if main.LincOE.arping( host ):
+                main.log.info( "Successfully reached host {} with arping".format( host ) )
+            else:
+                main.log.error( "Could not reach host {} with arping".format( host ) )
+                arpingHostResults = main.FALSE
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=arpingHostResults,
+                                 onpass="Successfully discovered all hosts",
+                                 onfail="Could not descover some hosts" )
+
+    def CASE23( self, main ):
+        """
+        Compare ONOS Topology to Mininet Topology
+        """
+        import json
+
+        main.case( "Compare ONOS Topology view to Mininet topology" )
+        main.caseExplanation = "Compare topology elements between Mininet" +\
+                                " and ONOS"
+
+        main.log.info( "Gathering topology information from Mininet" )
+        devicesResults = main.FALSE  # Overall Boolean for device correctness
+        linksResults = main.FALSE  # Overall Boolean for link correctness
+        hostsResults = main.FALSE  # Overall Boolean for host correctness
+        deviceFails = []  # Nodes where devices are incorrect
+        linkFails = []  # Nodes where links are incorrect
+        hostFails = []  # Nodes where hosts are incorrect
+        attempts = main.checkTopoAttempts  # Remaining Attempts
+
+        mnSwitches = 16
+        mnLinks = 46
+        mnHosts = 6
+
+        main.step( "Conmparing Mininet topology to ONOS topology" )
+
+        while ( attempts >= 0 ) and\
+            ( not devicesResults or not linksResults or not hostsResults ):
+            time.sleep( 2 )
+            if not devicesResults:
+                devices = main.topo.getAllDevices( main )
+                ports = main.topo.getAllPorts( main )
+                devicesResults = main.TRUE
+                deviceFails = []  # Reset for each attempt
+            if not linksResults:
+                links = main.topo.getAllLinks( main )
+                linksResults = main.TRUE
+                linkFails = []  # Reset for each attempt
+            if not hostsResults:
+                hosts = main.topo.getAllHosts( main )
+                hostsResults = main.TRUE
+                hostFails = []  # Reset for each attempt
+
+            #  Check for matching topology on each node
+            for controller in range( main.numCtrls ):
+                controllerStr = str( controller + 1 )  # ONOS node number
+                # Compare Devices
+                if devices[ controller ] and ports[ controller ] and\
+                    "Error" not in devices[ controller ] and\
+                    "Error" not in ports[ controller ]:
+
+                    try:
+                        deviceData = json.loads( devices[ controller ] )
+                        portData = json.loads( ports[ controller ] )
+                    except (TypeError,ValueError):
+                        main.log.error("Could not load json:" + str( devices[ controller ] ) + ' or ' + str( ports[ controller ] ))
+                        currentDevicesResult = main.FALSE
+                    else:
+                        if mnSwitches == len( deviceData ):
+                            currentDevicesResult = main.TRUE
+                        else:
+                            currentDevicesResult = main.FALSE
+                            main.log.error( "Node {} only sees {} device(s) but {} exist".format( 
+                                controllerStr,len( deviceData ),mnSwitches ) )
+                else:
+                    currentDevicesResult = main.FALSE
+                if not currentDevicesResult:
+                    deviceFails.append( controllerStr )
+                devicesResults = devicesResults and currentDevicesResult
+                # Compare Links
+                if links[ controller ] and "Error" not in links[ controller ]:
+                    try:
+                        linkData = json.loads( links[ controller ] )
+                    except (TypeError,ValueError):
+                        main.log.error("Could not load json:" + str( links[ controller ] ) )
+                        currentLinksResult = main.FALSE
+                    else:
+                        if mnLinks == len( linkData ):
+                            currentLinksResult = main.TRUE
+                        else:
+                            currentLinksResult = main.FALSE
+                            main.log.error( "Node {} only sees {} link(s) but {} exist".format( 
+                                controllerStr,len( linkData ),mnLinks ) )
+                else:
+                    currentLinksResult = main.FALSE
+                if not currentLinksResult:
+                    linkFails.append( controllerStr )
+                linksResults = linksResults and currentLinksResult
+                # Compare Hosts
+                if hosts[ controller ] and "Error" not in hosts[ controller ]:
+                    try:
+                        hostData = json.loads( hosts[ controller ] )
+                    except (TypeError,ValueError):
+                        main.log.error("Could not load json:" + str( hosts[ controller ] ) )
+                        currentHostsResult = main.FALSE
+                    else:
+                        if mnHosts == len( hostData ):
+                            currentHostsResult = main.TRUE
+                        else:
+                            currentHostsResult = main.FALSE
+                            main.log.error( "Node {} only sees {} host(s) but {} exist".format( 
+                                controllerStr,len( hostData ),mnHosts ) )
+                else:
+                    currentHostsResult = main.FALSE
+                if not currentHostsResult:
+                    hostFails.append( controllerStr )
+                hostsResults = hostsResults and currentHostsResult
+            # Decrement Attempts Remaining
+            attempts -= 1
+
+        utilities.assert_equals( expect=[],
+                                 actual=deviceFails,
+                                 onpass="ONOS correctly discovered all devices",
+                                 onfail="ONOS incorrectly discovered devices on nodes: " +
+                                 str( deviceFails ) )
+        utilities.assert_equals( expect=[],
+                                 actual=linkFails,
+                                 onpass="ONOS correctly discovered all links",
+                                 onfail="ONOS incorrectly discovered links on nodes: " +
+                                 str( linkFails ) )
+        utilities.assert_equals( expect=[],
+                                 actual=hostFails,
+                                 onpass="ONOS correctly discovered all hosts",
+                                 onfail="ONOS incorrectly discovered hosts on nodes: " +
+                                 str( hostFails ) )
+        if hostsResults and linksResults and devicesResults:
+            topoResults = main.TRUE
+        else:
+            topoResults = main.FALSE
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=topoResults,
+                                 onpass="ONOS correctly discovered the topology",
+                                 onfail="ONOS incorrectly discovered the topology" )
+
+
+    def CASE31( self, main ):
+        import time
+        """
+            Add bidirectional point intents between 2 packet layer( mininet )
+            devices and ping mininet hosts
+        """
+        main.log.report(
+            "This testcase adds bidirectional point intents between 2 " +
+            "packet layer( mininet ) devices and ping mininet hosts" )
+        main.case( "Install point intents between 2 packet layer device and " +
+                   "ping the hosts" )
+        main.caseExplanation = "This testcase adds bidirectional point intents between 2 " +\
+            "packet layer( mininet ) devices and ping mininet hosts"
+
+        main.step( "Adding point intents" )
+        checkFlowResult = main.TRUE
+        main.pIntentsId = []
+        pIntent1 = main.CLIs[ 0 ].addPointIntent(
+            "of:0000ffffffff0001/1",
+            "of:0000ffffffff0005/1" )
+        time.sleep( 10 )
+        pIntent2 = main.CLIs[ 0 ].addPointIntent(
+            "of:0000ffffffff0005/1",
+            "of:0000ffffffff0001/1" )
+        main.pIntentsId.append( pIntent1 )
+        main.pIntentsId.append( pIntent2 )
+        time.sleep( 10 )
+        main.log.info( "Checking intents state")
+        checkStateResult = main.CLIs[ 0 ].checkIntentState(
+                                                  intentsId = main.pIntentsId )
+        time.sleep( 10 )
+        main.log.info( "Checking flows state")
+        checkFlowResult = main.CLIs[ 0 ].checkFlowsState()
+        # Sleep for 10 seconds to provide time for the intent state to change
+        time.sleep( 10 )
+        main.log.info( "Checking intents state one more time")
+        checkStateResult = main.CLIs[ 0 ].checkIntentState(
+                                                  intentsId = main.pIntentsId )
+        
+        if checkStateResult and checkFlowResult:
+            addIntentsResult = main.TRUE
+        else:
+            addIntentsResult = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=addIntentsResult,
+            onpass="Successfully added point intents",
+            onfail="Failed to add point intents")
+
+        if not addIntentsResult:
+            main.log.error( "Intents were not properly installed. Exiting case." )
+            main.skipCase()
+
+        main.step( "Ping h1 and h5" )
+        pingResult = main.LincOE.pingHostOptical( src="h1", target="h5" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=pingResult,
+            onpass="Successfully pinged h1 and h5",
+            onfail="Failed to ping between h1 and h5")
+
+    def CASE32( self ):
+        """
+            Add host intents between 2 packet layer host
+        """
+        import time
+        import json
+        main.log.report( "Adding host intents between 2 optical layer host" )
+        main.case( "Test add host intents between optical layer host" )
+        main.caseExplanation = "Test host intents between 2 optical layer host"
+
+        main.step( "Adding host intents to h1 and h2" )
+        hostMACs = []
+        hostId = []
+        # Listing host MAC addresses
+        for i in range( 1 , 7 ):
+            hostMACs.append( "00:00:00:00:00:" +
+                                str( hex( i )[ 2: ] ).zfill( 2 ).upper() )
+        for macs in hostMACs:
+            hostId.append( macs + "/-1" )
+        host1 = hostId[ 0 ]
+        host2 = hostId[ 1 ]
+
+        intentsId = []
+        intent1 = main.CLIs[ 0 ].addHostIntent( hostIdOne = host1,
+                                            hostIdTwo = host2 )
+        intentsId.append( intent1 )
+        # Checking intents state before pinging
+        main.log.info( "Checking intents state" )
+        intentResult = main.CLIs[ 0 ].checkIntentState( intentsId = intentsId )
+        # Check intent state again if intents are not in installed state
+        
+
+        # If intent state is wrong, wait 3 sec and try again
+        if not intentResult:
+            time.sleep( 3 )
+            intentResult = main.CLIs[ 0 ].checkIntentState( intentsId = intentsId )
+
+        # If intent state is still wrong, display intent states
+        if not intentResult:
+            main.log.error( main.CLIs[ 0 ].intents() )
+        
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=intentResult,
+                                 onpass="All intents are in INSTALLED state ",
+                                 onfail="Some of the intents are not in " +
+                                        "INSTALLED state " )
+
+        if not intentResult:
+            main.log.error( "Intents were not properly installed. Skipping Ping" )
+        else:
+            # Pinging h1 to h2 and then ping h2 to h1
+            main.step( "Pinging h1 and h2" )
+            pingResult = main.TRUE
+            pingResult = main.LincOE.pingHostOptical( src="h1", target="h2" ) \
+                and main.LincOE.pingHostOptical( src="h2",target="h1" )
+            
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=pingResult,
+                                     onpass="Pinged successfully between h1 and h2",
+                                     onfail="Pinged failed between h1 and h2" )
+
+        # Removed all added host intents
+        main.step( "Removing host intents" )
+        removeResult = main.TRUE
+        # Check remaining intents
+        intentsJson = json.loads( main.CLIs[ 0 ].intents() )
+        main.CLIs[ 0 ].removeIntent( intentId=intent1, purge=True )
+        #main.CLIs[ 0 ].removeIntent( intentId=intent2, purge=True )
+        for intents in intentsJson:
+            main.CLIs[ 0 ].removeIntent( intentId=intents.get( 'id' ),
+                                     app='org.onosproject.optical',
+                                     purge=True )
+        # Check if any intents could not be removed
+        if len( json.loads( main.CLIs[ 0 ].intents() ) ):
+            print json.loads( main.CLIs[ 0 ].intents() )
+            removeResult = main.FALSE
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=removeResult,
+                                 onpass="Successfully removed host intents",
+                                 onfail="Failed to remove host intents" )
+
diff --git a/TestON/tests/FUNCoptical/FUNCoptical.topo b/TestON/tests/FUNCoptical/FUNCoptical.topo
new file mode 100755
index 0000000..73859bd
--- /dev/null
+++ b/TestON/tests/FUNCoptical/FUNCoptical.topo
@@ -0,0 +1,64 @@
+<TOPOLOGY>
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>admin</user>
+            <password></password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <nodes>3</nodes>
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOScli1>
+            <host>localhost</host>
+            <user>admin</user>
+            <password></password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli1>
+
+        <ONOScli2>
+            <host>localhost</host>
+            <user>admin</user>
+            <password></password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli2>
+
+         <ONOScli3>
+            <host>localhost</host>
+            <user>admin</user>
+            <password></password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli3>
+
+        <Mininet1>
+            <host>OCN</host>
+            <user>admin</user>
+            <password></password>
+            <type>MininetCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS>
+                <home>~/mininet/custom/</home>
+            </COMPONENTS>
+        </Mininet1>
+
+        <LincOE>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>rocks</password>
+            <type>LincOEMininetDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </LincOE>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/FUNCoptical/TopoConfig.json b/TestON/tests/FUNCoptical/TopoConfig.json
new file mode 100644
index 0000000..9545eae
--- /dev/null
+++ b/TestON/tests/FUNCoptical/TopoConfig.json
@@ -0,0 +1,2832 @@
+{
+    "linkConfig": [
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 100,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:12",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:15",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 100,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:12",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:13",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:15",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1e",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 100,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:10",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:42",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:04",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:08",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:04",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0c",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:04",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1a",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:0b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:0b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:0b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:0b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:0b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:4b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:19",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:4b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:39",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:05",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0e",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 104,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:05",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:35",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:06",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:09",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:06",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:13",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:06",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3f",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2e",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:30",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:46",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:08",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:26",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:08",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:27",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:09",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:24",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0a",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:19",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0a",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:27",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:14",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:22",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3e",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0c",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:17",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0d",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1a",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0d",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:34",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0e",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0f",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 101,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0e",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:46",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:0f",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:30",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:10",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:31",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:11",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0f",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:11",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1f",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:11",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:48",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:12",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:19",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:12",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:20",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:12",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2a",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:0a",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:12",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:0a",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:12",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:0a",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:12",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:0a",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:12",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:0a",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:12",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:13",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2c",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:13",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:38",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:14",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:46",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:15",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:39",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:15",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:44",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:16",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1d",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:16",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1f",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 108,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:16",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2a",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 108,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:17",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1f",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:17",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:33",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:17",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:34",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 108,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:18",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1c",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:18",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:31",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1a",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2d",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2c",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:40",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:47",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1c",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:29",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1d",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3a",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1d",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3b",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:09",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:09",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:09",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:09",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:09",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:1d",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1e",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2f",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1e",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:38",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 104,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1f",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:26",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 108,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:1f",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:40",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:20",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:23",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:21",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:43",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:21",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:4a",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:22",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:24",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:23",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:26",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:24",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2c",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:08",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:24",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:08",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:24",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:08",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:24",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:08",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:24",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:08",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:24",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:25",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:34",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:25",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:49",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:27",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:45",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:28",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2e",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:07",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:28",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:07",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:28",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:07",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:28",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:07",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:28",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:07",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:28",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:29",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:28",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:29",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:37",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:29",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:49",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:2a",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:47",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:2b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:36",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:2b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:38",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:2b",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3c",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:2d",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:4a",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:06",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:06",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:06",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:06",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:06",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2d",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:2e",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:37",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:2f",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3b",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:2f",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:44",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:05",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2f",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:05",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2f",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:05",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2f",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:05",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2f",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:05",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:2f",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:30",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:37",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:32",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:36",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 108,
+                "numWaves": 80,
+                "port1": 102,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:32",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:38",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 103,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:32",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:41",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:33",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:48",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:35",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:42",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:04",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:35",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:04",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:35",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:04",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:35",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:04",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:35",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:04",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:35",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:37",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:42",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:03",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:39",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:03",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:39",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:03",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:39",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:03",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:39",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:03",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:39",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 105,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:3c",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3d",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:3d",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3a",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:02",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:02",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:02",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:02",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3d",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:02",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3d",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:3e",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:40",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 107,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:41",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:3f",
+            "allowed": true
+        },
+        {
+            "type": "wdmLink",
+            "params": {
+                "port2": 106,
+                "numWaves": 80,
+                "port1": 101,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:ff:ff:45",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:43",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 10,
+                "bandwidth": 100000,
+                "port1": 2,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:01",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:48",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 11,
+                "bandwidth": 100000,
+                "port1": 3,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:01",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:48",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 12,
+                "bandwidth": 100000,
+                "port1": 4,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:01",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:48",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 13,
+                "bandwidth": 100000,
+                "port1": 5,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:01",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:48",
+            "allowed": true
+        },
+        {
+            "type": "pktOptLink",
+            "params": {
+                "port2": 14,
+                "bandwidth": 100000,
+                "port1": 6,
+                "nodeName2": "none",
+                "nodeName1": "none"
+            },
+            "nodeDpid1": "00:00:ff:ff:ff:00:00:01",
+            "nodeDpid2": "00:00:ff:ff:ff:ff:ff:48",
+            "allowed": true
+        }
+    ],
+    "switchConfig": [
+        {
+            "name": "none",
+            "longitude": -99.741564,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 32.508086,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:01"
+        },
+        {
+            "name": "none",
+            "longitude": -106.649719,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 35.084446,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:02"
+        },
+        {
+            "name": "none",
+            "longitude": -73.758333,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 42.652222,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:03"
+        },
+        {
+            "name": "none",
+            "longitude": -97.743057,
+            "params": {
+                "numregens": 5
+            },
+            "allowed": true,
+            "latitude": 33.755833,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:04"
+        },
+        {
+            "name": "none",
+            "longitude": -96.7,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 29.57,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:4b"
+        },
+        {
+            "name": "none",
+            "longitude": -78.877778,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 42.882778,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:05"
+        },
+        {
+            "name": "none",
+            "longitude": -108.509167,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 45.781667,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:06"
+        },
+        {
+            "name": "none",
+            "longitude": -76.614127,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 39.293781,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:07"
+        },
+        {
+            "name": "none",
+            "longitude": -86.812225,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 33.517223,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:08"
+        },
+        {
+            "name": "none",
+            "longitude": -100.796917,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 46.836379,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:09"
+        },
+        {
+            "name": "none",
+            "longitude": -91.184167,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 30.449722,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:0a"
+        },
+        {
+            "name": "none",
+            "longitude": -87.640432,
+            "params": {
+                "numregens": 4
+            },
+            "allowed": true,
+            "latitude": 41.881484,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:0b"
+        },
+        {
+            "name": "none",
+            "longitude": -80.837502,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 35.224924,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:0c"
+        },
+        {
+            "name": "none",
+            "longitude": -79.938056,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 32.785278,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:0d"
+        },
+        {
+            "name": "none",
+            "longitude": -81.686943,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 41.498333,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:0e"
+        },
+        {
+            "name": "none",
+            "longitude": -82.996666,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 39.965279,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:0f"
+        },
+        {
+            "name": "none",
+            "longitude": -71.084918,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 42.36745,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:10"
+        },
+        {
+            "name": "none",
+            "longitude": -84.516944,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 39.102778,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:11"
+        },
+        {
+            "name": "none",
+            "longitude": -96.780431,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 32.797524,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:12"
+        },
+        {
+            "name": "none",
+            "longitude": -104.996391,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 39.744999,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:13"
+        },
+        {
+            "name": "none",
+            "longitude": -83.054169,
+            "params": {
+                "numregens": 5
+            },
+            "allowed": true,
+            "latitude": 42.332779,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:14"
+        },
+        {
+            "name": "none",
+            "longitude": -106.483611,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 31.756389,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:15"
+        },
+        {
+            "name": "none",
+            "longitude": -119.79423,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 36.73923,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:16"
+        },
+        {
+            "name": "none",
+            "longitude": -79.793889,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 36.072222,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:17"
+        },
+        {
+            "name": "none",
+            "longitude": -72.676389,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 41.765833,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:18"
+        },
+        {
+            "name": "none",
+            "longitude": -95.36528,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 29.748333,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:19"
+        },
+        {
+            "name": "none",
+            "longitude": -81.43,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 30.33071,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:1a"
+        },
+        {
+            "name": "none",
+            "longitude": -94.578716,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 39.096649,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:1b"
+        },
+        {
+            "name": "none",
+            "longitude": -73.6699993,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 40.5899999,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:1c"
+        },
+        {
+            "name": "none",
+            "longitude": -118.252958,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 34.051227,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:1d"
+        },
+        {
+            "name": "none",
+            "longitude": -115.138889,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 36.168056,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:1e"
+        },
+        {
+            "name": "none",
+            "longitude": -85.760833,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 38.249167,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:1f"
+        },
+        {
+            "name": "none",
+            "longitude": -92.271942,
+            "params": {
+                "numregens": 2
+            },
+            "allowed": true,
+            "latitude": 34.740833,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:20"
+        },
+        {
+            "name": "none",
+            "longitude": -80.195,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 25.779167,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:21"
+        },
+        {
+            "name": "none",
+            "longitude": -87.922501,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 43.037224,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:22"
+        },
+        {
+            "name": "none",
+            "longitude": -90.048058,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 35.145158,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:23"
+        },
+        {
+            "name": "none",
+            "longitude": -93.26718,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 44.977365,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:24"
+        },
+        {
+            "name": "none",
+            "longitude": -76.29,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 36.853333,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:25"
+        },
+        {
+            "name": "none",
+            "longitude": -86.775558,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 36.163955,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:26"
+        },
+        {
+            "name": "none",
+            "longitude": -90.07222,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 29.949806,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:27"
+        },
+        {
+            "name": "none",
+            "longitude": -74.177978,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 40.734408,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:28"
+        },
+        {
+            "name": "none",
+            "longitude": -73.989713,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 40.767497,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:29"
+        },
+        {
+            "name": "none",
+            "longitude": -97.515274,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 35.470833,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:2a"
+        },
+        {
+            "name": "none",
+            "longitude": -122.268889,
+            "params": {
+                "numregens": 2
+            },
+            "allowed": true,
+            "latitude": 37.805556,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:2b"
+        },
+        {
+            "name": "none",
+            "longitude": -95.940277,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 41.259167,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:2c"
+        },
+        {
+            "name": "none",
+            "longitude": -81.377502,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 28.543279,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:2d"
+        },
+        {
+            "name": "none",
+            "longitude": -75.184139,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 39.946446,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:2e"
+        },
+        {
+            "name": "none",
+            "longitude": -112.07709,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 33.450361,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:2f"
+        },
+        {
+            "name": "none",
+            "longitude": -79.995552,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 40.441387,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:30"
+        },
+        {
+            "name": "none",
+            "longitude": -71.415278,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 41.818889,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:31"
+        },
+        {
+            "name": "none",
+            "longitude": -122.678055,
+            "params": {
+                "numregens": 2
+            },
+            "allowed": true,
+            "latitude": 45.522499,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:32"
+        },
+        {
+            "name": "none",
+            "longitude": -77.436096,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 37.540752,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:33"
+        },
+        {
+            "name": "none",
+            "longitude": -78.640831,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 35.779656,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:34"
+        },
+        {
+            "name": "none",
+            "longitude": -77.616389,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 43.157222,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:35"
+        },
+        {
+            "name": "none",
+            "longitude": -121.487221,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 38.578609,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:36"
+        },
+        {
+            "name": "none",
+            "longitude": -75.649167,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 41.415278,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:37"
+        },
+        {
+            "name": "none",
+            "longitude": -111.888336,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 40.767776,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:38"
+        },
+        {
+            "name": "none",
+            "longitude": -98.488892,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 29.429445,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:39"
+        },
+        {
+            "name": "none",
+            "longitude": -119.7,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 34.418889,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:3a"
+        },
+        {
+            "name": "none",
+            "longitude": -117.158611,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 32.746944,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:3b"
+        },
+        {
+            "name": "none",
+            "longitude": -122.397263,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 37.785143,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:3c"
+        },
+        {
+            "name": "none",
+            "longitude": -121.892778,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 37.333333,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:3d"
+        },
+        {
+            "name": "none",
+            "longitude": -89.649444,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 39.795278,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:3e"
+        },
+        {
+            "name": "none",
+            "longitude": -117.419167,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 47.654724,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:3f"
+        },
+        {
+            "name": "none",
+            "longitude": -90.215279,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 38.633335,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:40"
+        },
+        {
+            "name": "none",
+            "longitude": -122.333336,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 47.606945,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:41"
+        },
+        {
+            "name": "none",
+            "longitude": -76.1475,
+            "params": {
+                "numregens": 3
+            },
+            "allowed": true,
+            "latitude": 43.049444,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:42"
+        },
+        {
+            "name": "none",
+            "longitude": -82.522778,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 28.0225,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:43"
+        },
+        {
+            "name": "none",
+            "longitude": -110.968333,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 32.224444,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:44"
+        },
+        {
+            "name": "none",
+            "longitude": -84.290833,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 30.456389,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:45"
+        },
+        {
+            "name": "none",
+            "longitude": -83.538056,
+            "params": {
+                "numregens": 2
+            },
+            "allowed": true,
+            "latitude": 41.65,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:46"
+        },
+        {
+            "name": "none",
+            "longitude": -95.985832,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 36.151669,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:47"
+        },
+        {
+            "name": "none",
+            "longitude": -77.01028,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 38.88306,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:48"
+        },
+        {
+            "name": "none",
+            "longitude": -75.553889,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 39.739167,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:49"
+        },
+        {
+            "name": "none",
+            "longitude": -80.05278,
+            "params": {
+                "numregens": 0
+            },
+            "allowed": true,
+            "latitude": 26.709391,
+            "type": "Roadm",
+            "nodeDpid": "00:00:ff:ff:ff:ff:ff:4a"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/TestON/tests/FUNCoptical/Topology.json b/TestON/tests/FUNCoptical/Topology.json
new file mode 100644
index 0000000..21c21e7
--- /dev/null
+++ b/TestON/tests/FUNCoptical/Topology.json
@@ -0,0 +1,4362 @@
+{
+    "devices": {
+        "of:0000ffffffffff4a": {
+            "basic": {
+                "name": "WPBHFLAN",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff4a",
+                "longitude": -80.05278,
+                "mfr": "Linc",
+                "latitude": 26.709391,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff4b": {
+            "basic": {
+                "name": "AUSTTXGR",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff4b",
+                "longitude": -96.7,
+                "mfr": "Linc",
+                "latitude": 29.57,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff44": {
+            "basic": {
+                "name": "TCSNAZMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff44",
+                "longitude": -110.968333,
+                "mfr": "Linc",
+                "latitude": 32.224444,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff45": {
+            "basic": {
+                "name": "TLHSFLAT",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff45",
+                "longitude": -84.290833,
+                "mfr": "Linc",
+                "latitude": 30.456389,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff46": {
+            "basic": {
+                "name": "TOLDOH21",
+                "optical.regens": 2,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff46",
+                "longitude": -83.538056,
+                "mfr": "Linc",
+                "latitude": 41.65,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff47": {
+            "basic": {
+                "name": "TULSOKTB",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff47",
+                "longitude": -95.985832,
+                "mfr": "Linc",
+                "latitude": 36.151669,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff40": {
+            "basic": {
+                "name": "STLSMO09",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff40",
+                "longitude": -90.215279,
+                "mfr": "Linc",
+                "latitude": 38.633335,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff41": {
+            "basic": {
+                "name": "STTLWA06",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff41",
+                "longitude": -122.333336,
+                "mfr": "Linc",
+                "latitude": 47.606945,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff42": {
+            "basic": {
+                "name": "SYRCNYSU",
+                "optical.regens": 3,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff42",
+                "longitude": -76.1475,
+                "mfr": "Linc",
+                "latitude": 43.049444,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff43": {
+            "basic": {
+                "name": "TAMQFLFN",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff43",
+                "longitude": -82.522778,
+                "mfr": "Linc",
+                "latitude": 28.0225,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff48": {
+            "basic": {
+                "name": "WASHDCSW",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff48",
+                "longitude": -77.01028,
+                "mfr": "Linc",
+                "latitude": 38.88306,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff49": {
+            "basic": {
+                "name": "WLMGDE01",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff49",
+                "longitude": -75.553889,
+                "mfr": "Linc",
+                "latitude": 39.739167,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffff00000a": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "DLLSTXTL-R",
+                "latitude": 32.7,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "eaf75c83054e",
+                "longitude": -96.7
+            }
+        },
+        "of:0000ffffff00000b": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "ATLNGATL-R",
+                "latitude": 33.7,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "ee5628887b4f",
+                "longitude": -97.7
+            }
+        },
+        "of:0000ffffffffff1d": {
+            "basic": {
+                "name": "LSANCA03",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff1d",
+                "longitude": -118.252958,
+                "mfr": "Linc",
+                "latitude": 34.051227,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff03": {
+            "basic": {
+                "name": "ALBYNYSS",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff03",
+                "longitude": -73.758333,
+                "mfr": "Linc",
+                "latitude": 42.652222,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff0a": {
+            "basic": {
+                "name": "BTRGLAMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff0a",
+                "longitude": -91.184167,
+                "mfr": "Linc",
+                "latitude": 30.449722,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff0b": {
+            "basic": {
+                "name": "CHCGILCL",
+                "optical.regens": 4,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff0b",
+                "longitude": -87.640432,
+                "mfr": "Linc",
+                "latitude": 41.881484,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff0c": {
+            "basic": {
+                "name": "CHRLNCCA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff0c",
+                "longitude": -80.837502,
+                "mfr": "Linc",
+                "latitude": 35.224924,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff0d": {
+            "basic": {
+                "name": "CHTNSCDT",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff0d",
+                "longitude": -79.938056,
+                "mfr": "Linc",
+                "latitude": 32.785278,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff0e": {
+            "basic": {
+                "name": "CLEVOH02",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff0e",
+                "longitude": -81.686943,
+                "mfr": "Linc",
+                "latitude": 41.498333,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff0f": {
+            "basic": {
+                "name": "CLMBOH11",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff0f",
+                "longitude": -82.996666,
+                "mfr": "Linc",
+                "latitude": 39.965279,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffff000008": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "MPLSMNDT-R",
+                "latitude": 44.9,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "96d57fb4eb43",
+                "longitude": -93.2
+            }
+        },
+        "of:0000ffffff000009": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "LSANCA03-R",
+                "latitude": 34.1,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "6ee9b704c04d",
+                "longitude": -118.3
+            }
+        },
+        "of:0000ffffffffff19": {
+            "basic": {
+                "name": "HSTNTX01",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff19",
+                "longitude": -95.36528,
+                "mfr": "Linc",
+                "latitude": 29.748333,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff18": {
+            "basic": {
+                "name": "HRFRCT03",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff18",
+                "longitude": -72.676389,
+                "mfr": "Linc",
+                "latitude": 41.765833,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff13": {
+            "basic": {
+                "name": "DNVRCOMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff13",
+                "longitude": -104.996391,
+                "mfr": "Linc",
+                "latitude": 39.744999,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffff000001": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "WASHDCSW-R",
+                "latitude": 38.8,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "2221b5cb5c45",
+                "longitude": -77.0
+            }
+        },
+        "of:0000ffffff000002": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "SNJSCA02-R",
+                "latitude": 37.3,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "f28c95ff6145",
+                "longitude": -121.8
+            }
+        },
+        "of:0000ffffffffff10": {
+            "basic": {
+                "name": "CMBRMA01",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff10",
+                "longitude": -71.084918,
+                "mfr": "Linc",
+                "latitude": 42.36745,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff17": {
+            "basic": {
+                "name": "GNBONCEU",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff17",
+                "longitude": -79.793889,
+                "mfr": "Linc",
+                "latitude": 36.072222,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffff000005": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "PHNXAZMA-R",
+                "latitude": 33.4,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "566c93367041",
+                "longitude": -112.0
+            }
+        },
+        "of:0000ffffffffff15": {
+            "basic": {
+                "name": "ELPSTXMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff15",
+                "longitude": -106.483611,
+                "mfr": "Linc",
+                "latitude": 31.756389,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff14": {
+            "basic": {
+                "name": "DTRTMIBA",
+                "optical.regens": 5,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff14",
+                "longitude": -83.054169,
+                "mfr": "Linc",
+                "latitude": 42.332779,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff12": {
+            "basic": {
+                "name": "DLLSTXTL",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff12",
+                "longitude": -96.780431,
+                "mfr": "Linc",
+                "latitude": 32.797524,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff11": {
+            "basic": {
+                "name": "CNCNOHWS",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff11",
+                "longitude": -84.516944,
+                "mfr": "Linc",
+                "latitude": 39.102778,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffff000003": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "SNANTXCA-R",
+                "latitude": 29.4,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "c6463e3da348",
+                "longitude": -98.4
+            }
+        },
+        "of:0000ffffffffff1c": {
+            "basic": {
+                "name": "LGISLAND",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff1c",
+                "longitude": -73.6699993,
+                "mfr": "Linc",
+                "latitude": 40.5899999,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffff000004": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "ROCHNYXA-R",
+                "latitude": 43.1,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "a2c8e539f440",
+                "longitude": -77.6
+            }
+        },
+        "of:0000ffffffffff1a": {
+            "basic": {
+                "name": "JCVLFLCL",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff1a",
+                "longitude": -81.43,
+                "mfr": "Linc",
+                "latitude": 30.33071,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff1f": {
+            "basic": {
+                "name": "LSVLKYCS",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff1f",
+                "longitude": -85.760833,
+                "mfr": "Linc",
+                "latitude": 38.249167,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff1e": {
+            "basic": {
+                "name": "LSVGNV02",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff1e",
+                "longitude": -115.138889,
+                "mfr": "Linc",
+                "latitude": 36.168056,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff16": {
+            "basic": {
+                "name": "FRSNCA01",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff16",
+                "longitude": -119.79423,
+                "mfr": "Linc",
+                "latitude": 36.73923,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff08": {
+            "basic": {
+                "name": "BRHMALMT",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff08",
+                "longitude": -86.812225,
+                "mfr": "Linc",
+                "latitude": 33.517223,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff09": {
+            "basic": {
+                "name": "BSMRNDJC",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff09",
+                "longitude": -100.796917,
+                "mfr": "Linc",
+                "latitude": 46.836379,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffff000006": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "ORLDFLMA-R",
+                "latitude": 28.5,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "bac54f68574f",
+                "longitude": -81.3
+            }
+        },
+        "of:0000ffffffffff01": {
+            "basic": {
+                "name": "ABLNTXRO",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff01",
+                "longitude": -99.741564,
+                "mfr": "Linc",
+                "latitude": 32.508086,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff02": {
+            "basic": {
+                "name": "ALBQNMMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff02",
+                "longitude": -106.649719,
+                "mfr": "Linc",
+                "latitude": 35.084446,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffff000007": {
+            "basic": {
+                "mfr": "Linc",
+                "name": "NWRKNJ02-R",
+                "latitude": 40.7,
+                "driver": "PK",
+                "type": "SWITCH",
+                "mac": "1237bde27347",
+                "longitude": -74.1
+            }
+        },
+        "of:0000ffffffffff04": {
+            "basic": {
+                "name": "ATLNGATL",
+                "optical.regens": 5,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff04",
+                "longitude": -97.743057,
+                "mfr": "Linc",
+                "latitude": 33.755833,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff05": {
+            "basic": {
+                "name": "BFLONYFR",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff05",
+                "longitude": -78.877778,
+                "mfr": "Linc",
+                "latitude": 42.882778,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff06": {
+            "basic": {
+                "name": "BLNGMTMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff06",
+                "longitude": -108.509167,
+                "mfr": "Linc",
+                "latitude": 45.781667,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff07": {
+            "basic": {
+                "name": "BLTMMDCH",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff07",
+                "longitude": -76.614127,
+                "mfr": "Linc",
+                "latitude": 39.293781,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff2b": {
+            "basic": {
+                "name": "OKLDCA03",
+                "optical.regens": 2,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff2b",
+                "longitude": -122.268889,
+                "mfr": "Linc",
+                "latitude": 37.805556,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff2c": {
+            "basic": {
+                "name": "OMAHNENW",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff2c",
+                "longitude": -95.940277,
+                "mfr": "Linc",
+                "latitude": 41.259167,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff2a": {
+            "basic": {
+                "name": "OKCYOKCE",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff2a",
+                "longitude": -97.515274,
+                "mfr": "Linc",
+                "latitude": 35.470833,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff2f": {
+            "basic": {
+                "name": "PHNXAZMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff2f",
+                "longitude": -112.07709,
+                "mfr": "Linc",
+                "latitude": 33.450361,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff2d": {
+            "basic": {
+                "name": "ORLDFLMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff2d",
+                "longitude": -81.377502,
+                "mfr": "Linc",
+                "latitude": 28.543279,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff2e": {
+            "basic": {
+                "name": "PHLAPASL",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff2e",
+                "longitude": -75.184139,
+                "mfr": "Linc",
+                "latitude": 39.946446,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff39": {
+            "basic": {
+                "name": "SNANTXCA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff39",
+                "longitude": -98.488892,
+                "mfr": "Linc",
+                "latitude": 29.429445,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff38": {
+            "basic": {
+                "name": "SLKCUTMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff38",
+                "longitude": -111.888336,
+                "mfr": "Linc",
+                "latitude": 40.767776,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff35": {
+            "basic": {
+                "name": "ROCHNYXA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff35",
+                "longitude": -77.616389,
+                "mfr": "Linc",
+                "latitude": 43.157222,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff34": {
+            "basic": {
+                "name": "RLGHNCMO",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff34",
+                "longitude": -78.640831,
+                "mfr": "Linc",
+                "latitude": 35.779656,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff37": {
+            "basic": {
+                "name": "SCTNPA01",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff37",
+                "longitude": -75.649167,
+                "mfr": "Linc",
+                "latitude": 41.415278,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff36": {
+            "basic": {
+                "name": "SCRMCA01",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff36",
+                "longitude": -121.487221,
+                "mfr": "Linc",
+                "latitude": 38.578609,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff31": {
+            "basic": {
+                "name": "PRVDRIGR",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff31",
+                "longitude": -71.415278,
+                "mfr": "Linc",
+                "latitude": 41.818889,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff30": {
+            "basic": {
+                "name": "PITBPADG",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff30",
+                "longitude": -79.995552,
+                "mfr": "Linc",
+                "latitude": 40.441387,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff33": {
+            "basic": {
+                "name": "RCMDVAGR",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff33",
+                "longitude": -77.436096,
+                "mfr": "Linc",
+                "latitude": 37.540752,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff32": {
+            "basic": {
+                "name": "PTLDOR62",
+                "optical.regens": 2,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff32",
+                "longitude": -122.678055,
+                "mfr": "Linc",
+                "latitude": 45.522499,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff22": {
+            "basic": {
+                "name": "MILWWIHE",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff22",
+                "longitude": -87.922501,
+                "mfr": "Linc",
+                "latitude": 43.037224,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff23": {
+            "basic": {
+                "name": "MMPHTNMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff23",
+                "longitude": -90.048058,
+                "mfr": "Linc",
+                "latitude": 35.145158,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff20": {
+            "basic": {
+                "name": "LTRKARFR",
+                "optical.regens": 2,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff20",
+                "longitude": -92.271942,
+                "mfr": "Linc",
+                "latitude": 34.740833,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff21": {
+            "basic": {
+                "name": "MIAMFLAC",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff21",
+                "longitude": -80.195,
+                "mfr": "Linc",
+                "latitude": 25.779167,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff26": {
+            "basic": {
+                "name": "NSVLTNMT",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff26",
+                "longitude": -86.775558,
+                "mfr": "Linc",
+                "latitude": 36.163955,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff27": {
+            "basic": {
+                "name": "NWORLAMA",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff27",
+                "longitude": -90.07222,
+                "mfr": "Linc",
+                "latitude": 29.949806,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff24": {
+            "basic": {
+                "name": "MPLSMNDT",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff24",
+                "longitude": -93.26718,
+                "mfr": "Linc",
+                "latitude": 44.977365,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff25": {
+            "basic": {
+                "name": "NRFLVABS",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff25",
+                "longitude": -76.29,
+                "mfr": "Linc",
+                "latitude": 36.853333,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff28": {
+            "basic": {
+                "name": "NWRKNJ02",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff28",
+                "longitude": -74.177978,
+                "mfr": "Linc",
+                "latitude": 40.734408,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff29": {
+            "basic": {
+                "name": "NYCMNY54",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff29",
+                "longitude": -73.989713,
+                "mfr": "Linc",
+                "latitude": 40.767497,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff3e": {
+            "basic": {
+                "name": "SPFDILSD",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff3e",
+                "longitude": -89.649444,
+                "mfr": "Linc",
+                "latitude": 39.795278,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff3d": {
+            "basic": {
+                "name": "SNJSCA02",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff3d",
+                "longitude": -121.892778,
+                "mfr": "Linc",
+                "latitude": 37.333333,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff3f": {
+            "basic": {
+                "name": "SPKNWA01",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff3f",
+                "longitude": -117.419167,
+                "mfr": "Linc",
+                "latitude": 47.654724,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff3a": {
+            "basic": {
+                "name": "SNBBCA01",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff3a",
+                "longitude": -119.7,
+                "mfr": "Linc",
+                "latitude": 34.418889,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff3c": {
+            "basic": {
+                "name": "SNFCCA21",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff3c",
+                "longitude": -122.397263,
+                "mfr": "Linc",
+                "latitude": 37.785143,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff3b": {
+            "basic": {
+                "name": "SNDGCA02",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff3b",
+                "longitude": -117.158611,
+                "mfr": "Linc",
+                "latitude": 32.746944,
+                "type": "ROADM"
+            }
+        },
+        "of:0000ffffffffff1b": {
+            "basic": {
+                "name": "KSCYMO09",
+                "optical.regens": 0,
+                "driver": "LINC-OE",
+                "mac": "ffffffffffff1b",
+                "longitude": -94.578716,
+                "mfr": "Linc",
+                "latitude": 39.096649,
+                "type": "ROADM"
+            }
+        }
+    },
+    "links": {
+        "of:0000ffffff000006/6-of:0000ffffffffff2d/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff1b/101-of:0000ffffffffff2c/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 320
+            }
+        },
+        "of:0000ffffffffff1f/102-of:0000ffffffffff40/108": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 468
+            }
+        },
+        "of:0000ffffff000001/4-of:0000ffffffffff48/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff0f/101-of:0000ffffffffff30/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 312
+            }
+        },
+        "of:0000ffffffffff06/103-of:0000ffffffffff3f/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 852
+            }
+        },
+        "of:0000ffffffffff30/101-of:0000ffffffffff37/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 457
+            }
+        },
+        "of:0000ffffffffff02/103-of:0000ffffffffff1e/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 931
+            }
+        },
+        "of:0000ffffff00000a/6-of:0000ffffffffff12/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff12/102-of:0000ffffffffff20/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 563
+            }
+        },
+        "of:0000ffffff000003/5-of:0000ffffffffff39/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000005/3-of:0000ffffffffff2f/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff05/103-of:0000ffffffffff0e/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 333
+            }
+        },
+        "of:0000ffffffffff22/101-of:0000ffffffffff24/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 574
+            }
+        },
+        "of:0000ffffffffff0a/102-of:0000ffffffffff27/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 144
+            }
+        },
+        "of:0000ffffffffff02/100-of:0000ffffffffff12/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 1134
+            }
+        },
+        "of:0000ffffffffff04/102-of:0000ffffffffff0c/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 436
+            }
+        },
+        "of:0000ffffff00000a/4-of:0000ffffffffff12/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff2d/101-of:0000ffffffffff4a/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 290
+            }
+        },
+        "of:0000ffffffffff13/101-of:0000ffffffffff2c/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 940
+            }
+        },
+        "of:0000ffffff000008/2-of:0000ffffffffff24/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000007/6-of:0000ffffffffff28/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000008/3-of:0000ffffffffff24/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff14/101-of:0000ffffffffff46/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 103
+            }
+        },
+        "of:0000ffffff000002/3-of:0000ffffffffff3d/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000009/3-of:0000ffffffffff1d/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff11/103-of:0000ffffffffff48/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 779
+            }
+        },
+        "of:0000ffffff000002/5-of:0000ffffffffff3d/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff1b/103-of:0000ffffffffff47/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 420
+            }
+        },
+        "of:0000ffffffffff0d/101-of:0000ffffffffff1a/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 368
+            }
+        },
+        "of:0000ffffff000009/4-of:0000ffffffffff1d/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff28/101-of:0000ffffffffff2e/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 146
+            }
+        },
+        "of:0000ffffffffff1f/104-of:0000ffffffffff26/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 298
+            }
+        },
+        "of:0000ffffffffff0e/102-of:0000ffffffffff46/101": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 185
+            }
+        },
+        "of:0000ffffff000005/4-of:0000ffffffffff2f/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff0c/101-of:0000ffffffffff17/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 160
+            }
+        },
+        "of:0000ffffffffff18/101-of:0000ffffffffff1c/108": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 185
+            }
+        },
+        "of:0000ffffffffff06/101-of:0000ffffffffff09/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 724
+            }
+        },
+        "of:0000ffffff000009/5-of:0000ffffffffff1d/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff17/101-of:0000ffffffffff1f/108": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 697
+            }
+        },
+        "of:0000ffffffffff16/102-of:0000ffffffffff1d/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 396
+            }
+        },
+        "of:0000ffffff00000a/2-of:0000ffffffffff12/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff1c/101-of:0000ffffffffff29/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 40
+            }
+        },
+        "of:0000ffffff000006/4-of:0000ffffffffff2d/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff08/102-of:0000ffffffffff27/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 602
+            }
+        },
+        "of:0000ffffffffff1d/102-of:0000ffffffffff3a/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 167
+            }
+        },
+        "of:0000ffffff00000a/5-of:0000ffffffffff12/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000001/3-of:0000ffffffffff48/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff01/100-of:0000ffffffffff12/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 334
+            }
+        },
+        "of:0000ffffffffff1a/101-of:0000ffffffffff2d/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 238
+            }
+        },
+        "of:0000ffffff000004/6-of:0000ffffffffff35/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff1e/102-of:0000ffffffffff38/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 701
+            }
+        },
+        "of:0000ffffff000008/6-of:0000ffffffffff24/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000004/4-of:0000ffffffffff35/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000002/2-of:0000ffffffffff3d/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff03/101-of:0000ffffffffff42/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 239
+            }
+        },
+        "of:0000ffffffffff2e/101-of:0000ffffffffff37/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 201
+            }
+        },
+        "of:0000ffffffffff13/102-of:0000ffffffffff38/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 714
+            }
+        },
+        "of:0000ffffffffff07/101-of:0000ffffffffff2e/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 170
+            }
+        },
+        "of:0000ffffffffff16/103-of:0000ffffffffff2a/108": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 298
+            }
+        },
+        "of:0000ffffffffff3e/101-of:0000ffffffffff40/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 165
+            }
+        },
+        "of:0000ffffffffff02/101-of:0000ffffffffff13/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 646
+            }
+        },
+        "of:0000ffffff000002/6-of:0000ffffffffff3d/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000007/5-of:0000ffffffffff28/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000002/4-of:0000ffffffffff3d/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff01/101-of:0000ffffffffff15/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 768
+            }
+        },
+        "of:0000ffffff000006/2-of:0000ffffffffff2d/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff04/103-of:0000ffffffffff1a/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 566
+            }
+        },
+        "of:0000ffffffffff0e/101-of:0000ffffffffff0f/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 243
+            }
+        },
+        "of:0000ffffff000003/4-of:0000ffffffffff39/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000009/2-of:0000ffffffffff1d/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff18/102-of:0000ffffffffff31/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 125
+            }
+        },
+        "of:0000ffffff000001/5-of:0000ffffffffff48/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff11/102-of:0000ffffffffff1f/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 172
+            }
+        },
+        "of:0000ffffff00000b/6-of:0000ffffffffff04/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff29/101-of:0000ffffffffff28/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 19
+            }
+        },
+        "of:0000ffffffffff12/101-of:0000ffffffffff19/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 437
+            }
+        },
+        "of:0000ffffffffff3d/101-of:0000ffffffffff3a/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 455
+            }
+        },
+        "of:0000ffffffffff2b/103-of:0000ffffffffff3c/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 13
+            }
+        },
+        "of:0000ffffffffff4b/101-of:0000ffffffffff19/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 283
+            }
+        },
+        "of:0000ffffffffff32/101-of:0000ffffffffff36/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 934
+            }
+        },
+        "of:0000ffffffffff12/103-of:0000ffffffffff2a/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 365
+            }
+        },
+        "of:0000ffffffffff0d/102-of:0000ffffffffff34/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 424
+            }
+        },
+        "of:0000ffffffffff29/103-of:0000ffffffffff49/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 210
+            }
+        },
+        "of:0000ffffffffff10/101-of:0000ffffffffff31/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 80
+            }
+        },
+        "of:0000ffffffffff1d/101-of:0000ffffffffff3b/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 212
+            }
+        },
+        "of:0000ffffffffff29/102-of:0000ffffffffff37/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 187
+            }
+        },
+        "of:0000ffffff00000a/3-of:0000ffffffffff12/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff15/101-of:0000ffffffffff39/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 969
+            }
+        },
+        "of:0000ffffff000003/6-of:0000ffffffffff39/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff1e/101-of:0000ffffffffff2f/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 494
+            }
+        },
+        "of:0000ffffffffff1b/102-of:0000ffffffffff40/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 457
+            }
+        },
+        "of:0000ffffff000001/2-of:0000ffffffffff48/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff21/102-of:0000ffffffffff4a/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 125
+            }
+        },
+        "of:0000ffffff000003/3-of:0000ffffffffff39/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff15/102-of:0000ffffffffff44/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 511
+            }
+        },
+        "of:0000ffffff000005/2-of:0000ffffffffff2f/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff2b/102-of:0000ffffffffff38/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 1142
+            }
+        },
+        "of:0000ffffffffff0b/101-of:0000ffffffffff14/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 458
+            }
+        },
+        "of:0000ffffffffff45/101-of:0000ffffffffff43/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 384
+            }
+        },
+        "of:0000ffffffffff32/102-of:0000ffffffffff38/108": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 1225
+            }
+        },
+        "of:0000ffffffffff24/101-of:0000ffffffffff2c/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 560
+            }
+        },
+        "of:0000ffffff000006/3-of:0000ffffffffff2d/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff3c/101-of:0000ffffffffff3d/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 80.0
+            }
+        },
+        "of:0000ffffffffff21/101-of:0000ffffffffff43/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 407
+            }
+        },
+        "of:0000ffffff000008/5-of:0000ffffffffff24/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000005/6-of:0000ffffffffff2f/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff2f/102-of:0000ffffffffff44/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 205
+            }
+        },
+        "of:0000ffffff000007/3-of:0000ffffffffff28/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff0a/101-of:0000ffffffffff19/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 491
+            }
+        },
+        "of:0000ffffffffff41/101-of:0000ffffffffff3f/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 442
+            }
+        },
+        "of:0000ffffffffff33/101-of:0000ffffffffff48/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 184
+            }
+        },
+        "of:0000ffffff000004/3-of:0000ffffffffff35/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff2f/101-of:0000ffffffffff3b/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 575
+            }
+        },
+        "of:0000ffffff000006/5-of:0000ffffffffff2d/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff00000b/3-of:0000ffffffffff04/11": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000009/6-of:0000ffffffffff1d/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000007/2-of:0000ffffffffff28/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff17/103-of:0000ffffffffff33/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 319
+            }
+        },
+        "of:0000ffffffffff16/101-of:0000ffffffffff1f/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 505
+            }
+        },
+        "of:0000ffffffffff17/102-of:0000ffffffffff34/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 130
+            }
+        },
+        "of:0000ffffffffff2b/101-of:0000ffffffffff36/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 131
+            }
+        },
+        "of:0000ffffffffff03/100-of:0000ffffffffff10/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 265
+            }
+        },
+        "of:0000ffffffffff04/101-of:0000ffffffffff08/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 271
+            }
+        },
+        "of:0000ffffffffff07/103-of:0000ffffffffff46/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 68
+            }
+        },
+        "of:0000ffffffffff0b/102-of:0000ffffffffff22/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 156
+            }
+        },
+        "of:0000ffffffffff20/101-of:0000ffffffffff23/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 249
+            }
+        },
+        "of:0000ffffff00000b/2-of:0000ffffffffff04/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff25/102-of:0000ffffffffff49/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 392
+            }
+        },
+        "of:0000ffffffffff09/101-of:0000ffffffffff24/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 741
+            }
+        },
+        "of:0000ffffffffff2a/101-of:0000ffffffffff47/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 188
+            }
+        },
+        "of:0000ffffff000003/2-of:0000ffffffffff39/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff11/101-of:0000ffffffffff0f/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 194
+            }
+        },
+        "of:0000ffffffffff35/101-of:0000ffffffffff42/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 143
+            }
+        },
+        "of:0000ffffff000005/5-of:0000ffffffffff2f/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff00000b/5-of:0000ffffffffff04/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff25/101-of:0000ffffffffff34/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 290
+            }
+        },
+        "of:0000ffffffffff32/103-of:0000ffffffffff41/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 280
+            }
+        },
+        "of:0000ffffff000008/4-of:0000ffffffffff24/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff02/102-of:0000ffffffffff15/107": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 444
+            }
+        },
+        "of:0000ffffffffff0b/103-of:0000ffffffffff3e/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 344
+            }
+        },
+        "of:0000ffffffffff07/102-of:0000ffffffffff30/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 378
+            }
+        },
+        "of:0000ffffffffff4b/102-of:0000ffffffffff39/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 141
+            }
+        },
+        "of:0000ffffffffff23/101-of:0000ffffffffff26/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 380
+            }
+        },
+        "of:0000ffffff00000b/4-of:0000ffffffffff04/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff08/101-of:0000ffffffffff26/106": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 353
+            }
+        },
+        "of:0000ffffffffff27/101-of:0000ffffffffff45/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 670
+            }
+        },
+        "of:0000ffffff000004/2-of:0000ffffffffff35/10": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000001/6-of:0000ffffffffff48/14": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff05/104-of:0000ffffffffff35/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 128
+            }
+        },
+        "of:0000ffffffffff37/101-of:0000ffffffffff42/105": {
+            "basic": {
+                "optical.waves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 223
+            }
+        },
+        "of:0000ffffff000004/5-of:0000ffffffffff35/13": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffff000007/4-of:0000ffffffffff28/12": {
+            "basic": {
+                "bandwidth": 100000,
+                "type": "OPTICAL",
+                "durable": "true",
+                "optical.type": "cross-connect"
+            }
+        },
+        "of:0000ffffffffff06/102-of:0000ffffffffff13/107": {
+            "basic": {
+                "optical.wves": 80,
+                "durable": "true",
+                "type": "OPTICAL",
+                "optical.type": "WDM",
+                "optical.kms": 875
+            }
+        }
+    },
+    "ports": {
+        "of:0000ffffffffff27/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff3b/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff3b/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffff00000b/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffffffff32/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff22/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff4b/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff22/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff2f/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff03/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff03/100": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 100
+            }
+        },
+        "of:0000ffffffffff38/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff32/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff38/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff38/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff38/108": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 108
+            }
+        },
+        "of:0000ffffffffff1e/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffff000008/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffffffff3d/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff3d/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffffffff1e/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff3d/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff3f/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff1e/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff42/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff42/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff42/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff41/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff39/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff39/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff35/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffff000009/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffffffff49/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff49/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff2f/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff24/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff46/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff27/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff43/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff43/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff35/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff04/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffffffff04/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff04/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff04/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff36/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff36/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff04/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff35/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff28/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff17/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff17/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff17/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff47/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff47/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff17/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff20/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff14/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffff000005/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffffffff1d/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff1d/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffffffff14/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff1d/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff18/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff18/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff35/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff2b/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff2b/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff2a/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff39/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffff000006/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffff000006/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffffffff1d/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff39/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff16/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff16/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff16/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff15/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff15/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff15/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff15/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff48/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffff00000a/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffff00000a/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffffffff3c/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff3c/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff23/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff04/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff04/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff04/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff23/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff1c/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff33/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff07/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff07/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff07/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff3d/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff40/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff2e/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff2e/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff35/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff2e/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff3a/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff2d/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff2d/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff2d/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff2d/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffffffff2d/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff05/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff05/104": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 104
+            }
+        },
+        "of:0000ffffffffff24/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff13/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff13/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff06/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff13/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff13/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff06/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffff000007/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffff000007/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffffffff48/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff44/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff44/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff35/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffffffff46/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff46/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff31/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff31/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff12/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff12/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff2d/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff12/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff32/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff12/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff12/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff0d/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff0d/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff48/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff19/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff19/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff19/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff29/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff29/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff29/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff28/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff0a/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff29/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff35/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff0a/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff30/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffff000004/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffffffff39/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff39/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff30/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff30/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff39/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff12/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff12/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff12/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff12/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffffffff12/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff1d/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff33/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff2c/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff48/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff2c/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff2c/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff2d/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff28/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff28/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff28/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffffffff28/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff28/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff45/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff3d/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff45/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffff000004/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffff000004/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffffffff01/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff01/100": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 100
+            }
+        },
+        "of:0000ffffff000001/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffff000005/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffff000005/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffffffff27/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffff000007/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffffffff1b/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff1b/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff1b/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff24/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff2b/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff06/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff11/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff11/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff11/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff24/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffff000002/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffffffff08/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff2a/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff24/12": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 12
+            }
+        },
+        "of:0000ffffffffff08/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff08/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff0b/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff0b/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff0c/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff0b/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff0c/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff26/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff26/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff2f/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffff00000a/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffffffff2f/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff2f/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff1c/108": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 108
+            }
+        },
+        "of:0000ffffffffff2f/14": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 14
+            }
+        },
+        "of:0000ffffffffff34/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff34/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff34/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff4a/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff4a/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff09/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff2a/108": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 108
+            }
+        },
+        "of:0000ffffffffff09/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffff000002/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffffffff1d/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff1d/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff1d/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffff000006/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffff000002/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffff000001/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffffffff02/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff02/103": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 103
+            }
+        },
+        "of:0000ffffffffff02/100": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 100
+            }
+        },
+        "of:0000ffffffffff02/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff2f/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff26/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff0e/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff0e/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff4b/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff0e/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffff000008/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffffffff1a/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff1a/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffff000009/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffffffff1a/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff24/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffff000009/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffffffff24/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffff000008/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffffffff24/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffff000001/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffff00000b/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffff00000b/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffffffff2f/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff3a/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff3d/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffff000003/7": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 7
+            }
+        },
+        "of:0000ffffffffff48/11": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 11
+            }
+        },
+        "of:0000ffffffffff48/10": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 10
+            }
+        },
+        "of:0000ffffffffff3d/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff20/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff41/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff25/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff25/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff1f/108": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 108
+            }
+        },
+        "of:0000ffffffffff10/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff37/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff37/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff37/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        },
+        "of:0000ffffffffff10/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff37/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffff000003/8": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 8
+            }
+        },
+        "of:0000ffffff000003/9": {
+            "optical": {
+                "speed": 0,
+                "type": "COPPER",
+                "port": 9
+            }
+        },
+        "of:0000ffffffffff1f/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff1f/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff1f/104": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 104
+            }
+        },
+        "of:0000ffffffffff1f/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff0f/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff3e/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff0f/105": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 105
+            }
+        },
+        "of:0000ffffffffff48/13": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 13
+            }
+        },
+        "of:0000ffffffffff3e/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff40/106": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 106
+            }
+        },
+        "of:0000ffffffffff0f/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff40/108": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 108
+            }
+        },
+        "of:0000ffffffffff21/102": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 102
+            }
+        },
+        "of:0000ffffffffff21/101": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 101
+            }
+        },
+        "of:0000ffffffffff3f/107": {
+            "optical": {
+                "type": "FIBER",
+                "speed": 0,
+                "port": 107
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/TestON/tests/HAminorityRestart/__init__.py b/TestON/tests/FUNCoptical/__init__.py
similarity index 100%
copy from TestON/tests/HAminorityRestart/__init__.py
copy to TestON/tests/FUNCoptical/__init__.py
diff --git a/TestON/tests/HAclusterRestart/HAclusterRestart.params b/TestON/tests/HAclusterRestart/HAclusterRestart.params
index 4626c39..e28c0f7 100644
--- a/TestON/tests/HAclusterRestart/HAclusterRestart.params
+++ b/TestON/tests/HAclusterRestart/HAclusterRestart.params
@@ -40,7 +40,7 @@
         <port7>6653</port7>
     </CTRL>
     <BACKUP>
-        <ENABLED>False</ENABLED>
+        <ENABLED> False </ENABLED>
         <TESTONUSER>admin</TESTONUSER>
         <TESTONIP>10.128.30.9</TESTONIP>
     </BACKUP>
@@ -69,6 +69,7 @@
     <timers>
         <LinkDiscovery>12</LinkDiscovery>
         <SwitchDiscovery>12</SwitchDiscovery>
+        <gossip>5</gossip>
     </timers>
     <kill>
         <switch> s5 </switch>
diff --git a/TestON/tests/HAclusterRestart/HAclusterRestart.py b/TestON/tests/HAclusterRestart/HAclusterRestart.py
index 3e81d3e..1169a7d 100644
--- a/TestON/tests/HAclusterRestart/HAclusterRestart.py
+++ b/TestON/tests/HAclusterRestart/HAclusterRestart.py
@@ -752,14 +752,16 @@
                 append = True
             else:
                 count += 1
-        # FIXME: make this time configurable/calculate based off of number of
-        #        nodes and gossip rounds
+        gossipPeriod = int( main.params['timers']['gossip'] )
+        maxGossipTime = gossipPeriod * len( main.nodes )
         utilities.assert_greater_equals(
-                expect=40, actual=gossipTime,
+                expect=maxGossipTime, actual=gossipTime,
                 onpass="ECM anti-entropy for intents worked within " +
                        "expected time",
-                onfail="Intent ECM anti-entropy took too long" )
-        if gossipTime <= 40:
+                onfail="Intent ECM anti-entropy took too long. " +
+                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
+                                                                  gossipTime ) )
+        if gossipTime <= maxGossipTime:
             intentAddResult = True
 
         if not intentAddResult or "key" in pendingMap:
diff --git a/TestON/tests/HAclusterRestart/dependencies/obelisk.py b/TestON/tests/HAclusterRestart/dependencies/obelisk.py
index 4378a9b..d613806 100755
--- a/TestON/tests/HAclusterRestart/dependencies/obelisk.py
+++ b/TestON/tests/HAclusterRestart/dependencies/obelisk.py
@@ -67,4 +67,3 @@
 if __name__ == '__main__':
     setLogLevel( 'info' )
     run()
-
diff --git a/TestON/tests/HAminorityRestart/HAminorityRestart.params b/TestON/tests/HAkillNodes/HAkillNodes.params
similarity index 62%
copy from TestON/tests/HAminorityRestart/HAminorityRestart.params
copy to TestON/tests/HAkillNodes/HAkillNodes.params
index 348768c..7d9c090 100644
--- a/TestON/tests/HAminorityRestart/HAminorityRestart.params
+++ b/TestON/tests/HAkillNodes/HAkillNodes.params
@@ -1,7 +1,27 @@
 <PARAMS>
-    <testcases>1,2,8,3,4,5,14,16,17,[6],8,7,4,15,17,9,8,4,10,8,4,11,8,4,12,8,4,13</testcases>
+    #List of test cases:
+    #CASE1: Compile ONOS and push it to the test machines
+    #CASE2: Assign devices to controllers
+    #CASE21: Assign mastership to controllers
+    #CASE3: Assign intents
+    #CASE4: Ping across added host intents
+    #CASE5: Reading state of ONOS
+    #CASE61: The Failure inducing case.
+    #CASE62: The Failure recovery case.
+    #CASE7: Check state after control plane failure
+    #CASE8: Compare topo
+    #CASE9: Link s3-s28 down
+    #CASE10: Link s3-s28 up
+    #CASE11: Switch down
+    #CASE12: Switch up
+    #CASE13: Clean up
+    #CASE14: start election app on all onos nodes
+    #CASE15: Check that Leadership Election is still functional
+    #CASE16: Install Distributed Primitives app
+    #CASE17: Check for basic functionality with distributed primitives
+    <testcases>1,2,8,3,4,5,14,16,17,[61,8,7,4,15,17,62],8,7,4,15,17,9,8,4,10,8,4,11,8,4,12,8,4,13</testcases>
     <imports>
-        <path> /home/admin/OnosSystemTest/TestON/tests/HAminorityRestart/dependencies/ </path>
+        <path> /home/admin/OnosSystemTest/TestON/tests/HAkillNodes/dependencies/ </path>
     </imports>
     <ENV>
         <cellName>HA</cellName>
@@ -51,6 +71,7 @@
     <timers>
         <LinkDiscovery>12</LinkDiscovery>
         <SwitchDiscovery>12</SwitchDiscovery>
+        <gossip>5</gossip>
     </timers>
     <kill>
         <switch> s5 </switch>
diff --git a/TestON/tests/HAminorityRestart/HAminorityRestart.py b/TestON/tests/HAkillNodes/HAkillNodes.py
similarity index 90%
rename from TestON/tests/HAminorityRestart/HAminorityRestart.py
rename to TestON/tests/HAkillNodes/HAkillNodes.py
index ca8a194..4c61769 100644
--- a/TestON/tests/HAminorityRestart/HAminorityRestart.py
+++ b/TestON/tests/HAkillNodes/HAkillNodes.py
@@ -9,7 +9,8 @@
 CASE3: Assign intents
 CASE4: Ping across added host intents
 CASE5: Reading state of ONOS
-CASE6: The Failure case.
+CASE61: The Failure inducing case.
+CASE62: The Failure recovery case.
 CASE7: Check state after control plane failure
 CASE8: Compare topo
 CASE9: Link s3-s28 down
@@ -24,7 +25,7 @@
 """
 
 
-class HAminorityRestart:
+class HAkillNodes:
 
     def __init__( self ):
         self.default = ''
@@ -171,12 +172,19 @@
                                  actual=cleanInstallResult,
                                  onpass="MCI successful",
                                  onfail="MCI failed" )
+
+        main.step( "Make sure ONOS service doesn't automatically respawn" )
+        handle = main.ONOSbench.handle
+        handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
+        handle.expect( "\$" )  # $ from the command
+        handle.expect( "\$" )  # $ from the prompt
+
         # GRAPHS
         # NOTE: important params here:
         #       job = name of Jenkins job
         #       Plot Name = Plot-HA, only can be used if multiple plots
         #       index = The number of the graph under plot name
-        job = "HAminorityRestart"
+        job = "HAkillNodes"
         plotName = "Plot-HA"
         graphs = '<ac:structured-macro ac:name="html">\n'
         graphs += '<ac:plain-text-body><![CDATA[\n'
@@ -261,6 +269,9 @@
                                  onpass="ONOS cli startup successful",
                                  onfail="ONOS cli startup failed" )
 
+        # Create a list of active nodes for use when some nodes are stopped
+        main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
+
         if main.params[ 'tcpdump' ].lower() == "true":
             main.step( "Start Packet Capture MN" )
             main.Mininet2.startTcpdump(
@@ -272,7 +283,7 @@
         main.step( "App Ids check" )
         appCheck = main.TRUE
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].appToIDCheck,
                              name="appToIDCheck-" + str( i ),
                              args=[] )
@@ -283,12 +294,17 @@
             t.join()
             appCheck = appCheck and t.result
         if appCheck != main.TRUE:
-            main.log.warn( main.CLIs[0].apps() )
-            main.log.warn( main.CLIs[0].appIDs() )
+            node = main.activeNodes[0]
+            main.log.warn( main.CLIs[node].apps() )
+            main.log.warn( main.CLIs[node].appIDs() )
         utilities.assert_equals( expect=main.TRUE, actual=appCheck,
                                  onpass="App Ids seem to be correct",
                                  onfail="Something is wrong with app Ids" )
 
+        main.step( "Clean up ONOS service changes" )
+        handle.sendline( "git checkout -- tools/package/init/onos.conf" )
+        handle.expect( "\$" )
+
         if cliResults == main.FALSE:
             main.log.error( "Failed to start ONOS, stopping test" )
             main.cleanup()
@@ -376,6 +392,7 @@
 
         ipList = [ ]
         deviceList = []
+        onosCli = main.CLIs[ main.activeNodes[0] ]
         try:
             # Assign mastership to specific controllers. This assignment was
             # determined for a 7 node cluser, but will work with any sized
@@ -385,45 +402,45 @@
                 if i == 1:
                     c = 0
                     ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
                 elif i == 2:
                     c = 1 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
                 elif i == 3:
                     c = 1 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
                 elif i == 4:
                     c = 3 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
                 elif i == 5:
                     c = 2 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
                 elif i == 6:
                     c = 2 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
                 elif i == 7:
                     c = 5 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
                 elif i >= 8 and i <= 17:
                     c = 4 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS5
                     dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
                 elif i >= 18 and i <= 27:
                     c = 6 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS7
                     dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
                 elif i == 28:
                     c = 0
                     ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
                 else:
                     main.log.error( "You didn't write an else statement for " +
                                     "switch s" + str( i ) )
@@ -431,13 +448,12 @@
                 # Assign switch
                 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
                 # TODO: make this controller dynamic
-                roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
-                                                                  ip )
+                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
                 ipList.append( ip )
                 deviceList.append( deviceId )
         except ( AttributeError, AssertionError ):
             main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( main.ONOScli1.devices() )
+            main.log.info( onosCli.devices() )
         utilities.assert_equals(
             expect=main.TRUE,
             actual=roleCall,
@@ -453,7 +469,7 @@
             ip = ipList[i]
             deviceId = deviceList[i]
             # Check assignment
-            master = main.ONOScli1.getRole( deviceId ).get( 'master' )
+            master = onosCli.getRole( deviceId ).get( 'master' )
             if ip in master:
                 roleCheck = roleCheck and main.TRUE
             else:
@@ -489,7 +505,8 @@
 
         # install onos-app-fwd
         main.step( "Install reactive forwarding app" )
-        installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
+        onosCli = main.CLIs[ main.activeNodes[0] ]
+        installResults = onosCli.activateApp( "org.onosproject.fwd" )
         utilities.assert_equals( expect=main.TRUE, actual=installResults,
                                  onpass="Install fwd successful",
                                  onfail="Install fwd failed" )
@@ -497,7 +514,7 @@
         main.step( "Check app ids" )
         appCheck = main.TRUE
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].appToIDCheck,
                              name="appToIDCheck-" + str( i ),
                              args=[] )
@@ -508,8 +525,8 @@
             t.join()
             appCheck = appCheck and t.result
         if appCheck != main.TRUE:
-            main.log.warn( main.CLIs[0].apps() )
-            main.log.warn( main.CLIs[0].appIDs() )
+            main.log.warn( onosCli.apps() )
+            main.log.warn( onosCli.appIDs() )
         utilities.assert_equals( expect=main.TRUE, actual=appCheck,
                                  onpass="App Ids seem to be correct",
                                  onfail="Something is wrong with app Ids" )
@@ -538,7 +555,8 @@
         time.sleep( 11 )
         # uninstall onos-app-fwd
         main.step( "Uninstall reactive forwarding app" )
-        uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
+        node = main.activeNodes[0]
+        uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
         utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
                                  onpass="Uninstall fwd successful",
                                  onfail="Uninstall fwd failed" )
@@ -546,7 +564,7 @@
         main.step( "Check app ids" )
         threads = []
         appCheck2 = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].appToIDCheck,
                              name="appToIDCheck-" + str( i ),
                              args=[] )
@@ -557,16 +575,17 @@
             t.join()
             appCheck2 = appCheck2 and t.result
         if appCheck2 != main.TRUE:
-            main.log.warn( main.CLIs[0].apps() )
-            main.log.warn( main.CLIs[0].appIDs() )
+            node = main.activeNodes[0]
+            main.log.warn( main.CLIs[node].apps() )
+            main.log.warn( main.CLIs[node].appIDs() )
         utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
                                  onpass="App Ids seem to be correct",
                                  onfail="Something is wrong with app Ids" )
 
         main.step( "Add host intents via cli" )
         intentIds = []
-        # TODO:  move the host numbers to params
-        #        Maybe look at all the paths we ping?
+        # TODO: move the host numbers to params
+        #       Maybe look at all the paths we ping?
         intentAddResult = True
         hostResult = main.TRUE
         for i in range( 8, 18 ):
@@ -577,16 +596,17 @@
             host2 = "00:00:00:00:00:" + \
                 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
             # NOTE: getHost can return None
-            host1Dict = main.ONOScli1.getHost( host1 )
-            host2Dict = main.ONOScli1.getHost( host2 )
+            host1Dict = onosCli.getHost( host1 )
+            host2Dict = onosCli.getHost( host2 )
             host1Id = None
             host2Id = None
             if host1Dict and host2Dict:
                 host1Id = host1Dict.get( 'id', None )
                 host2Id = host2Dict.get( 'id', None )
             if host1Id and host2Id:
-                nodeNum = ( i % main.numCtrls )
-                tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
+                nodeNum = ( i % len( main.activeNodes ) )
+                node = main.activeNodes[nodeNum]
+                tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
                 if tmpId:
                     main.log.info( "Added intent with id: " + tmpId )
                     intentIds.append( tmpId )
@@ -596,7 +616,8 @@
             else:
                 main.log.error( "Error, getHost() failed for h" + str( i ) +
                                 " and/or h" + str( i + 10 ) )
-                hosts = main.CLIs[ 0 ].hosts()
+                node = main.activeNodes[0]
+                hosts = main.CLIs[node].hosts()
                 main.log.warn( "Hosts output: " )
                 try:
                     main.log.warn( json.dumps( json.loads( hosts ),
@@ -611,7 +632,7 @@
                                  onfail="Error looking up host ids" )
 
         intentStart = time.time()
-        onosIds = main.ONOScli1.getAllIntentsId()
+        onosIds = onosCli.getAllIntentsId()
         main.log.info( "Submitted intents: " + str( intentIds ) )
         main.log.info( "Intents in ONOS: " + str( onosIds ) )
         for intent in intentIds:
@@ -624,7 +645,7 @@
         else:
             intentStop = None
         # Print the intent states
-        intents = main.ONOScli1.intents()
+        intents = onosCli.intents()
         intentStates = []
         installedCheck = True
         main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
@@ -650,7 +671,7 @@
             count += 1
             main.log.info( "%-6s%-15s%-15s" %
                            ( str( count ), str( i ), str( s ) ) )
-        leaders = main.ONOScli1.leaders()
+        leaders = onosCli.leaders()
         try:
             missing = False
             if leaders:
@@ -677,12 +698,12 @@
             main.log.error( repr( leaders ) )
         # Check all nodes
         if missing:
-            for node in main.CLIs:
-                response = node.leaders( jsonFormat=False)
-                main.log.warn( str( node.name ) + " leaders output: \n" +
+            for i in main.activeNodes:
+                response = main.CLIs[i].leaders( jsonFormat=False)
+                main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
                                str( response ) )
 
-        partitions = main.ONOScli1.partitions()
+        partitions = onosCli.partitions()
         try:
             if partitions :
                 parsedPartitions = json.loads( partitions )
@@ -697,7 +718,7 @@
         except ( ValueError, TypeError ):
             main.log.exception( "Error parsing partitions" )
             main.log.error( repr( partitions ) )
-        pendingMap = main.ONOScli1.pendingMap()
+        pendingMap = onosCli.pendingMap()
         try:
             if pendingMap :
                 parsedPending = json.loads( pendingMap )
@@ -718,21 +739,21 @@
             main.log.error( "Error in pushing host intents to ONOS" )
 
         main.step( "Intent Anti-Entropy dispersion" )
-        for i in range(100):
+        for j in range(100):
             correct = True
             main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for cli in main.CLIs:
+            for i in main.activeNodes:
                 onosIds = []
-                ids = cli.getAllIntentsId()
+                ids = main.CLIs[i].getAllIntentsId()
                 onosIds.append( ids )
-                main.log.debug( "Intents in " + cli.name + ": " +
+                main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
                                 str( sorted( onosIds ) ) )
                 if sorted( ids ) != sorted( intentIds ):
                     main.log.warn( "Set of intent IDs doesn't match" )
                     correct = False
                     break
                 else:
-                    intents = json.loads( cli.intents() )
+                    intents = json.loads( main.CLIs[i].intents() )
                     for intent in intents:
                         if intent[ 'state' ] != "INSTALLED":
                             main.log.warn( "Intent " + intent[ 'id' ] +
@@ -749,14 +770,16 @@
         gossipTime = intentStop - intentStart
         main.log.info( "It took about " + str( gossipTime ) +
                         " seconds for all intents to appear in each node" )
-        # FIXME: make this time configurable/calculate based off of number of
-        #        nodes and gossip rounds
+        gossipPeriod = int( main.params['timers']['gossip'] )
+        maxGossipTime = gossipPeriod * len( main.activeNodes )
         utilities.assert_greater_equals(
-                expect=40, actual=gossipTime,
+                expect=maxGossipTime, actual=gossipTime,
                 onpass="ECM anti-entropy for intents worked within " +
                        "expected time",
-                onfail="Intent ECM anti-entropy took too long" )
-        if gossipTime <= 40:
+                onfail="Intent ECM anti-entropy took too long. " +
+                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
+                                                                  gossipTime ) )
+        if gossipTime <= maxGossipTime:
             intentAddResult = True
 
         if not intentAddResult or "key" in pendingMap:
@@ -764,11 +787,11 @@
             installedCheck = True
             main.log.info( "Sleeping 60 seconds to see if intents are found" )
             time.sleep( 60 )
-            onosIds = main.ONOScli1.getAllIntentsId()
+            onosIds = onosCli.getAllIntentsId()
             main.log.info( "Submitted intents: " + str( intentIds ) )
             main.log.info( "Intents in ONOS: " + str( onosIds ) )
             # Print the intent states
-            intents = main.ONOScli1.intents()
+            intents = onosCli.intents()
             intentStates = []
             main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
             count = 0
@@ -792,7 +815,7 @@
                 count += 1
                 main.log.info( "%-6s%-15s%-15s" %
                                ( str( count ), str( i ), str( s ) ) )
-            leaders = main.ONOScli1.leaders()
+            leaders = onosCli.leaders()
             try:
                 missing = False
                 if leaders:
@@ -822,12 +845,13 @@
                 main.log.error( repr( leaders ) )
             # Check all nodes
             if missing:
-                for node in main.CLIs:
+                for i in main.activeNodes:
+                    node = main.CLIs[i]
                     response = node.leaders( jsonFormat=False)
                     main.log.warn( str( node.name ) + " leaders output: \n" +
                                    str( response ) )
 
-            partitions = main.ONOScli1.partitions()
+            partitions = onosCli.partitions()
             try:
                 if partitions :
                     parsedPartitions = json.loads( partitions )
@@ -842,7 +866,7 @@
             except ( ValueError, TypeError ):
                 main.log.exception( "Error parsing partitions" )
                 main.log.error( repr( partitions ) )
-            pendingMap = main.ONOScli1.pendingMap()
+            pendingMap = onosCli.pendingMap()
             try:
                 if pendingMap :
                     parsedPending = json.loads( pendingMap )
@@ -868,11 +892,12 @@
         assert utilities.assert_equals, "utilities.assert_equals not defined"
         assert main.CLIs, "main.CLIs not defined"
         assert main.nodes, "main.nodes not defined"
-        main.case( "Verify connectivity by sendind traffic across Intents" )
+        main.case( "Verify connectivity by sending traffic across Intents" )
         main.caseExplanation = "Ping across added host intents to check " +\
                                 "functionality and check the state of " +\
                                 "the intent"
         main.step( "Ping across added host intents" )
+        onosCli = main.CLIs[ main.activeNodes[0] ]
         PingResult = main.TRUE
         for i in range( 8, 18 ):
             ping = main.Mininet1.pingHost( src="h" + str( i ),
@@ -890,7 +915,7 @@
             # TODO: pretty print
             main.log.warn( "ONOS1 intents: " )
             try:
-                tmpIntents = main.ONOScli1.intents()
+                tmpIntents = onosCli.intents()
                 main.log.warn( json.dumps( json.loads( tmpIntents ),
                                            sort_keys=True,
                                            indent=4,
@@ -909,7 +934,7 @@
         while not installedCheck and loopCount < 40:
             installedCheck = True
             # Print the intent states
-            intents = main.ONOScli1.intents()
+            intents = onosCli.intents()
             intentStates = []
             main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
             count = 0
@@ -938,7 +963,7 @@
                                         "INSTALLED state" )
 
         main.step( "Check leadership of topics" )
-        leaders = main.ONOScli1.leaders()
+        leaders = onosCli.leaders()
         topicCheck = main.TRUE
         try:
             if leaders:
@@ -973,7 +998,8 @@
             # TODO: Check for a leader of these topics
         # Check all nodes
         if topicCheck:
-            for node in main.CLIs:
+            for i in main.activeNodes:
+                node = main.CLIs[i]
                 response = node.leaders( jsonFormat=False)
                 main.log.warn( str( node.name ) + " leaders output: \n" +
                                str( response ) )
@@ -982,7 +1008,7 @@
                                  onpass="intent Partitions is in leaders",
                                  onfail="Some topics were lost " )
         # Print partitions
-        partitions = main.ONOScli1.partitions()
+        partitions = onosCli.partitions()
         try:
             if partitions :
                 parsedPartitions = json.loads( partitions )
@@ -998,7 +1024,7 @@
             main.log.exception( "Error parsing partitions" )
             main.log.error( repr( partitions ) )
         # Print Pending Map
-        pendingMap = main.ONOScli1.pendingMap()
+        pendingMap = onosCli.pendingMap()
         try:
             if pendingMap :
                 parsedPending = json.loads( pendingMap )
@@ -1018,7 +1044,7 @@
                            "intents change" )
             time.sleep( 60 )
             # Print the intent states
-            intents = main.ONOScli1.intents()
+            intents = onosCli.intents()
             intentStates = []
             main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
             count = 0
@@ -1037,7 +1063,7 @@
                 count += 1
                 main.log.info( "%-6s%-15s%-15s" %
                                ( str( count ), str( i ), str( s ) ) )
-            leaders = main.ONOScli1.leaders()
+            leaders = onosCli.leaders()
             try:
                 missing = False
                 if leaders:
@@ -1066,12 +1092,13 @@
                 main.log.exception( "Error parsing leaders" )
                 main.log.error( repr( leaders ) )
             if missing:
-                for node in main.CLIs:
+                for i in main.activeNodes:
+                    node = main.CLIs[i]
                     response = node.leaders( jsonFormat=False)
                     main.log.warn( str( node.name ) + " leaders output: \n" +
                                    str( response ) )
 
-            partitions = main.ONOScli1.partitions()
+            partitions = onosCli.partitions()
             try:
                 if partitions :
                     parsedPartitions = json.loads( partitions )
@@ -1086,7 +1113,7 @@
             except ( ValueError, TypeError ):
                 main.log.exception( "Error parsing partitions" )
                 main.log.error( repr( partitions ) )
-            pendingMap = main.ONOScli1.pendingMap()
+            pendingMap = onosCli.pendingMap()
             try:
                 if pendingMap :
                     parsedPending = json.loads( pendingMap )
@@ -1101,7 +1128,8 @@
                 main.log.exception( "Error parsing pending map" )
                 main.log.error( repr( pendingMap ) )
         # Print flowrules
-        main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
+        node = main.activeNodes[0]
+        main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
         main.step( "Wait a minute then ping again" )
         # the wait is above
         PingResult = main.TRUE
@@ -1121,7 +1149,7 @@
             # TODO: pretty print
             main.log.warn( "ONOS1 intents: " )
             try:
-                tmpIntents = main.ONOScli1.intents()
+                tmpIntents = onosCli.intents()
                 main.log.warn( json.dumps( json.loads( tmpIntents ),
                                            sort_keys=True,
                                            indent=4,
@@ -1158,7 +1186,7 @@
         # Assert that each device has a master
         rolesNotNull = main.TRUE
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].rolesNotNull,
                              name="rolesNotNull-" + str( i ),
                              args=[] )
@@ -1180,7 +1208,7 @@
         consistentMastership = True
         rolesResults = True
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].roles,
                              name="roles-" + str( i ),
                              args=[] )
@@ -1191,13 +1219,12 @@
             t.join()
             ONOSMastership.append( t.result )
 
-        for i in range( main.numCtrls ):
+        for i in range( len( ONOSMastership ) ):
+            node = str( main.activeNodes[i] + 1 )
             if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
-                main.log.error( "Error in getting ONOS" + str( i + 1 ) +
-                                 " roles" )
-                main.log.warn(
-                    "ONOS" + str( i + 1 ) + " mastership response: " +
-                    repr( ONOSMastership[i] ) )
+                main.log.error( "Error in getting ONOS" + node + " roles" )
+                main.log.warn( "ONOS" + node + " mastership response: " +
+                               repr( ONOSMastership[i] ) )
                 rolesResults = False
         utilities.assert_equals(
             expect=True,
@@ -1218,10 +1245,11 @@
             onfail="ONOS nodes have different views of switch roles" )
 
         if rolesResults and not consistentMastership:
-            for i in range( main.numCtrls ):
+            for i in range( len( main.activeNodes ) ):
+                node = str( main.activeNodes[i] + 1 )
                 try:
                     main.log.warn(
-                        "ONOS" + str( i + 1 ) + " roles: ",
+                        "ONOS" + node + " roles: ",
                         json.dumps(
                             json.loads( ONOSMastership[ i ] ),
                             sort_keys=True,
@@ -1241,7 +1269,7 @@
         consistentIntents = True
         intentsResults = True
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].intents,
                              name="intents-" + str( i ),
                              args=[],
@@ -1253,11 +1281,11 @@
             t.join()
             ONOSIntents.append( t.result )
 
-        for i in range( main.numCtrls ):
+        for i in range( len( ONOSIntents ) ):
+            node = str( main.activeNodes[i] + 1 )
             if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + str( i + 1 ) +
-                                 " intents" )
-                main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
+                main.log.error( "Error in getting ONOS" + node + " intents" )
+                main.log.warn( "ONOS" + node + " intents response: " +
                                repr( ONOSIntents[ i ] ) )
                 intentsResults = False
         utilities.assert_equals(
@@ -1287,7 +1315,7 @@
             #  ...        ...         ...
             #  ...        ...         ...
             title = "   Id"
-            for n in range( main.numCtrls ):
+            for n in main.activeNodes:
                 title += " " * 10 + "ONOS" + str( n + 1 )
             main.log.warn( title )
             # get all intent keys in the cluster
@@ -1309,22 +1337,23 @@
 
         if intentsResults and not consistentIntents:
             # print the json objects
-            n = len(ONOSIntents)
-            main.log.debug( "ONOS" + str( n ) + " intents: " )
+            n = str( main.activeNodes[-1] + 1 )
+            main.log.debug( "ONOS" + n + " intents: " )
             main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
                                         sort_keys=True,
                                         indent=4,
                                         separators=( ',', ': ' ) ) )
-            for i in range( main.numCtrls ):
+            for i in range( len( ONOSIntents ) ):
+                node = str( main.activeNodes[i] + 1 )
                 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
-                    main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
+                    main.log.debug( "ONOS" + node + " intents: " )
                     main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
                                                 sort_keys=True,
                                                 indent=4,
                                                 separators=( ',', ': ' ) ) )
                 else:
-                    main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
-                                    str( n ) + " intents" )
+                    main.log.debug( "ONOS" + node + " intents match ONOS" +
+                                    n + " intents" )
         elif intentsResults and consistentIntents:
             intentCheck = main.TRUE
             intentState = ONOSIntents[ 0 ]
@@ -1338,7 +1367,7 @@
         consistentFlows = True
         flowsResults = True
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].flows,
                              name="flows-" + str( i ),
                              args=[],
@@ -1353,8 +1382,8 @@
             result = t.result
             ONOSFlows.append( result )
 
-        for i in range( main.numCtrls ):
-            num = str( i + 1 )
+        for i in range( len( ONOSFlows ) ):
+            num = str( main.activeNodes[i] + 1 )
             if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
                 main.log.error( "Error in getting ONOS" + num + " flows" )
                 main.log.warn( "ONOS" + num + " flows response: " +
@@ -1390,16 +1419,16 @@
             onfail="ONOS nodes have different flow counts" )
 
         if flowsResults and not consistentFlows:
-            for i in range( main.numCtrls ):
+            for i in range( len( ONOSFlows ) ):
+                node = str( main.activeNodes[i] + 1 )
                 try:
                     main.log.warn(
-                        "ONOS" + str( i + 1 ) + " flows: " +
+                        "ONOS" + node + " flows: " +
                         json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
                                     indent=4, separators=( ',', ': ' ) ) )
                 except ( ValueError, TypeError ):
-                    main.log.warn(
-                        "ONOS" + str( i + 1 ) + " flows: " +
-                        repr( ONOSFlows[ i ] ) )
+                    main.log.warn( "ONOS" + node + " flows: " +
+                                   repr( ONOSFlows[ i ] ) )
         elif flowsResults and consistentFlows:
             flowCheck = main.TRUE
             flowState = ONOSFlows[ 0 ]
@@ -1459,7 +1488,7 @@
         main.step( "Collecting topology information from ONOS" )
         devices = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].devices,
                              name="devices-" + str( i ),
                              args=[ ] )
@@ -1471,7 +1500,7 @@
             devices.append( t.result )
         hosts = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].hosts,
                              name="hosts-" + str( i ),
                              args=[ ] )
@@ -1491,7 +1520,7 @@
 
         ports = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].ports,
                              name="ports-" + str( i ),
                              args=[ ] )
@@ -1503,7 +1532,7 @@
             ports.append( t.result )
         links = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].links,
                              name="links-" + str( i ),
                              args=[ ] )
@@ -1515,7 +1544,7 @@
             links.append( t.result )
         clusters = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].clusters,
                              name="clusters-" + str( i ),
                              args=[ ] )
@@ -1531,7 +1560,7 @@
         main.step( "Host view is consistent across ONOS nodes" )
         consistentHostsResult = main.TRUE
         for controller in range( len( hosts ) ):
-            controllerStr = str( controller + 1 )
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if "Error" not in hosts[ controller ]:
                 if hosts[ controller ] == hosts[ 0 ]:
                     continue
@@ -1558,10 +1587,10 @@
         main.step( "Each host has an IP address" )
         ipResult = main.TRUE
         for controller in range( 0, len( hosts ) ):
-            controllerStr = str( controller + 1 )
+            controllerStr = str( main.activeNodes[controller] + 1 )
             for host in hosts[ controller ]:
                 if not host.get( 'ipAddresses', [ ] ):
-                    main.log.error( "DEBUG:Error with host ips on controller" +
+                    main.log.error( "Error with host ips on controller" +
                                     controllerStr + ": " + str( host ) )
                     ipResult = main.FALSE
         utilities.assert_equals(
@@ -1574,7 +1603,7 @@
         main.step( "Cluster view is consistent across ONOS nodes" )
         consistentClustersResult = main.TRUE
         for controller in range( len( clusters ) ):
-            controllerStr = str( controller + 1 )
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if "Error" not in clusters[ controller ]:
                 if clusters[ controller ] == clusters[ 0 ]:
                     continue
@@ -1618,8 +1647,8 @@
         mnSwitches = main.Mininet1.getSwitches()
         mnLinks = main.Mininet1.getLinks()
         mnHosts = main.Mininet1.getHosts()
-        for controller in range( main.numCtrls ):
-            controllerStr = str( controller + 1 )
+        for controller in main.activeNodes:
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if devices[ controller ] and ports[ controller ] and\
                 "Error" not in devices[ controller ] and\
                 "Error" not in ports[ controller ]:
@@ -1687,17 +1716,16 @@
             onpass="Hosts are correct",
             onfail="Hosts are incorrect" )
 
-    def CASE6( self, main ):
+    def CASE61( self, main ):
         """
         The Failure case.
         """
-        import time
         assert main.numCtrls, "main.numCtrls not defined"
         assert main, "main not defined"
         assert utilities.assert_equals, "utilities.assert_equals not defined"
         assert main.CLIs, "main.CLIs not defined"
         assert main.nodes, "main.nodes not defined"
-        main.case( "Restart minority of ONOS nodes" )
+        main.case( "Kill minority of ONOS nodes" )
 
         main.step( "Checking ONOS Logs for errors" )
         for node in main.nodes:
@@ -1711,15 +1739,38 @@
             main.kill.append( p - 1 )
             # NOTE: This only works for cluster sizes of 3,5, or 7.
 
-        main.step( "Killing " + str( len( main.kill ) ) + " ONOS nodes" )
-        killTime = time.time()
+        main.step( "Kill " + str( len( main.kill ) ) + " ONOS nodes" )
         killResults = main.TRUE
         for i in main.kill:
             killResults = killResults and\
                           main.ONOSbench.onosKill( main.nodes[i].ip_address )
+            main.activeNodes.remove( i )
         utilities.assert_equals( expect=main.TRUE, actual=killResults,
-                                 onpass="ONOS Killed successfully",
-                                 onfail="ONOS kill NOT successful" )
+                                 onpass="ONOS nodes killed successfully",
+                                 onfail="ONOS nodes NOT successfully killed" )
+
+    def CASE62( self, main ):
+        """
+        The bring up stopped nodes
+        """
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+        assert main.kill, "main.kill not defined"
+        main.case( "Restart minority of ONOS nodes" )
+
+        main.step( "Restarting " + str( len( main.kill ) ) + " ONOS nodes" )
+        startResults = main.TRUE
+        restartTime = time.time()
+        for i in main.kill:
+            startResults = startResults and\
+                           main.ONOSbench.onosStart( main.nodes[i].ip_address )
+        utilities.assert_equals( expect=main.TRUE, actual=startResults,
+                                 onpass="ONOS nodes started successfully",
+                                 onfail="ONOS nodes NOT successfully started" )
 
         main.step( "Checking if ONOS is up yet" )
         count = 0
@@ -1739,19 +1790,29 @@
         for i in main.kill:
             cliResults = cliResults and\
                          main.CLIs[i].startOnosCli( main.nodes[i].ip_address )
+            main.activeNodes.append( i )
         utilities.assert_equals( expect=main.TRUE, actual=cliResults,
                                  onpass="ONOS cli restarted",
                                  onfail="ONOS cli did not restart" )
+        main.activeNodes.sort()
+        try:
+            assert list( set( main.activeNodes ) ) == main.activeNodes,\
+                   "List of active nodes has duplicates, this likely indicates something was run out of order"
+        except AssertionError:
+            main.log.exception( "" )
+            main.cleanup()
+            main.exit()
 
         # Grab the time of restart so we chan check how long the gossip
         # protocol has had time to work
-        main.restartTime = time.time() - killTime
+        main.restartTime = time.time() - restartTime
         main.log.debug( "Restart time: " + str( main.restartTime ) )
         # TODO: MAke this configurable. Also, we are breaking the above timer
         time.sleep( 60 )
-        main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
-        main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
-        main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
+        node = main.activeNodes[0]
+        main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
+        main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
+        main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
 
     def CASE7( self, main ):
         """
@@ -1763,13 +1824,18 @@
         assert utilities.assert_equals, "utilities.assert_equals not defined"
         assert main.CLIs, "main.CLIs not defined"
         assert main.nodes, "main.nodes not defined"
+        try:
+            main.kill
+        except AttributeError:
+            main.kill = []
+
         main.case( "Running ONOS Constant State Tests" )
 
         main.step( "Check that each switch has a master" )
         # Assert that each device has a master
         rolesNotNull = main.TRUE
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].rolesNotNull,
                              name="rolesNotNull-" + str( i ),
                              args=[ ] )
@@ -1790,7 +1856,7 @@
         consistentMastership = True
         rolesResults = True
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].roles,
                              name="roles-" + str( i ),
                              args=[] )
@@ -1801,13 +1867,12 @@
             t.join()
             ONOSMastership.append( t.result )
 
-        for i in range( main.numCtrls ):
+        for i in range( len( ONOSMastership ) ):
+            node = str( main.activeNodes[i] + 1 )
             if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
-                main.log.error( "Error in getting ONOS" + str( i + 1 ) +
-                                 " roles" )
-                main.log.warn(
-                    "ONOS" + str( i + 1 ) + " mastership response: " +
-                    repr( ONOSMastership[i] ) )
+                main.log.error( "Error in getting ONOS" + node + " roles" )
+                main.log.warn( "ONOS" + node + " mastership response: " +
+                               repr( ONOSMastership[i] ) )
                 rolesResults = False
         utilities.assert_equals(
             expect=True,
@@ -1828,48 +1893,15 @@
             onfail="ONOS nodes have different views of switch roles" )
 
         if rolesResults and not consistentMastership:
-            for i in range( main.numCtrls ):
-                main.log.warn(
-                    "ONOS" + str( i + 1 ) + " roles: ",
-                    json.dumps(
-                        json.loads( ONOSMastership[ i ] ),
-                        sort_keys=True,
-                        indent=4,
-                        separators=( ',', ': ' ) ) )
+            for i in range( len( ONOSMastership ) ):
+                node = str( main.activeNodes[i] + 1 )
+                main.log.warn( "ONOS" + node + " roles: ",
+                               json.dumps( json.loads( ONOSMastership[ i ] ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
 
         # NOTE: we expect mastership to change on controller failure
-        '''
-        description2 = "Compare switch roles from before failure"
-        main.step( description2 )
-        try:
-            currentJson = json.loads( ONOSMastership[0] )
-            oldJson = json.loads( mastershipState )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Something is wrong with parsing " +
-                                "ONOSMastership[0] or mastershipState" )
-            main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
-            main.log.error( "mastershipState" + repr( mastershipState ) )
-            main.cleanup()
-            main.exit()
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            switchDPID = str(
-                main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
-            current = [ switch[ 'master' ] for switch in currentJson
-                        if switchDPID in switch[ 'id' ] ]
-            old = [ switch[ 'master' ] for switch in oldJson
-                    if switchDPID in switch[ 'id' ] ]
-            if current == old:
-                mastershipCheck = mastershipCheck and main.TRUE
-            else:
-                main.log.warn( "Mastership of switch %s changed" % switchDPID )
-                mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Mastership of Switches was not changed",
-            onfail="Mastership of some switches changed" )
-        '''
 
         main.step( "Get the intents and compare across all nodes" )
         ONOSIntents = []
@@ -1877,7 +1909,7 @@
         consistentIntents = True
         intentsResults = True
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].intents,
                              name="intents-" + str( i ),
                              args=[],
@@ -1889,11 +1921,11 @@
             t.join()
             ONOSIntents.append( t.result )
 
-        for i in range( main.numCtrls ):
+        for i in range( len( ONOSIntents) ):
+            node = str( main.activeNodes[i] + 1 )
             if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + str( i + 1 ) +
-                                 " intents" )
-                main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
+                main.log.error( "Error in getting ONOS" + node + " intents" )
+                main.log.warn( "ONOS" + node + " intents response: " +
                                repr( ONOSIntents[ i ] ) )
                 intentsResults = False
         utilities.assert_equals(
@@ -1916,7 +1948,7 @@
         #  ...        ...         ...
         #  ...        ...         ...
         title = "   ID"
-        for n in range( main.numCtrls ):
+        for n in main.activeNodes:
             title += " " * 10 + "ONOS" + str( n + 1 )
         main.log.warn( title )
         # get all intent keys in the cluster
@@ -1956,8 +1988,9 @@
             main.log.info( dict( out ) )
 
         if intentsResults and not consistentIntents:
-            for i in range( main.numCtrls ):
-                main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
+            for i in range( len( main.activeNodes ) ):
+                node = str( main.activeNodes[i] + 1 )
+                main.log.warn( "ONOS" + node + " intents: " )
                 main.log.warn( json.dumps(
                     json.loads( ONOSIntents[ i ] ),
                     sort_keys=True,
@@ -2072,7 +2105,8 @@
             restarted.append( main.nodes[i].ip_address )
         leaderResult = main.TRUE
 
-        for cli in main.CLIs:
+        for i in main.activeNodes:
+            cli = main.CLIs[i]
             leaderN = cli.electionTestLeader()
             leaderList.append( leaderN )
             if leaderN == main.FALSE:
@@ -2134,7 +2168,7 @@
             cliStart = time.time()
             devices = []
             threads = []
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].devices,
                                  name="devices-" + str( i ),
                                  args=[ ] )
@@ -2147,7 +2181,7 @@
             hosts = []
             ipResult = main.TRUE
             threads = []
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].hosts,
                                  name="hosts-" + str( i ),
                                  args=[ ] )
@@ -2162,7 +2196,7 @@
                     main.log.exception( "Error parsing hosts results" )
                     main.log.error( repr( t.result ) )
             for controller in range( 0, len( hosts ) ):
-                controllerStr = str( controller + 1 )
+                controllerStr = str( main.activeNodes[controller] + 1 )
                 for host in hosts[ controller ]:
                     if host is None or host.get( 'ipAddresses', [] ) == []:
                         main.log.error(
@@ -2171,7 +2205,7 @@
                         ipResult = main.FALSE
             ports = []
             threads = []
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].ports,
                                  name="ports-" + str( i ),
                                  args=[ ] )
@@ -2183,7 +2217,7 @@
                 ports.append( t.result )
             links = []
             threads = []
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].links,
                                  name="links-" + str( i ),
                                  args=[ ] )
@@ -2195,7 +2229,7 @@
                 links.append( t.result )
             clusters = []
             threads = []
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].clusters,
                                  name="clusters-" + str( i ),
                                  args=[ ] )
@@ -2214,8 +2248,8 @@
             mnSwitches = main.Mininet1.getSwitches()
             mnLinks = main.Mininet1.getLinks()
             mnHosts = main.Mininet1.getHosts()
-            for controller in range( main.numCtrls ):
-                controllerStr = str( controller + 1 )
+            for controller in range( len( main.activeNodes ) ):
+                controllerStr = str( main.activeNodes[controller] + 1 )
                 if devices[ controller ] and ports[ controller ] and\
                     "Error" not in devices[ controller ] and\
                     "Error" not in ports[ controller ]:
@@ -2353,7 +2387,7 @@
         main.step( "Hosts view is consistent across all ONOS nodes" )
         consistentHostsResult = main.TRUE
         for controller in range( len( hosts ) ):
-            controllerStr = str( controller + 1 )
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if "Error" not in hosts[ controller ]:
                 if hosts[ controller ] == hosts[ 0 ]:
                     continue
@@ -2395,7 +2429,7 @@
         main.step( "Clusters view is consistent across all ONOS nodes" )
         consistentClustersResult = main.TRUE
         for controller in range( len( clusters ) ):
-            controllerStr = str( controller + 1 )
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if "Error" not in clusters[ controller ]:
                 if clusters[ controller ] == clusters[ 0 ]:
                     continue
@@ -2467,7 +2501,7 @@
         nodesOutput = []
         nodeResults = main.TRUE
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].nodes,
                              name="nodes-" + str( i ),
                              args=[ ] )
@@ -2477,7 +2511,7 @@
         for t in threads:
             t.join()
             nodesOutput.append( t.result )
-        ips = [ node.ip_address for node in main.nodes ]
+        ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
         for i in nodesOutput:
             try:
                 current = json.loads( i )
@@ -2573,6 +2607,7 @@
         switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
 
         description = "Killing a switch to ensure it is discovered correctly"
+        onosCli = main.CLIs[ main.activeNodes[0] ]
         main.case( description )
         switch = main.params[ 'kill' ][ 'switch' ]
         switchDPID = main.params[ 'kill' ][ 'dpid' ]
@@ -2584,7 +2619,7 @@
         main.log.info( "Waiting " + str( switchSleep ) +
                        " seconds for switch down to be discovered" )
         time.sleep( switchSleep )
-        device = main.ONOScli1.getDevice( dpid=switchDPID )
+        device = onosCli.getDevice( dpid=switchDPID )
         # Peek at the deleted switch
         main.log.warn( str( device ) )
         result = main.FALSE
@@ -2617,6 +2652,7 @@
         switch = main.params[ 'kill' ][ 'switch' ]
         switchDPID = main.params[ 'kill' ][ 'dpid' ]
         links = main.params[ 'kill' ][ 'links' ].split()
+        onosCli = main.CLIs[ main.activeNodes[0] ]
         description = "Adding a switch to ensure it is discovered correctly"
         main.case( description )
 
@@ -2624,14 +2660,12 @@
         main.Mininet1.addSwitch( switch, dpid=switchDPID )
         for peer in links:
             main.Mininet1.addLink( switch, peer )
-        ipList = []
-        for i in range( main.numCtrls ):
-            ipList.append( main.nodes[ i ].ip_address )
+        ipList = [ node.ip_address for node in main.nodes ]
         main.Mininet1.assignSwController( sw=switch, ip=ipList )
         main.log.info( "Waiting " + str( switchSleep ) +
                        " seconds for switch up to be discovered" )
         time.sleep( switchSleep )
-        device = main.ONOScli1.getDevice( dpid=switchDPID )
+        device = onosCli.getDevice( dpid=switchDPID )
         # Peek at the deleted switch
         main.log.warn( str( device ) )
         result = main.FALSE
@@ -2677,7 +2711,7 @@
             # NOTE: must end in /
             for f in logFiles:
                 for node in main.nodes:
-                    dstName =  main.logdir + "/" + node.name + "-" + f
+                    dstName = main.logdir + "/" + node.name + "-" + f
                     main.ONOSbench.secureCopy( node.user_name, node.ip_address,
                                                logFolder + f, dstName )
             # std*.log's
@@ -2687,7 +2721,7 @@
             # NOTE: must end in /
             for f in logFiles:
                 for node in main.nodes:
-                    dstName =  main.logdir + "/" + node.name + "-" + f
+                    dstName = main.logdir + "/" + node.name + "-" + f
                     main.ONOSbench.secureCopy( node.user_name, node.ip_address,
                                                logFolder + f, dstName )
         else:
@@ -2726,7 +2760,8 @@
 
         main.case("Start Leadership Election app")
         main.step( "Install leadership election app" )
-        appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
+        onosCli = main.CLIs[ main.activeNodes[0] ]
+        appResult = onosCli.activateApp( "org.onosproject.election" )
         utilities.assert_equals(
             expect=main.TRUE,
             actual=appResult,
@@ -2736,9 +2771,10 @@
         main.step( "Run for election on each node" )
         leaderResult = main.TRUE
         leaders = []
-        for cli in main.CLIs:
-            cli.electionTestRun()
-        for cli in main.CLIs:
+        for i in main.activeNodes:
+            main.CLIs[i].electionTestRun()
+        for i in main.activeNodes:
+            cli = main.CLIs[i]
             leader = cli.electionTestLeader()
             if leader is None or leader == main.FALSE:
                 main.log.error( cli.name + ": Leader for the election app " +
@@ -2808,10 +2844,9 @@
         main.step( "Run for election on each node" )
         electionResult = main.TRUE
 
-        for cli in main.CLIs:  # run test election on each node
-            if cli.electionTestRun() == main.FALSE:
+        for i in main.activeNodes:  # run test election on each node
+            if main.CLIs[i].electionTestRun() == main.FALSE:
                 electionResult = main.FALSE
-
         utilities.assert_equals(
             expect=main.TRUE,
             actual=electionResult,
@@ -2826,7 +2861,8 @@
         main.step( "Check that each node shows the same leader and candidates" )
         sameResult = main.TRUE
         failMessage = "Nodes have different leaders"
-        for cli in main.CLIs:
+        for i in main.activeNodes:
+            cli = main.CLIs[i]
             node = cli.specificLeaderCandidate( 'org.onosproject.election' )
             oldAllCandidates.append( node )
             oldLeaders.append( node[ 0 ] )
@@ -2845,7 +2881,6 @@
             if set( candidates ) != set( oldCandidates ):
                 sameResult = main.FALSE
                 failMessage += "and candidates"
-
         utilities.assert_equals(
             expect=main.TRUE,
             actual=sameResult,
@@ -2859,7 +2894,7 @@
             main.log.error( "Leadership isn't consistent." )
             withdrawResult = main.FALSE
         # Get the CLI of the oldLeader
-        for i in range( len( main.CLIs ) ):
+        for i in main.activeNodes:
             if oldLeader == main.nodes[ i ].ip_address:
                 oldLeaderCLI = main.CLIs[ i ]
                 break
@@ -2880,7 +2915,8 @@
         failMessage = "Nodes have different leaders"
 
         # Get new leaders and candidates
-        for cli in main.CLIs:
+        for i in main.activeNodes:
+            cli = main.CLIs[i]
             node = cli.specificLeaderCandidate( 'org.onosproject.election' )
             # elections might no have finished yet
             if node[ 0 ] == 'none' and not expectNoLeader:
@@ -2966,7 +3002,8 @@
         newAllCandidates = []
         newCandidates = []
         newLeaders = []
-        for cli in main.CLIs:
+        for i in main.activeNodes:
+            cli = main.CLIs[i]
             node = cli.specificLeaderCandidate( 'org.onosproject.election' )
             if oldLeader not in node:  # election might no have finished yet
                 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
@@ -2998,7 +3035,7 @@
 
         # Check that the re-elected node is last on the candidate List
         if oldLeader != newCandidates[ -1 ]:
-            main.log.error( "Old Leader ("  + oldLeader + ") not in the proper position " +
+            main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
                 str( newCandidates ) )
             positionResult = main.FALSE
 
@@ -3038,7 +3075,8 @@
         main.case( description )
         main.step( "Install Primitives app" )
         appName = "org.onosproject.distributedprimitives"
-        appResults = main.CLIs[0].activateApp( appName )
+        node = main.activeNodes[0]
+        appResults = main.CLIs[node].activateApp( appName )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=appResults,
                                  onpass="Primitives app activated",
@@ -3090,7 +3128,7 @@
         pCounters = []
         threads = []
         addedPValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="counterAddAndGet-" + str( i ),
                              args=[ pCounterName ] )
@@ -3120,7 +3158,7 @@
         pCounters = []
         threads = []
         addedPValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
                              name="counterGetAndAdd-" + str( i ),
                              args=[ pCounterName ] )
@@ -3157,7 +3195,7 @@
         pCounters = []
         threads = []
         addedPValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="counterIncrement-" + str( i ),
                              args=[ pCounterName ],
@@ -3188,7 +3226,7 @@
         pCounters = []
         threads = []
         addedPValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="counterIncrement-" + str( i ),
                              args=[ pCounterName ],
@@ -3219,7 +3257,7 @@
         pCounters = []
         threads = []
         addedPValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
                              name="counterIncrement-" + str( i ),
                              args=[ pCounterName ],
@@ -3258,7 +3296,7 @@
         iCounters = []
         addedIValues = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="icounterIncrement-" + str( i ),
                              args=[ iCounterName ],
@@ -3289,7 +3327,7 @@
         iCounters = []
         threads = []
         addedIValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
                              name="counterGetAndAdd-" + str( i ),
                              args=[ iCounterName ],
@@ -3327,7 +3365,7 @@
         iCounters = []
         threads = []
         addedIValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="counterIncrement-" + str( i ),
                              args=[ iCounterName ],
@@ -3358,7 +3396,7 @@
         iCounters = []
         threads = []
         addedIValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="counterIncrement-" + str( i ),
                              args=[ iCounterName ],
@@ -3389,7 +3427,7 @@
         iCounters = []
         threads = []
         addedIValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
                              name="counterIncrement-" + str( i ),
                              args=[ iCounterName ],
@@ -3445,7 +3483,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3456,13 +3494,14 @@
             getResponses.append( t.result )
 
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -3471,7 +3510,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -3486,7 +3525,7 @@
         main.step( "Distributed Set size" )
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -3497,10 +3536,11 @@
             sizeResponses.append( t.result )
 
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -3513,7 +3553,7 @@
         onosSet.add( addValue )
         addResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestAdd,
                              name="setTestAdd-" + str( i ),
                              args=[ onosSetName, addValue ] )
@@ -3527,7 +3567,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         addResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if addResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -3547,7 +3587,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3557,14 +3597,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
-                                        " has incorrect view" +
+                        main.log.error( "ONOS" + node + " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
                         main.log.debug( "Expected: " + str( onosSet ) )
@@ -3572,8 +3612,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
-                                    " has repeat elements in" +
+                    main.log.error( "ONOS" + node + " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
                     getResults = main.FALSE
@@ -3581,7 +3620,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -3591,10 +3630,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -3608,7 +3648,7 @@
         onosSet.update( addAllValue.split() )
         addResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestAdd,
                              name="setTestAddAll-" + str( i ),
                              args=[ onosSetName, addAllValue ] )
@@ -3622,7 +3662,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         addAllResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if addResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -3642,7 +3682,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3652,13 +3692,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -3667,7 +3708,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -3676,7 +3717,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -3686,10 +3727,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -3702,7 +3744,7 @@
         main.step( "Distributed Set contains()" )
         containsResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setContains-" + str( i ),
                              args=[ onosSetName ],
@@ -3715,7 +3757,7 @@
             containsResponses.append( t.result )
 
         containsResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if containsResponses[ i ] == main.ERROR:
                 containsResults = main.FALSE
             else:
@@ -3729,7 +3771,7 @@
         main.step( "Distributed Set containsAll()" )
         containsAllResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setContainsAll-" + str( i ),
                              args=[ onosSetName ],
@@ -3742,7 +3784,7 @@
             containsAllResponses.append( t.result )
 
         containsAllResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if containsResponses[ i ] == main.ERROR:
                 containsResults = main.FALSE
             else:
@@ -3757,7 +3799,7 @@
         onosSet.remove( addValue )
         removeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestRemove,
                              name="setTestRemove-" + str( i ),
                              args=[ onosSetName, addValue ] )
@@ -3771,7 +3813,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         removeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if removeResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -3791,7 +3833,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3801,13 +3843,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -3816,7 +3859,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -3825,7 +3868,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -3835,10 +3878,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -3853,7 +3897,7 @@
         removeAllResponses = []
         threads = []
         try:
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].setTestRemove,
                                  name="setTestRemoveAll-" + str( i ),
                                  args=[ onosSetName, addAllValue ] )
@@ -3869,7 +3913,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         removeAllResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if removeAllResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -3889,7 +3933,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3899,13 +3943,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -3914,7 +3959,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -3923,7 +3968,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -3933,10 +3978,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -3950,7 +3996,7 @@
         onosSet.update( addAllValue.split() )
         addResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestAdd,
                              name="setTestAddAll-" + str( i ),
                              args=[ onosSetName, addAllValue ] )
@@ -3964,7 +4010,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         addAllResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if addResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -3984,7 +4030,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3994,13 +4040,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -4009,7 +4056,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -4018,7 +4065,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -4028,10 +4075,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -4045,7 +4093,7 @@
         onosSet.clear()
         clearResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestRemove,
                              name="setTestClear-" + str( i ),
                              args=[ onosSetName, " "],  # Values doesn't matter
@@ -4060,7 +4108,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         clearResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if clearResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -4080,7 +4128,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -4090,13 +4138,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -4105,7 +4154,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -4114,7 +4163,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -4124,10 +4173,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -4141,7 +4191,7 @@
         onosSet.update( addAllValue.split() )
         addResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestAdd,
                              name="setTestAddAll-" + str( i ),
                              args=[ onosSetName, addAllValue ] )
@@ -4155,7 +4205,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         addAllResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if addResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -4175,7 +4225,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -4185,13 +4235,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -4200,7 +4251,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -4209,7 +4260,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -4219,10 +4270,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -4236,7 +4288,7 @@
         onosSet.intersection_update( retainValue.split() )
         retainResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestRemove,
                              name="setTestRetain-" + str( i ),
                              args=[ onosSetName, retainValue ],
@@ -4251,7 +4303,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         retainResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if retainResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -4271,7 +4323,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -4281,13 +4333,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -4296,7 +4349,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -4305,7 +4358,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -4315,11 +4368,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
-                                " expected a size of " +
+                main.log.error( "ONOS" + node + " expected a size of " +
                                 str( size ) + " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
         retainResults = retainResults and getResults and sizeResults
@@ -4333,7 +4386,8 @@
         tMapValue = "Testing"
         numKeys = 100
         putResult = True
-        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
+        node = main.activeNodes[0]
+        putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
         if len( putResponses ) == 100:
             for i in putResponses:
                 if putResponses[ i ][ 'value' ] != tMapValue:
@@ -4353,10 +4407,10 @@
             getResponses = []
             threads = []
             valueCheck = True
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
                                  name="TMap-get-" + str( i ),
-                                 args=[ "Key" + str ( n ) ] )
+                                 args=[ "Key" + str( n ) ] )
                 threads.append( t )
                 t.start()
             for t in threads:
@@ -4378,7 +4432,8 @@
         tMapValue = "Testing"
         numKeys = 100
         putResult = True
-        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
+        node = main.activeNodes[0]
+        putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue, inMemory=True )
         if len( putResponses ) == 100:
             for i in putResponses:
                 if putResponses[ i ][ 'value' ] != tMapValue:
@@ -4398,10 +4453,10 @@
             getResponses = []
             threads = []
             valueCheck = True
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
                                  name="TMap-get-" + str( i ),
-                                 args=[ "Key" + str ( n ) ],
+                                 args=[ "Key" + str( n ) ],
                                  kwargs={ "inMemory": True } )
                 threads.append( t )
                 t.start()
diff --git a/TestON/tests/HAminorityRestart/HAminorityRestart.topo b/TestON/tests/HAkillNodes/HAkillNodes.topo
similarity index 100%
rename from TestON/tests/HAminorityRestart/HAminorityRestart.topo
rename to TestON/tests/HAkillNodes/HAkillNodes.topo
diff --git a/TestON/tests/HAminorityRestart/README b/TestON/tests/HAkillNodes/README
similarity index 93%
rename from TestON/tests/HAminorityRestart/README
rename to TestON/tests/HAkillNodes/README
index a913f85..274adfb 100644
--- a/TestON/tests/HAminorityRestart/README
+++ b/TestON/tests/HAkillNodes/README
@@ -19,6 +19,8 @@
     - Distributed Primitives
 - Kill some ONOS nodes
 - Verify ONOS state and functionality
+- Restart ONOS nodes
+- Verify ONOS state and functionality
 - Dataplane failures
     - link down and up
     - switch down and up
diff --git a/TestON/tests/HAminorityRestart/__init__.py b/TestON/tests/HAkillNodes/__init__.py
similarity index 100%
rename from TestON/tests/HAminorityRestart/__init__.py
rename to TestON/tests/HAkillNodes/__init__.py
diff --git a/TestON/tests/HAkillNodes/dependencies/Counters.py b/TestON/tests/HAkillNodes/dependencies/Counters.py
new file mode 100644
index 0000000..455e3e7
--- /dev/null
+++ b/TestON/tests/HAkillNodes/dependencies/Counters.py
@@ -0,0 +1,103 @@
+def __init__( self ):
+    self.default = ''
+
+def consistentCheck():
+    """
+    Checks that TestON counters are consistent across all nodes.
+
+    Returns the tuple (onosCounters, consistent)
+    - onosCounters is the parsed json output of the counters command on all nodes
+    - consistent is main.TRUE if all "TestON" counters are consitent across all
+        nodes or main.FALSE
+    """
+    import json
+    try:
+        correctResults = main.TRUE
+        # Get onos counters results
+        onosCountersRaw = []
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.CLIs[i].counters,
+                             name="counters-" + str( i ) )
+            threads.append( t )
+            t.start()
+        for t in threads:
+            t.join()
+            onosCountersRaw.append( t.result )
+        onosCounters = []
+        for i in range( len( main.activeNodes ) ):
+            try:
+                onosCounters.append( json.loads( onosCountersRaw[i] ) )
+            except ( ValueError, TypeError ):
+                main.log.error( "Could not parse counters response from ONOS" +
+                                str( main.activeNodes[i] + 1 ) )
+                main.log.warn( repr( onosCountersRaw[ i ] ) )
+                return main.FALSE
+
+        testCounters = {}
+        # make a list of all the "TestON-*" counters in ONOS
+        # lookes like a dict whose keys are the name of the ONOS node and values
+        # are a list of the counters. I.E.
+        # { "ONOS1": [ {"name":"TestON-inMemory","value":56},
+        #              {"name":"TestON-Partitions","value":56} ]
+        # }
+        # NOTE: There is an assumtion that all nodes are active
+        #        based on the above for loops
+        for controller in enumerate( onosCounters ):
+            for dbType in controller[1]:
+                for dbName, items in dbType.iteritems():
+                    for item in items:
+                        if 'TestON' in item['name']:
+                            node = 'ONOS' + str( main.activeNodes[ controller[0] ] + 1 )
+                            try:
+                                testCounters[node].append( item )
+                            except KeyError:
+                                testCounters[node] = [ item ]
+        # compare the counters on each node
+        firstV = testCounters.values()[0]
+        tmp = [ v == firstV for k, v in testCounters.iteritems() ]
+        if all( tmp ):
+            consistent = main.TRUE
+        else:
+            consistent = main.FALSE
+            main.log.error( "ONOS nodes have different values for counters:\n" +
+                            testCounters )
+        return ( onosCounters, consistent )
+    except Exception:
+        main.log.exception( "" )
+        main.cleanup()
+        main.exit()
+
+def counterCheck( counterName, counterValue ):
+    """
+    Checks that TestON counters are consistent across all nodes and that
+    specified counter is in ONOS with the given value
+    """
+    import json
+    correctResults = main.TRUE
+    # Get onos counters results and consistentCheck
+    onosCounters, consistent = main.Counters.consistentCheck()
+    # Check for correct values
+    for i in range( len( main.activeNodes ) ):
+        current = onosCounters[i]
+        onosValue = None
+        try:
+            for database in current:
+                database = database.values()[0]
+                for counter in database:
+                    if counter.get( 'name' ) == counterName:
+                        onosValue = counter.get( 'value' )
+                        break
+        except AttributeError, e:
+            node = str( main.activeNodes[i] + 1 )
+            main.log.error( "ONOS" + node + " counters result " +
+                            "is not as expected" )
+            correctResults = main.FALSE
+        if onosValue == counterValue:
+            main.log.info( counterName + " counter value is correct" )
+        else:
+            main.log.error( counterName + " counter value is incorrect," +
+                            " expected value: " + str( counterValue )
+                            + " current value: " + str( onosValue ) )
+            correctResults = main.FALSE
+    return consistent and correctResults
diff --git a/TestON/tests/HAminorityRestart/dependencies/__init__.py b/TestON/tests/HAkillNodes/dependencies/__init__.py
similarity index 100%
rename from TestON/tests/HAminorityRestart/dependencies/__init__.py
rename to TestON/tests/HAkillNodes/dependencies/__init__.py
diff --git a/TestON/tests/HAminorityRestart/dependencies/obelisk.py b/TestON/tests/HAkillNodes/dependencies/obelisk.py
similarity index 99%
rename from TestON/tests/HAminorityRestart/dependencies/obelisk.py
rename to TestON/tests/HAkillNodes/dependencies/obelisk.py
index 4378a9b..d613806 100755
--- a/TestON/tests/HAminorityRestart/dependencies/obelisk.py
+++ b/TestON/tests/HAkillNodes/dependencies/obelisk.py
@@ -67,4 +67,3 @@
 if __name__ == '__main__':
     setLogLevel( 'info' )
     run()
-
diff --git a/TestON/tests/HAminorityRestart/dependencies/onos-gen-partitions b/TestON/tests/HAkillNodes/dependencies/onos-gen-partitions
similarity index 100%
rename from TestON/tests/HAminorityRestart/dependencies/onos-gen-partitions
rename to TestON/tests/HAkillNodes/dependencies/onos-gen-partitions
diff --git a/TestON/tests/HAminorityRestart/dependencies/Counters.py b/TestON/tests/HAminorityRestart/dependencies/Counters.py
deleted file mode 100644
index 6614887..0000000
--- a/TestON/tests/HAminorityRestart/dependencies/Counters.py
+++ /dev/null
@@ -1,96 +0,0 @@
-def __init__( self ):
-    self.default = ''
-
-def consistentCheck():
-    """
-    Checks that TestON counters are consistent across all nodes.
-
-    Returns the tuple (onosCounters, consistent)
-    - onosCounters is the parsed json output of the counters command on all nodes
-    - consistent is main.TRUE if all "TestON" counters are consitent across all
-        nodes or main.FALSE
-    """
-    import json
-    correctResults = main.TRUE
-    # Get onos counters results
-    onosCountersRaw = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[i].counters,
-                         name="counters-" + str( i ) )
-        threads.append( t )
-        t.start()
-    for t in threads:
-        t.join()
-        onosCountersRaw.append( t.result )
-    onosCounters = []
-    for i in range( main.numCtrls ):
-        try:
-            onosCounters.append( json.loads( onosCountersRaw[i] ) )
-        except ( ValueError, TypeError ):
-            main.log.error( "Could not parse counters response from ONOS" +
-                            str( i + 1 ) )
-            main.log.warn( repr( onosCountersRaw[ i ] ) )
-            return main.FALSE
-
-    testCounters = {}
-    # make a list of all the "TestON-*" counters in ONOS
-    # lookes like a dict whose keys are the name of the ONOS node and values
-    # are a list of the counters. I.E.
-    # { "ONOS1": [ {"name":"TestON-inMemory","value":56},
-    #              {"name":"TestON-Partitions","value":56} ]
-    # }
-    # NOTE: There is an assumtion that all nodes are active
-    #        based on the above for loops
-    for controller in enumerate( onosCounters ):
-        for dbType in controller[1]:
-            for dbName, items in dbType.iteritems():
-                for item in items:
-                    if 'TestON' in item['name']:
-                        node = 'ONOS' + str( controller[0] + 1 )
-                        try:
-                            testCounters[node].append( item )
-                        except KeyError:
-                            testCounters[node] = [ item ]
-    # compare the counters on each node
-    tmp = [ v == testCounters['ONOS1'] for k, v in testCounters.iteritems() ]
-    if all( tmp ):
-        consistent = main.TRUE
-    else:
-        consistent = main.FALSE
-        main.log.error( "ONOS nodes have different values for counters:\n" +
-                        testCounters )
-    return ( onosCounters, consistent )
-
-def counterCheck( counterName, counterValue ):
-    """
-    Checks that TestON counters are consistent across all nodes and that
-    specified counter is in ONOS with the given value
-    """
-    import json
-    correctResults = main.TRUE
-    # Get onos counters results and consistentCheck
-    onosCounters, consistent = main.Counters.consistentCheck()
-    # Check for correct values
-    for i in range( main.numCtrls ):
-        current = onosCounters[i]
-        onosValue = None
-        try:
-            for database in current:
-                database = database.values()[0]
-                for counter in database:
-                    if counter.get( 'name' ) == counterName:
-                        onosValue = counter.get( 'value' )
-                        break
-        except AttributeError, e:
-            main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
-                            "is not as expected" )
-            correctResults = main.FALSE
-        if onosValue == counterValue:
-            main.log.info( counterName + " counter value is correct" )
-        else:
-            main.log.error( counterName + " counter value is incorrect," +
-                            " expected value: " + str( counterValue )
-                            + " current value: " + str( onosValue ) )
-            correctResults = main.FALSE
-    return consistent and correctResults
diff --git a/TestON/tests/HAsanity/HAsanity.params b/TestON/tests/HAsanity/HAsanity.params
index cae5b3c..b8455c0 100644
--- a/TestON/tests/HAsanity/HAsanity.params
+++ b/TestON/tests/HAsanity/HAsanity.params
@@ -70,6 +70,7 @@
     <timers>
         <LinkDiscovery>12</LinkDiscovery>
         <SwitchDiscovery>12</SwitchDiscovery>
+        <gossip>5</gossip>
     </timers>
     <kill>
         <switch> s5 </switch>
diff --git a/TestON/tests/HAsanity/HAsanity.py b/TestON/tests/HAsanity/HAsanity.py
index 3dfdde6..3ea2cde 100644
--- a/TestON/tests/HAsanity/HAsanity.py
+++ b/TestON/tests/HAsanity/HAsanity.py
@@ -725,14 +725,16 @@
         gossipTime = intentStop - intentStart
         main.log.info( "It took about " + str( gossipTime ) +
                         " seconds for all intents to appear in each node" )
-        # FIXME: make this time configurable/calculate based off of number of
-        #        nodes and gossip rounds
+        gossipPeriod = int( main.params['timers']['gossip'] )
+        maxGossipTime = gossipPeriod * len( main.nodes )
         utilities.assert_greater_equals(
-                expect=40, actual=gossipTime,
+                expect=maxGossipTime, actual=gossipTime,
                 onpass="ECM anti-entropy for intents worked within " +
                        "expected time",
-                onfail="Intent ECM anti-entropy took too long" )
-        if gossipTime <= 40:
+                onfail="Intent ECM anti-entropy took too long. " +
+                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
+                                                                  gossipTime ) )
+        if gossipTime <= maxGossipTime:
             intentAddResult = True
 
         if not intentAddResult or "key" in pendingMap:
diff --git a/TestON/tests/HAsanity/dependencies/obelisk.py b/TestON/tests/HAsanity/dependencies/obelisk.py
index 4378a9b..d613806 100755
--- a/TestON/tests/HAsanity/dependencies/obelisk.py
+++ b/TestON/tests/HAsanity/dependencies/obelisk.py
@@ -67,4 +67,3 @@
 if __name__ == '__main__':
     setLogLevel( 'info' )
     run()
-
diff --git a/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.params b/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.params
index 3e31402..990bef4 100644
--- a/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.params
+++ b/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.params
@@ -60,6 +60,7 @@
     <timers>
         <LinkDiscovery>12</LinkDiscovery>
         <SwitchDiscovery>12</SwitchDiscovery>
+        <gossip>5</gossip>
     </timers>
     <kill>
         <switch> s5 </switch>
diff --git a/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py b/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py
index bdcf969..0883484 100644
--- a/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py
+++ b/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py
@@ -609,14 +609,16 @@
         gossipTime = intentStop - intentStart
         main.log.info( "It took about " + str( gossipTime ) +
                         " seconds for all intents to appear in each node" )
-        # FIXME: make this time configurable/calculate based off of number of
-        #        nodes and gossip rounds
+        gossipPeriod = int( main.params['timers']['gossip'] )
+        maxGossipTime = gossipPeriod * len( main.nodes )
         utilities.assert_greater_equals(
-                expect=40, actual=gossipTime,
+                expect=maxGossipTime, actual=gossipTime,
                 onpass="ECM anti-entropy for intents worked within " +
                        "expected time",
-                onfail="Intent ECM anti-entropy took too long" )
-        if gossipTime <= 40:
+                onfail="Intent ECM anti-entropy took too long. " +
+                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
+                                                                  gossipTime ) )
+        if gossipTime <= maxGossipTime:
             intentAddResult = True
 
         if not intentAddResult or "key" in pendingMap:
diff --git a/TestON/tests/HAsingleInstanceRestart/dependencies/obelisk.py b/TestON/tests/HAsingleInstanceRestart/dependencies/obelisk.py
index 4378a9b..d613806 100755
--- a/TestON/tests/HAsingleInstanceRestart/dependencies/obelisk.py
+++ b/TestON/tests/HAsingleInstanceRestart/dependencies/obelisk.py
@@ -67,4 +67,3 @@
 if __name__ == '__main__':
     setLogLevel( 'info' )
     run()
-
diff --git a/TestON/tests/HAminorityRestart/HAminorityRestart.params b/TestON/tests/HAstopNodes/HAstopNodes.params
similarity index 62%
rename from TestON/tests/HAminorityRestart/HAminorityRestart.params
rename to TestON/tests/HAstopNodes/HAstopNodes.params
index 348768c..fd10739 100644
--- a/TestON/tests/HAminorityRestart/HAminorityRestart.params
+++ b/TestON/tests/HAstopNodes/HAstopNodes.params
@@ -1,7 +1,27 @@
 <PARAMS>
-    <testcases>1,2,8,3,4,5,14,16,17,[6],8,7,4,15,17,9,8,4,10,8,4,11,8,4,12,8,4,13</testcases>
+    #List of test cases:
+    #CASE1: Compile ONOS and push it to the test machines
+    #CASE2: Assign devices to controllers
+    #CASE21: Assign mastership to controllers
+    #CASE3: Assign intents
+    #CASE4: Ping across added host intents
+    #CASE5: Reading state of ONOS
+    #CASE61: The Failure inducing case.
+    #CASE62: The Failure recovery case.
+    #CASE7: Check state after control plane failure
+    #CASE8: Compare topo
+    #CASE9: Link s3-s28 down
+    #CASE10: Link s3-s28 up
+    #CASE11: Switch down
+    #CASE12: Switch up
+    #CASE13: Clean up
+    #CASE14: start election app on all onos nodes
+    #CASE15: Check that Leadership Election is still functional
+    #CASE16: Install Distributed Primitives app
+    #CASE17: Check for basic functionality with distributed primitives
+    <testcases>1,2,8,3,4,5,14,16,17,[61,8,7,4,15,17,62],8,7,4,15,17,9,8,4,10,8,4,11,8,4,12,8,4,13</testcases>
     <imports>
-        <path> /home/admin/OnosSystemTest/TestON/tests/HAminorityRestart/dependencies/ </path>
+        <path> /home/admin/OnosSystemTest/TestON/tests/HAstopNodes/dependencies/ </path>
     </imports>
     <ENV>
         <cellName>HA</cellName>
@@ -51,6 +71,7 @@
     <timers>
         <LinkDiscovery>12</LinkDiscovery>
         <SwitchDiscovery>12</SwitchDiscovery>
+        <gossip>5</gossip>
     </timers>
     <kill>
         <switch> s5 </switch>
diff --git a/TestON/tests/HAminorityRestart/HAminorityRestart.py b/TestON/tests/HAstopNodes/HAstopNodes.py
similarity index 90%
copy from TestON/tests/HAminorityRestart/HAminorityRestart.py
copy to TestON/tests/HAstopNodes/HAstopNodes.py
index ca8a194..c6e584f 100644
--- a/TestON/tests/HAminorityRestart/HAminorityRestart.py
+++ b/TestON/tests/HAstopNodes/HAstopNodes.py
@@ -9,7 +9,8 @@
 CASE3: Assign intents
 CASE4: Ping across added host intents
 CASE5: Reading state of ONOS
-CASE6: The Failure case.
+CASE61: The Failure inducing case.
+CASE62: The Failure recovery case.
 CASE7: Check state after control plane failure
 CASE8: Compare topo
 CASE9: Link s3-s28 down
@@ -24,7 +25,7 @@
 """
 
 
-class HAminorityRestart:
+class HAstopNodes:
 
     def __init__( self ):
         self.default = ''
@@ -49,7 +50,7 @@
         """
         import imp
         import pexpect
-        main.log.info( "ONOS HA test: Restart minority of ONOS nodes - " +
+        main.log.info( "ONOS HA test: Stop a minority of ONOS nodes - " +
                          "initialization" )
         main.case( "Setting up test environment" )
         main.caseExplanation = "Setup the test environment including " +\
@@ -176,7 +177,7 @@
         #       job = name of Jenkins job
         #       Plot Name = Plot-HA, only can be used if multiple plots
         #       index = The number of the graph under plot name
-        job = "HAminorityRestart"
+        job = "HAstopNodes"
         plotName = "Plot-HA"
         graphs = '<ac:structured-macro ac:name="html">\n'
         graphs += '<ac:plain-text-body><![CDATA[\n'
@@ -261,6 +262,9 @@
                                  onpass="ONOS cli startup successful",
                                  onfail="ONOS cli startup failed" )
 
+        # Create a list of active nodes for use when some nodes are stopped
+        main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
+
         if main.params[ 'tcpdump' ].lower() == "true":
             main.step( "Start Packet Capture MN" )
             main.Mininet2.startTcpdump(
@@ -272,7 +276,7 @@
         main.step( "App Ids check" )
         appCheck = main.TRUE
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].appToIDCheck,
                              name="appToIDCheck-" + str( i ),
                              args=[] )
@@ -283,8 +287,9 @@
             t.join()
             appCheck = appCheck and t.result
         if appCheck != main.TRUE:
-            main.log.warn( main.CLIs[0].apps() )
-            main.log.warn( main.CLIs[0].appIDs() )
+            node = main.activeNodes[0]
+            main.log.warn( main.CLIs[node].apps() )
+            main.log.warn( main.CLIs[node].appIDs() )
         utilities.assert_equals( expect=main.TRUE, actual=appCheck,
                                  onpass="App Ids seem to be correct",
                                  onfail="Something is wrong with app Ids" )
@@ -376,6 +381,7 @@
 
         ipList = [ ]
         deviceList = []
+        onosCli = main.CLIs[ main.activeNodes[0] ]
         try:
             # Assign mastership to specific controllers. This assignment was
             # determined for a 7 node cluser, but will work with any sized
@@ -385,45 +391,45 @@
                 if i == 1:
                     c = 0
                     ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
                 elif i == 2:
                     c = 1 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
                 elif i == 3:
                     c = 1 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
                 elif i == 4:
                     c = 3 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
                 elif i == 5:
                     c = 2 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
                 elif i == 6:
                     c = 2 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
                 elif i == 7:
                     c = 5 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
                 elif i >= 8 and i <= 17:
                     c = 4 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS5
                     dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
                 elif i >= 18 and i <= 27:
                     c = 6 % main.numCtrls
                     ip = main.nodes[ c ].ip_address  # ONOS7
                     dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
                 elif i == 28:
                     c = 0
                     ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
+                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
                 else:
                     main.log.error( "You didn't write an else statement for " +
                                     "switch s" + str( i ) )
@@ -431,13 +437,12 @@
                 # Assign switch
                 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
                 # TODO: make this controller dynamic
-                roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
-                                                                  ip )
+                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
                 ipList.append( ip )
                 deviceList.append( deviceId )
         except ( AttributeError, AssertionError ):
             main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( main.ONOScli1.devices() )
+            main.log.info( onosCli.devices() )
         utilities.assert_equals(
             expect=main.TRUE,
             actual=roleCall,
@@ -453,7 +458,7 @@
             ip = ipList[i]
             deviceId = deviceList[i]
             # Check assignment
-            master = main.ONOScli1.getRole( deviceId ).get( 'master' )
+            master = onosCli.getRole( deviceId ).get( 'master' )
             if ip in master:
                 roleCheck = roleCheck and main.TRUE
             else:
@@ -489,7 +494,8 @@
 
         # install onos-app-fwd
         main.step( "Install reactive forwarding app" )
-        installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
+        onosCli = main.CLIs[ main.activeNodes[0] ]
+        installResults = onosCli.activateApp( "org.onosproject.fwd" )
         utilities.assert_equals( expect=main.TRUE, actual=installResults,
                                  onpass="Install fwd successful",
                                  onfail="Install fwd failed" )
@@ -497,7 +503,7 @@
         main.step( "Check app ids" )
         appCheck = main.TRUE
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].appToIDCheck,
                              name="appToIDCheck-" + str( i ),
                              args=[] )
@@ -508,8 +514,8 @@
             t.join()
             appCheck = appCheck and t.result
         if appCheck != main.TRUE:
-            main.log.warn( main.CLIs[0].apps() )
-            main.log.warn( main.CLIs[0].appIDs() )
+            main.log.warn( onosCli.apps() )
+            main.log.warn( onosCli.appIDs() )
         utilities.assert_equals( expect=main.TRUE, actual=appCheck,
                                  onpass="App Ids seem to be correct",
                                  onfail="Something is wrong with app Ids" )
@@ -538,7 +544,8 @@
         time.sleep( 11 )
         # uninstall onos-app-fwd
         main.step( "Uninstall reactive forwarding app" )
-        uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
+        node = main.activeNodes[0]
+        uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
         utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
                                  onpass="Uninstall fwd successful",
                                  onfail="Uninstall fwd failed" )
@@ -546,7 +553,7 @@
         main.step( "Check app ids" )
         threads = []
         appCheck2 = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].appToIDCheck,
                              name="appToIDCheck-" + str( i ),
                              args=[] )
@@ -557,16 +564,17 @@
             t.join()
             appCheck2 = appCheck2 and t.result
         if appCheck2 != main.TRUE:
-            main.log.warn( main.CLIs[0].apps() )
-            main.log.warn( main.CLIs[0].appIDs() )
+            node = main.activeNodes[0]
+            main.log.warn( main.CLIs[node].apps() )
+            main.log.warn( main.CLIs[node].appIDs() )
         utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
                                  onpass="App Ids seem to be correct",
                                  onfail="Something is wrong with app Ids" )
 
         main.step( "Add host intents via cli" )
         intentIds = []
-        # TODO:  move the host numbers to params
-        #        Maybe look at all the paths we ping?
+        # TODO: move the host numbers to params
+        #       Maybe look at all the paths we ping?
         intentAddResult = True
         hostResult = main.TRUE
         for i in range( 8, 18 ):
@@ -577,16 +585,17 @@
             host2 = "00:00:00:00:00:" + \
                 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
             # NOTE: getHost can return None
-            host1Dict = main.ONOScli1.getHost( host1 )
-            host2Dict = main.ONOScli1.getHost( host2 )
+            host1Dict = onosCli.getHost( host1 )
+            host2Dict = onosCli.getHost( host2 )
             host1Id = None
             host2Id = None
             if host1Dict and host2Dict:
                 host1Id = host1Dict.get( 'id', None )
                 host2Id = host2Dict.get( 'id', None )
             if host1Id and host2Id:
-                nodeNum = ( i % main.numCtrls )
-                tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
+                nodeNum = ( i % len( main.activeNodes ) )
+                node = main.activeNodes[nodeNum]
+                tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
                 if tmpId:
                     main.log.info( "Added intent with id: " + tmpId )
                     intentIds.append( tmpId )
@@ -596,7 +605,8 @@
             else:
                 main.log.error( "Error, getHost() failed for h" + str( i ) +
                                 " and/or h" + str( i + 10 ) )
-                hosts = main.CLIs[ 0 ].hosts()
+                node = main.activeNodes[0]
+                hosts = main.CLIs[node].hosts()
                 main.log.warn( "Hosts output: " )
                 try:
                     main.log.warn( json.dumps( json.loads( hosts ),
@@ -611,7 +621,7 @@
                                  onfail="Error looking up host ids" )
 
         intentStart = time.time()
-        onosIds = main.ONOScli1.getAllIntentsId()
+        onosIds = onosCli.getAllIntentsId()
         main.log.info( "Submitted intents: " + str( intentIds ) )
         main.log.info( "Intents in ONOS: " + str( onosIds ) )
         for intent in intentIds:
@@ -624,7 +634,7 @@
         else:
             intentStop = None
         # Print the intent states
-        intents = main.ONOScli1.intents()
+        intents = onosCli.intents()
         intentStates = []
         installedCheck = True
         main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
@@ -650,7 +660,7 @@
             count += 1
             main.log.info( "%-6s%-15s%-15s" %
                            ( str( count ), str( i ), str( s ) ) )
-        leaders = main.ONOScli1.leaders()
+        leaders = onosCli.leaders()
         try:
             missing = False
             if leaders:
@@ -677,12 +687,12 @@
             main.log.error( repr( leaders ) )
         # Check all nodes
         if missing:
-            for node in main.CLIs:
-                response = node.leaders( jsonFormat=False)
-                main.log.warn( str( node.name ) + " leaders output: \n" +
+            for i in main.activeNodes:
+                response = main.CLIs[i].leaders( jsonFormat=False)
+                main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
                                str( response ) )
 
-        partitions = main.ONOScli1.partitions()
+        partitions = onosCli.partitions()
         try:
             if partitions :
                 parsedPartitions = json.loads( partitions )
@@ -697,7 +707,7 @@
         except ( ValueError, TypeError ):
             main.log.exception( "Error parsing partitions" )
             main.log.error( repr( partitions ) )
-        pendingMap = main.ONOScli1.pendingMap()
+        pendingMap = onosCli.pendingMap()
         try:
             if pendingMap :
                 parsedPending = json.loads( pendingMap )
@@ -718,21 +728,21 @@
             main.log.error( "Error in pushing host intents to ONOS" )
 
         main.step( "Intent Anti-Entropy dispersion" )
-        for i in range(100):
+        for j in range(100):
             correct = True
             main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for cli in main.CLIs:
+            for i in main.activeNodes:
                 onosIds = []
-                ids = cli.getAllIntentsId()
+                ids = main.CLIs[i].getAllIntentsId()
                 onosIds.append( ids )
-                main.log.debug( "Intents in " + cli.name + ": " +
+                main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
                                 str( sorted( onosIds ) ) )
                 if sorted( ids ) != sorted( intentIds ):
                     main.log.warn( "Set of intent IDs doesn't match" )
                     correct = False
                     break
                 else:
-                    intents = json.loads( cli.intents() )
+                    intents = json.loads( main.CLIs[i].intents() )
                     for intent in intents:
                         if intent[ 'state' ] != "INSTALLED":
                             main.log.warn( "Intent " + intent[ 'id' ] +
@@ -749,14 +759,16 @@
         gossipTime = intentStop - intentStart
         main.log.info( "It took about " + str( gossipTime ) +
                         " seconds for all intents to appear in each node" )
-        # FIXME: make this time configurable/calculate based off of number of
-        #        nodes and gossip rounds
+        gossipPeriod = int( main.params['timers']['gossip'] )
+        maxGossipTime = gossipPeriod * len( main.activeNodes )
         utilities.assert_greater_equals(
-                expect=40, actual=gossipTime,
+                expect=maxGossipTime, actual=gossipTime,
                 onpass="ECM anti-entropy for intents worked within " +
                        "expected time",
-                onfail="Intent ECM anti-entropy took too long" )
-        if gossipTime <= 40:
+                onfail="Intent ECM anti-entropy took too long. " +
+                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
+                                                                  gossipTime ) )
+        if gossipTime <= maxGossipTime:
             intentAddResult = True
 
         if not intentAddResult or "key" in pendingMap:
@@ -764,11 +776,11 @@
             installedCheck = True
             main.log.info( "Sleeping 60 seconds to see if intents are found" )
             time.sleep( 60 )
-            onosIds = main.ONOScli1.getAllIntentsId()
+            onosIds = onosCli.getAllIntentsId()
             main.log.info( "Submitted intents: " + str( intentIds ) )
             main.log.info( "Intents in ONOS: " + str( onosIds ) )
             # Print the intent states
-            intents = main.ONOScli1.intents()
+            intents = onosCli.intents()
             intentStates = []
             main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
             count = 0
@@ -792,7 +804,7 @@
                 count += 1
                 main.log.info( "%-6s%-15s%-15s" %
                                ( str( count ), str( i ), str( s ) ) )
-            leaders = main.ONOScli1.leaders()
+            leaders = onosCli.leaders()
             try:
                 missing = False
                 if leaders:
@@ -822,12 +834,13 @@
                 main.log.error( repr( leaders ) )
             # Check all nodes
             if missing:
-                for node in main.CLIs:
+                for i in main.activeNodes:
+                    node = main.CLIs[i]
                     response = node.leaders( jsonFormat=False)
                     main.log.warn( str( node.name ) + " leaders output: \n" +
                                    str( response ) )
 
-            partitions = main.ONOScli1.partitions()
+            partitions = onosCli.partitions()
             try:
                 if partitions :
                     parsedPartitions = json.loads( partitions )
@@ -842,7 +855,7 @@
             except ( ValueError, TypeError ):
                 main.log.exception( "Error parsing partitions" )
                 main.log.error( repr( partitions ) )
-            pendingMap = main.ONOScli1.pendingMap()
+            pendingMap = onosCli.pendingMap()
             try:
                 if pendingMap :
                     parsedPending = json.loads( pendingMap )
@@ -868,11 +881,12 @@
         assert utilities.assert_equals, "utilities.assert_equals not defined"
         assert main.CLIs, "main.CLIs not defined"
         assert main.nodes, "main.nodes not defined"
-        main.case( "Verify connectivity by sendind traffic across Intents" )
+        main.case( "Verify connectivity by sending traffic across Intents" )
         main.caseExplanation = "Ping across added host intents to check " +\
                                 "functionality and check the state of " +\
                                 "the intent"
         main.step( "Ping across added host intents" )
+        onosCli = main.CLIs[ main.activeNodes[0] ]
         PingResult = main.TRUE
         for i in range( 8, 18 ):
             ping = main.Mininet1.pingHost( src="h" + str( i ),
@@ -890,7 +904,7 @@
             # TODO: pretty print
             main.log.warn( "ONOS1 intents: " )
             try:
-                tmpIntents = main.ONOScli1.intents()
+                tmpIntents = onosCli.intents()
                 main.log.warn( json.dumps( json.loads( tmpIntents ),
                                            sort_keys=True,
                                            indent=4,
@@ -909,7 +923,7 @@
         while not installedCheck and loopCount < 40:
             installedCheck = True
             # Print the intent states
-            intents = main.ONOScli1.intents()
+            intents = onosCli.intents()
             intentStates = []
             main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
             count = 0
@@ -938,7 +952,7 @@
                                         "INSTALLED state" )
 
         main.step( "Check leadership of topics" )
-        leaders = main.ONOScli1.leaders()
+        leaders = onosCli.leaders()
         topicCheck = main.TRUE
         try:
             if leaders:
@@ -973,7 +987,8 @@
             # TODO: Check for a leader of these topics
         # Check all nodes
         if topicCheck:
-            for node in main.CLIs:
+            for i in main.activeNodes:
+                node = main.CLIs[i]
                 response = node.leaders( jsonFormat=False)
                 main.log.warn( str( node.name ) + " leaders output: \n" +
                                str( response ) )
@@ -982,7 +997,7 @@
                                  onpass="intent Partitions is in leaders",
                                  onfail="Some topics were lost " )
         # Print partitions
-        partitions = main.ONOScli1.partitions()
+        partitions = onosCli.partitions()
         try:
             if partitions :
                 parsedPartitions = json.loads( partitions )
@@ -998,7 +1013,7 @@
             main.log.exception( "Error parsing partitions" )
             main.log.error( repr( partitions ) )
         # Print Pending Map
-        pendingMap = main.ONOScli1.pendingMap()
+        pendingMap = onosCli.pendingMap()
         try:
             if pendingMap :
                 parsedPending = json.loads( pendingMap )
@@ -1018,7 +1033,7 @@
                            "intents change" )
             time.sleep( 60 )
             # Print the intent states
-            intents = main.ONOScli1.intents()
+            intents = onosCli.intents()
             intentStates = []
             main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
             count = 0
@@ -1037,7 +1052,7 @@
                 count += 1
                 main.log.info( "%-6s%-15s%-15s" %
                                ( str( count ), str( i ), str( s ) ) )
-            leaders = main.ONOScli1.leaders()
+            leaders = onosCli.leaders()
             try:
                 missing = False
                 if leaders:
@@ -1066,12 +1081,13 @@
                 main.log.exception( "Error parsing leaders" )
                 main.log.error( repr( leaders ) )
             if missing:
-                for node in main.CLIs:
+                for i in main.activeNodes:
+                    node = main.CLIs[i]
                     response = node.leaders( jsonFormat=False)
                     main.log.warn( str( node.name ) + " leaders output: \n" +
                                    str( response ) )
 
-            partitions = main.ONOScli1.partitions()
+            partitions = onosCli.partitions()
             try:
                 if partitions :
                     parsedPartitions = json.loads( partitions )
@@ -1086,7 +1102,7 @@
             except ( ValueError, TypeError ):
                 main.log.exception( "Error parsing partitions" )
                 main.log.error( repr( partitions ) )
-            pendingMap = main.ONOScli1.pendingMap()
+            pendingMap = onosCli.pendingMap()
             try:
                 if pendingMap :
                     parsedPending = json.loads( pendingMap )
@@ -1101,7 +1117,8 @@
                 main.log.exception( "Error parsing pending map" )
                 main.log.error( repr( pendingMap ) )
         # Print flowrules
-        main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
+        node = main.activeNodes[0]
+        main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
         main.step( "Wait a minute then ping again" )
         # the wait is above
         PingResult = main.TRUE
@@ -1121,7 +1138,7 @@
             # TODO: pretty print
             main.log.warn( "ONOS1 intents: " )
             try:
-                tmpIntents = main.ONOScli1.intents()
+                tmpIntents = onosCli.intents()
                 main.log.warn( json.dumps( json.loads( tmpIntents ),
                                            sort_keys=True,
                                            indent=4,
@@ -1158,7 +1175,7 @@
         # Assert that each device has a master
         rolesNotNull = main.TRUE
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].rolesNotNull,
                              name="rolesNotNull-" + str( i ),
                              args=[] )
@@ -1180,7 +1197,7 @@
         consistentMastership = True
         rolesResults = True
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].roles,
                              name="roles-" + str( i ),
                              args=[] )
@@ -1191,13 +1208,12 @@
             t.join()
             ONOSMastership.append( t.result )
 
-        for i in range( main.numCtrls ):
+        for i in range( len( ONOSMastership ) ):
+            node = str( main.activeNodes[i] + 1 )
             if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
-                main.log.error( "Error in getting ONOS" + str( i + 1 ) +
-                                 " roles" )
-                main.log.warn(
-                    "ONOS" + str( i + 1 ) + " mastership response: " +
-                    repr( ONOSMastership[i] ) )
+                main.log.error( "Error in getting ONOS" + node + " roles" )
+                main.log.warn( "ONOS" + node + " mastership response: " +
+                               repr( ONOSMastership[i] ) )
                 rolesResults = False
         utilities.assert_equals(
             expect=True,
@@ -1218,10 +1234,11 @@
             onfail="ONOS nodes have different views of switch roles" )
 
         if rolesResults and not consistentMastership:
-            for i in range( main.numCtrls ):
+            for i in range( len( main.activeNodes ) ):
+                node = str( main.activeNodes[i] + 1 )
                 try:
                     main.log.warn(
-                        "ONOS" + str( i + 1 ) + " roles: ",
+                        "ONOS" + node + " roles: ",
                         json.dumps(
                             json.loads( ONOSMastership[ i ] ),
                             sort_keys=True,
@@ -1241,7 +1258,7 @@
         consistentIntents = True
         intentsResults = True
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].intents,
                              name="intents-" + str( i ),
                              args=[],
@@ -1253,11 +1270,11 @@
             t.join()
             ONOSIntents.append( t.result )
 
-        for i in range( main.numCtrls ):
+        for i in range( len( ONOSIntents ) ):
+            node = str( main.activeNodes[i] + 1 )
             if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + str( i + 1 ) +
-                                 " intents" )
-                main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
+                main.log.error( "Error in getting ONOS" + node + " intents" )
+                main.log.warn( "ONOS" + node + " intents response: " +
                                repr( ONOSIntents[ i ] ) )
                 intentsResults = False
         utilities.assert_equals(
@@ -1287,7 +1304,7 @@
             #  ...        ...         ...
             #  ...        ...         ...
             title = "   Id"
-            for n in range( main.numCtrls ):
+            for n in main.activeNodes:
                 title += " " * 10 + "ONOS" + str( n + 1 )
             main.log.warn( title )
             # get all intent keys in the cluster
@@ -1309,22 +1326,23 @@
 
         if intentsResults and not consistentIntents:
             # print the json objects
-            n = len(ONOSIntents)
-            main.log.debug( "ONOS" + str( n ) + " intents: " )
+            n = str( main.activeNodes[-1] + 1 )
+            main.log.debug( "ONOS" + n + " intents: " )
             main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
                                         sort_keys=True,
                                         indent=4,
                                         separators=( ',', ': ' ) ) )
-            for i in range( main.numCtrls ):
+            for i in range( len( ONOSIntents ) ):
+                node = str( main.activeNodes[i] + 1 )
                 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
-                    main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
+                    main.log.debug( "ONOS" + node + " intents: " )
                     main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
                                                 sort_keys=True,
                                                 indent=4,
                                                 separators=( ',', ': ' ) ) )
                 else:
-                    main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
-                                    str( n ) + " intents" )
+                    main.log.debug( "ONOS" + node + " intents match ONOS" +
+                                    n + " intents" )
         elif intentsResults and consistentIntents:
             intentCheck = main.TRUE
             intentState = ONOSIntents[ 0 ]
@@ -1338,7 +1356,7 @@
         consistentFlows = True
         flowsResults = True
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].flows,
                              name="flows-" + str( i ),
                              args=[],
@@ -1353,8 +1371,8 @@
             result = t.result
             ONOSFlows.append( result )
 
-        for i in range( main.numCtrls ):
-            num = str( i + 1 )
+        for i in range( len( ONOSFlows ) ):
+            num = str( main.activeNodes[i] + 1 )
             if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
                 main.log.error( "Error in getting ONOS" + num + " flows" )
                 main.log.warn( "ONOS" + num + " flows response: " +
@@ -1390,16 +1408,16 @@
             onfail="ONOS nodes have different flow counts" )
 
         if flowsResults and not consistentFlows:
-            for i in range( main.numCtrls ):
+            for i in range( len( ONOSFlows ) ):
+                node = str( main.activeNodes[i] + 1 )
                 try:
                     main.log.warn(
-                        "ONOS" + str( i + 1 ) + " flows: " +
+                        "ONOS" + node + " flows: " +
                         json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
                                     indent=4, separators=( ',', ': ' ) ) )
                 except ( ValueError, TypeError ):
-                    main.log.warn(
-                        "ONOS" + str( i + 1 ) + " flows: " +
-                        repr( ONOSFlows[ i ] ) )
+                    main.log.warn( "ONOS" + node + " flows: " +
+                                   repr( ONOSFlows[ i ] ) )
         elif flowsResults and consistentFlows:
             flowCheck = main.TRUE
             flowState = ONOSFlows[ 0 ]
@@ -1459,7 +1477,7 @@
         main.step( "Collecting topology information from ONOS" )
         devices = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].devices,
                              name="devices-" + str( i ),
                              args=[ ] )
@@ -1471,7 +1489,7 @@
             devices.append( t.result )
         hosts = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].hosts,
                              name="hosts-" + str( i ),
                              args=[ ] )
@@ -1491,7 +1509,7 @@
 
         ports = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].ports,
                              name="ports-" + str( i ),
                              args=[ ] )
@@ -1503,7 +1521,7 @@
             ports.append( t.result )
         links = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].links,
                              name="links-" + str( i ),
                              args=[ ] )
@@ -1515,7 +1533,7 @@
             links.append( t.result )
         clusters = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].clusters,
                              name="clusters-" + str( i ),
                              args=[ ] )
@@ -1531,7 +1549,7 @@
         main.step( "Host view is consistent across ONOS nodes" )
         consistentHostsResult = main.TRUE
         for controller in range( len( hosts ) ):
-            controllerStr = str( controller + 1 )
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if "Error" not in hosts[ controller ]:
                 if hosts[ controller ] == hosts[ 0 ]:
                     continue
@@ -1558,10 +1576,10 @@
         main.step( "Each host has an IP address" )
         ipResult = main.TRUE
         for controller in range( 0, len( hosts ) ):
-            controllerStr = str( controller + 1 )
+            controllerStr = str( main.activeNodes[controller] + 1 )
             for host in hosts[ controller ]:
                 if not host.get( 'ipAddresses', [ ] ):
-                    main.log.error( "DEBUG:Error with host ips on controller" +
+                    main.log.error( "Error with host ips on controller" +
                                     controllerStr + ": " + str( host ) )
                     ipResult = main.FALSE
         utilities.assert_equals(
@@ -1574,7 +1592,7 @@
         main.step( "Cluster view is consistent across ONOS nodes" )
         consistentClustersResult = main.TRUE
         for controller in range( len( clusters ) ):
-            controllerStr = str( controller + 1 )
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if "Error" not in clusters[ controller ]:
                 if clusters[ controller ] == clusters[ 0 ]:
                     continue
@@ -1618,8 +1636,8 @@
         mnSwitches = main.Mininet1.getSwitches()
         mnLinks = main.Mininet1.getLinks()
         mnHosts = main.Mininet1.getHosts()
-        for controller in range( main.numCtrls ):
-            controllerStr = str( controller + 1 )
+        for controller in main.activeNodes:
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if devices[ controller ] and ports[ controller ] and\
                 "Error" not in devices[ controller ] and\
                 "Error" not in ports[ controller ]:
@@ -1687,17 +1705,16 @@
             onpass="Hosts are correct",
             onfail="Hosts are incorrect" )
 
-    def CASE6( self, main ):
+    def CASE61( self, main ):
         """
         The Failure case.
         """
-        import time
         assert main.numCtrls, "main.numCtrls not defined"
         assert main, "main not defined"
         assert utilities.assert_equals, "utilities.assert_equals not defined"
         assert main.CLIs, "main.CLIs not defined"
         assert main.nodes, "main.nodes not defined"
-        main.case( "Restart minority of ONOS nodes" )
+        main.case( "Stop minority of ONOS nodes" )
 
         main.step( "Checking ONOS Logs for errors" )
         for node in main.nodes:
@@ -1711,15 +1728,38 @@
             main.kill.append( p - 1 )
             # NOTE: This only works for cluster sizes of 3,5, or 7.
 
-        main.step( "Killing " + str( len( main.kill ) ) + " ONOS nodes" )
-        killTime = time.time()
+        main.step( "Stopping " + str( len( main.kill ) ) + " ONOS nodes" )
         killResults = main.TRUE
         for i in main.kill:
             killResults = killResults and\
-                          main.ONOSbench.onosKill( main.nodes[i].ip_address )
+                          main.ONOSbench.onosStop( main.nodes[i].ip_address )
+            main.activeNodes.remove( i )
         utilities.assert_equals( expect=main.TRUE, actual=killResults,
-                                 onpass="ONOS Killed successfully",
-                                 onfail="ONOS kill NOT successful" )
+                                 onpass="ONOS nodes stopped successfully",
+                                 onfail="ONOS nodes NOT successfully stopped" )
+
+    def CASE62( self, main ):
+        """
+        The bring up stopped nodes
+        """
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+        assert main.kill, "main.kill not defined"
+        main.case( "Restart minority of ONOS nodes" )
+
+        main.step( "Restarting " + str( len( main.kill ) ) + " ONOS nodes" )
+        startResults = main.TRUE
+        restartTime = time.time()
+        for i in main.kill:
+            startResults = startResults and\
+                           main.ONOSbench.onosStart( main.nodes[i].ip_address )
+        utilities.assert_equals( expect=main.TRUE, actual=startResults,
+                                 onpass="ONOS nodes started successfully",
+                                 onfail="ONOS nodes NOT successfully started" )
 
         main.step( "Checking if ONOS is up yet" )
         count = 0
@@ -1739,19 +1779,29 @@
         for i in main.kill:
             cliResults = cliResults and\
                          main.CLIs[i].startOnosCli( main.nodes[i].ip_address )
+            main.activeNodes.append( i )
         utilities.assert_equals( expect=main.TRUE, actual=cliResults,
                                  onpass="ONOS cli restarted",
                                  onfail="ONOS cli did not restart" )
+        main.activeNodes.sort()
+        try:
+            assert list( set( main.activeNodes ) ) == main.activeNodes,\
+                   "List of active nodes has duplicates, this likely indicates something was run out of order"
+        except AssertionError:
+            main.log.exception( "" )
+            main.cleanup()
+            main.exit()
 
         # Grab the time of restart so we chan check how long the gossip
         # protocol has had time to work
-        main.restartTime = time.time() - killTime
+        main.restartTime = time.time() - restartTime
         main.log.debug( "Restart time: " + str( main.restartTime ) )
         # TODO: MAke this configurable. Also, we are breaking the above timer
         time.sleep( 60 )
-        main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
-        main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
-        main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
+        node = main.activeNodes[0]
+        main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
+        main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
+        main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
 
     def CASE7( self, main ):
         """
@@ -1763,13 +1813,18 @@
         assert utilities.assert_equals, "utilities.assert_equals not defined"
         assert main.CLIs, "main.CLIs not defined"
         assert main.nodes, "main.nodes not defined"
+        try:
+            main.kill
+        except AttributeError:
+            main.kill = []
+
         main.case( "Running ONOS Constant State Tests" )
 
         main.step( "Check that each switch has a master" )
         # Assert that each device has a master
         rolesNotNull = main.TRUE
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].rolesNotNull,
                              name="rolesNotNull-" + str( i ),
                              args=[ ] )
@@ -1790,7 +1845,7 @@
         consistentMastership = True
         rolesResults = True
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].roles,
                              name="roles-" + str( i ),
                              args=[] )
@@ -1801,13 +1856,12 @@
             t.join()
             ONOSMastership.append( t.result )
 
-        for i in range( main.numCtrls ):
+        for i in range( len( ONOSMastership ) ):
+            node = str( main.activeNodes[i] + 1 )
             if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
-                main.log.error( "Error in getting ONOS" + str( i + 1 ) +
-                                 " roles" )
-                main.log.warn(
-                    "ONOS" + str( i + 1 ) + " mastership response: " +
-                    repr( ONOSMastership[i] ) )
+                main.log.error( "Error in getting ONOS" + node + " roles" )
+                main.log.warn( "ONOS" + node + " mastership response: " +
+                               repr( ONOSMastership[i] ) )
                 rolesResults = False
         utilities.assert_equals(
             expect=True,
@@ -1828,48 +1882,15 @@
             onfail="ONOS nodes have different views of switch roles" )
 
         if rolesResults and not consistentMastership:
-            for i in range( main.numCtrls ):
-                main.log.warn(
-                    "ONOS" + str( i + 1 ) + " roles: ",
-                    json.dumps(
-                        json.loads( ONOSMastership[ i ] ),
-                        sort_keys=True,
-                        indent=4,
-                        separators=( ',', ': ' ) ) )
+            for i in range( len( ONOSMastership ) ):
+                node = str( main.activeNodes[i] + 1 )
+                main.log.warn( "ONOS" + node + " roles: ",
+                               json.dumps( json.loads( ONOSMastership[ i ] ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
 
         # NOTE: we expect mastership to change on controller failure
-        '''
-        description2 = "Compare switch roles from before failure"
-        main.step( description2 )
-        try:
-            currentJson = json.loads( ONOSMastership[0] )
-            oldJson = json.loads( mastershipState )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Something is wrong with parsing " +
-                                "ONOSMastership[0] or mastershipState" )
-            main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
-            main.log.error( "mastershipState" + repr( mastershipState ) )
-            main.cleanup()
-            main.exit()
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            switchDPID = str(
-                main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
-            current = [ switch[ 'master' ] for switch in currentJson
-                        if switchDPID in switch[ 'id' ] ]
-            old = [ switch[ 'master' ] for switch in oldJson
-                    if switchDPID in switch[ 'id' ] ]
-            if current == old:
-                mastershipCheck = mastershipCheck and main.TRUE
-            else:
-                main.log.warn( "Mastership of switch %s changed" % switchDPID )
-                mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Mastership of Switches was not changed",
-            onfail="Mastership of some switches changed" )
-        '''
 
         main.step( "Get the intents and compare across all nodes" )
         ONOSIntents = []
@@ -1877,7 +1898,7 @@
         consistentIntents = True
         intentsResults = True
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].intents,
                              name="intents-" + str( i ),
                              args=[],
@@ -1889,11 +1910,11 @@
             t.join()
             ONOSIntents.append( t.result )
 
-        for i in range( main.numCtrls ):
+        for i in range( len( ONOSIntents) ):
+            node = str( main.activeNodes[i] + 1 )
             if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + str( i + 1 ) +
-                                 " intents" )
-                main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
+                main.log.error( "Error in getting ONOS" + node + " intents" )
+                main.log.warn( "ONOS" + node + " intents response: " +
                                repr( ONOSIntents[ i ] ) )
                 intentsResults = False
         utilities.assert_equals(
@@ -1916,7 +1937,7 @@
         #  ...        ...         ...
         #  ...        ...         ...
         title = "   ID"
-        for n in range( main.numCtrls ):
+        for n in main.activeNodes:
             title += " " * 10 + "ONOS" + str( n + 1 )
         main.log.warn( title )
         # get all intent keys in the cluster
@@ -1956,8 +1977,9 @@
             main.log.info( dict( out ) )
 
         if intentsResults and not consistentIntents:
-            for i in range( main.numCtrls ):
-                main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
+            for i in range( len( main.activeNodes ) ):
+                node = str( main.activeNodes[i] + 1 )
+                main.log.warn( "ONOS" + node + " intents: " )
                 main.log.warn( json.dumps(
                     json.loads( ONOSIntents[ i ] ),
                     sort_keys=True,
@@ -2072,7 +2094,8 @@
             restarted.append( main.nodes[i].ip_address )
         leaderResult = main.TRUE
 
-        for cli in main.CLIs:
+        for i in main.activeNodes:
+            cli = main.CLIs[i]
             leaderN = cli.electionTestLeader()
             leaderList.append( leaderN )
             if leaderN == main.FALSE:
@@ -2134,7 +2157,7 @@
             cliStart = time.time()
             devices = []
             threads = []
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].devices,
                                  name="devices-" + str( i ),
                                  args=[ ] )
@@ -2147,7 +2170,7 @@
             hosts = []
             ipResult = main.TRUE
             threads = []
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].hosts,
                                  name="hosts-" + str( i ),
                                  args=[ ] )
@@ -2162,7 +2185,7 @@
                     main.log.exception( "Error parsing hosts results" )
                     main.log.error( repr( t.result ) )
             for controller in range( 0, len( hosts ) ):
-                controllerStr = str( controller + 1 )
+                controllerStr = str( main.activeNodes[controller] + 1 )
                 for host in hosts[ controller ]:
                     if host is None or host.get( 'ipAddresses', [] ) == []:
                         main.log.error(
@@ -2171,7 +2194,7 @@
                         ipResult = main.FALSE
             ports = []
             threads = []
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].ports,
                                  name="ports-" + str( i ),
                                  args=[ ] )
@@ -2183,7 +2206,7 @@
                 ports.append( t.result )
             links = []
             threads = []
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].links,
                                  name="links-" + str( i ),
                                  args=[ ] )
@@ -2195,7 +2218,7 @@
                 links.append( t.result )
             clusters = []
             threads = []
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].clusters,
                                  name="clusters-" + str( i ),
                                  args=[ ] )
@@ -2214,8 +2237,8 @@
             mnSwitches = main.Mininet1.getSwitches()
             mnLinks = main.Mininet1.getLinks()
             mnHosts = main.Mininet1.getHosts()
-            for controller in range( main.numCtrls ):
-                controllerStr = str( controller + 1 )
+            for controller in range( len( main.activeNodes ) ):
+                controllerStr = str( main.activeNodes[controller] + 1 )
                 if devices[ controller ] and ports[ controller ] and\
                     "Error" not in devices[ controller ] and\
                     "Error" not in ports[ controller ]:
@@ -2353,7 +2376,7 @@
         main.step( "Hosts view is consistent across all ONOS nodes" )
         consistentHostsResult = main.TRUE
         for controller in range( len( hosts ) ):
-            controllerStr = str( controller + 1 )
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if "Error" not in hosts[ controller ]:
                 if hosts[ controller ] == hosts[ 0 ]:
                     continue
@@ -2395,7 +2418,7 @@
         main.step( "Clusters view is consistent across all ONOS nodes" )
         consistentClustersResult = main.TRUE
         for controller in range( len( clusters ) ):
-            controllerStr = str( controller + 1 )
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if "Error" not in clusters[ controller ]:
                 if clusters[ controller ] == clusters[ 0 ]:
                     continue
@@ -2467,7 +2490,7 @@
         nodesOutput = []
         nodeResults = main.TRUE
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].nodes,
                              name="nodes-" + str( i ),
                              args=[ ] )
@@ -2477,7 +2500,7 @@
         for t in threads:
             t.join()
             nodesOutput.append( t.result )
-        ips = [ node.ip_address for node in main.nodes ]
+        ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
         for i in nodesOutput:
             try:
                 current = json.loads( i )
@@ -2573,6 +2596,7 @@
         switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
 
         description = "Killing a switch to ensure it is discovered correctly"
+        onosCli = main.CLIs[ main.activeNodes[0] ]
         main.case( description )
         switch = main.params[ 'kill' ][ 'switch' ]
         switchDPID = main.params[ 'kill' ][ 'dpid' ]
@@ -2584,7 +2608,7 @@
         main.log.info( "Waiting " + str( switchSleep ) +
                        " seconds for switch down to be discovered" )
         time.sleep( switchSleep )
-        device = main.ONOScli1.getDevice( dpid=switchDPID )
+        device = onosCli.getDevice( dpid=switchDPID )
         # Peek at the deleted switch
         main.log.warn( str( device ) )
         result = main.FALSE
@@ -2617,6 +2641,7 @@
         switch = main.params[ 'kill' ][ 'switch' ]
         switchDPID = main.params[ 'kill' ][ 'dpid' ]
         links = main.params[ 'kill' ][ 'links' ].split()
+        onosCli = main.CLIs[ main.activeNodes[0] ]
         description = "Adding a switch to ensure it is discovered correctly"
         main.case( description )
 
@@ -2624,14 +2649,12 @@
         main.Mininet1.addSwitch( switch, dpid=switchDPID )
         for peer in links:
             main.Mininet1.addLink( switch, peer )
-        ipList = []
-        for i in range( main.numCtrls ):
-            ipList.append( main.nodes[ i ].ip_address )
+        ipList = [ node.ip_address for node in main.nodes ]
         main.Mininet1.assignSwController( sw=switch, ip=ipList )
         main.log.info( "Waiting " + str( switchSleep ) +
                        " seconds for switch up to be discovered" )
         time.sleep( switchSleep )
-        device = main.ONOScli1.getDevice( dpid=switchDPID )
+        device = onosCli.getDevice( dpid=switchDPID )
         # Peek at the deleted switch
         main.log.warn( str( device ) )
         result = main.FALSE
@@ -2677,7 +2700,7 @@
             # NOTE: must end in /
             for f in logFiles:
                 for node in main.nodes:
-                    dstName =  main.logdir + "/" + node.name + "-" + f
+                    dstName = main.logdir + "/" + node.name + "-" + f
                     main.ONOSbench.secureCopy( node.user_name, node.ip_address,
                                                logFolder + f, dstName )
             # std*.log's
@@ -2687,7 +2710,7 @@
             # NOTE: must end in /
             for f in logFiles:
                 for node in main.nodes:
-                    dstName =  main.logdir + "/" + node.name + "-" + f
+                    dstName = main.logdir + "/" + node.name + "-" + f
                     main.ONOSbench.secureCopy( node.user_name, node.ip_address,
                                                logFolder + f, dstName )
         else:
@@ -2726,7 +2749,8 @@
 
         main.case("Start Leadership Election app")
         main.step( "Install leadership election app" )
-        appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
+        onosCli = main.CLIs[ main.activeNodes[0] ]
+        appResult = onosCli.activateApp( "org.onosproject.election" )
         utilities.assert_equals(
             expect=main.TRUE,
             actual=appResult,
@@ -2736,9 +2760,10 @@
         main.step( "Run for election on each node" )
         leaderResult = main.TRUE
         leaders = []
-        for cli in main.CLIs:
-            cli.electionTestRun()
-        for cli in main.CLIs:
+        for i in main.activeNodes:
+            main.CLIs[i].electionTestRun()
+        for i in main.activeNodes:
+            cli = main.CLIs[i]
             leader = cli.electionTestLeader()
             if leader is None or leader == main.FALSE:
                 main.log.error( cli.name + ": Leader for the election app " +
@@ -2808,10 +2833,9 @@
         main.step( "Run for election on each node" )
         electionResult = main.TRUE
 
-        for cli in main.CLIs:  # run test election on each node
-            if cli.electionTestRun() == main.FALSE:
+        for i in main.activeNodes:  # run test election on each node
+            if main.CLIs[i].electionTestRun() == main.FALSE:
                 electionResult = main.FALSE
-
         utilities.assert_equals(
             expect=main.TRUE,
             actual=electionResult,
@@ -2826,7 +2850,8 @@
         main.step( "Check that each node shows the same leader and candidates" )
         sameResult = main.TRUE
         failMessage = "Nodes have different leaders"
-        for cli in main.CLIs:
+        for i in main.activeNodes:
+            cli = main.CLIs[i]
             node = cli.specificLeaderCandidate( 'org.onosproject.election' )
             oldAllCandidates.append( node )
             oldLeaders.append( node[ 0 ] )
@@ -2845,7 +2870,6 @@
             if set( candidates ) != set( oldCandidates ):
                 sameResult = main.FALSE
                 failMessage += "and candidates"
-
         utilities.assert_equals(
             expect=main.TRUE,
             actual=sameResult,
@@ -2859,7 +2883,7 @@
             main.log.error( "Leadership isn't consistent." )
             withdrawResult = main.FALSE
         # Get the CLI of the oldLeader
-        for i in range( len( main.CLIs ) ):
+        for i in main.activeNodes:
             if oldLeader == main.nodes[ i ].ip_address:
                 oldLeaderCLI = main.CLIs[ i ]
                 break
@@ -2880,7 +2904,8 @@
         failMessage = "Nodes have different leaders"
 
         # Get new leaders and candidates
-        for cli in main.CLIs:
+        for i in main.activeNodes:
+            cli = main.CLIs[i]
             node = cli.specificLeaderCandidate( 'org.onosproject.election' )
             # elections might no have finished yet
             if node[ 0 ] == 'none' and not expectNoLeader:
@@ -2966,7 +2991,8 @@
         newAllCandidates = []
         newCandidates = []
         newLeaders = []
-        for cli in main.CLIs:
+        for i in main.activeNodes:
+            cli = main.CLIs[i]
             node = cli.specificLeaderCandidate( 'org.onosproject.election' )
             if oldLeader not in node:  # election might no have finished yet
                 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
@@ -2998,7 +3024,7 @@
 
         # Check that the re-elected node is last on the candidate List
         if oldLeader != newCandidates[ -1 ]:
-            main.log.error( "Old Leader ("  + oldLeader + ") not in the proper position " +
+            main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
                 str( newCandidates ) )
             positionResult = main.FALSE
 
@@ -3038,7 +3064,8 @@
         main.case( description )
         main.step( "Install Primitives app" )
         appName = "org.onosproject.distributedprimitives"
-        appResults = main.CLIs[0].activateApp( appName )
+        node = main.activeNodes[0]
+        appResults = main.CLIs[node].activateApp( appName )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=appResults,
                                  onpass="Primitives app activated",
@@ -3090,7 +3117,7 @@
         pCounters = []
         threads = []
         addedPValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="counterAddAndGet-" + str( i ),
                              args=[ pCounterName ] )
@@ -3120,7 +3147,7 @@
         pCounters = []
         threads = []
         addedPValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
                              name="counterGetAndAdd-" + str( i ),
                              args=[ pCounterName ] )
@@ -3157,7 +3184,7 @@
         pCounters = []
         threads = []
         addedPValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="counterIncrement-" + str( i ),
                              args=[ pCounterName ],
@@ -3188,7 +3215,7 @@
         pCounters = []
         threads = []
         addedPValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="counterIncrement-" + str( i ),
                              args=[ pCounterName ],
@@ -3219,7 +3246,7 @@
         pCounters = []
         threads = []
         addedPValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
                              name="counterIncrement-" + str( i ),
                              args=[ pCounterName ],
@@ -3258,7 +3285,7 @@
         iCounters = []
         addedIValues = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="icounterIncrement-" + str( i ),
                              args=[ iCounterName ],
@@ -3289,7 +3316,7 @@
         iCounters = []
         threads = []
         addedIValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
                              name="counterGetAndAdd-" + str( i ),
                              args=[ iCounterName ],
@@ -3327,7 +3354,7 @@
         iCounters = []
         threads = []
         addedIValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="counterIncrement-" + str( i ),
                              args=[ iCounterName ],
@@ -3358,7 +3385,7 @@
         iCounters = []
         threads = []
         addedIValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
                              name="counterIncrement-" + str( i ),
                              args=[ iCounterName ],
@@ -3389,7 +3416,7 @@
         iCounters = []
         threads = []
         addedIValues = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
                              name="counterIncrement-" + str( i ),
                              args=[ iCounterName ],
@@ -3445,7 +3472,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3456,13 +3483,14 @@
             getResponses.append( t.result )
 
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -3471,7 +3499,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -3486,7 +3514,7 @@
         main.step( "Distributed Set size" )
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -3497,10 +3525,11 @@
             sizeResponses.append( t.result )
 
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -3513,7 +3542,7 @@
         onosSet.add( addValue )
         addResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestAdd,
                              name="setTestAdd-" + str( i ),
                              args=[ onosSetName, addValue ] )
@@ -3527,7 +3556,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         addResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if addResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -3547,7 +3576,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3557,14 +3586,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
-                                        " has incorrect view" +
+                        main.log.error( "ONOS" + node + " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
                         main.log.debug( "Expected: " + str( onosSet ) )
@@ -3572,8 +3601,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
-                                    " has repeat elements in" +
+                    main.log.error( "ONOS" + node + " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
                     getResults = main.FALSE
@@ -3581,7 +3609,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -3591,10 +3619,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -3608,7 +3637,7 @@
         onosSet.update( addAllValue.split() )
         addResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestAdd,
                              name="setTestAddAll-" + str( i ),
                              args=[ onosSetName, addAllValue ] )
@@ -3622,7 +3651,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         addAllResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if addResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -3642,7 +3671,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3652,13 +3681,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -3667,7 +3697,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -3676,7 +3706,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -3686,10 +3716,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -3702,7 +3733,7 @@
         main.step( "Distributed Set contains()" )
         containsResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setContains-" + str( i ),
                              args=[ onosSetName ],
@@ -3715,7 +3746,7 @@
             containsResponses.append( t.result )
 
         containsResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if containsResponses[ i ] == main.ERROR:
                 containsResults = main.FALSE
             else:
@@ -3729,7 +3760,7 @@
         main.step( "Distributed Set containsAll()" )
         containsAllResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setContainsAll-" + str( i ),
                              args=[ onosSetName ],
@@ -3742,7 +3773,7 @@
             containsAllResponses.append( t.result )
 
         containsAllResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if containsResponses[ i ] == main.ERROR:
                 containsResults = main.FALSE
             else:
@@ -3757,7 +3788,7 @@
         onosSet.remove( addValue )
         removeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestRemove,
                              name="setTestRemove-" + str( i ),
                              args=[ onosSetName, addValue ] )
@@ -3771,7 +3802,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         removeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if removeResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -3791,7 +3822,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3801,13 +3832,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -3816,7 +3848,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -3825,7 +3857,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -3835,10 +3867,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -3853,7 +3886,7 @@
         removeAllResponses = []
         threads = []
         try:
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].setTestRemove,
                                  name="setTestRemoveAll-" + str( i ),
                                  args=[ onosSetName, addAllValue ] )
@@ -3869,7 +3902,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         removeAllResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if removeAllResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -3889,7 +3922,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3899,13 +3932,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -3914,7 +3948,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -3923,7 +3957,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -3933,10 +3967,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -3950,7 +3985,7 @@
         onosSet.update( addAllValue.split() )
         addResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestAdd,
                              name="setTestAddAll-" + str( i ),
                              args=[ onosSetName, addAllValue ] )
@@ -3964,7 +3999,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         addAllResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if addResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -3984,7 +4019,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -3994,13 +4029,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -4009,7 +4045,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -4018,7 +4054,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -4028,10 +4064,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -4045,7 +4082,7 @@
         onosSet.clear()
         clearResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestRemove,
                              name="setTestClear-" + str( i ),
                              args=[ onosSetName, " "],  # Values doesn't matter
@@ -4060,7 +4097,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         clearResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if clearResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -4080,7 +4117,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -4090,13 +4127,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -4105,7 +4143,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -4114,7 +4152,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -4124,10 +4162,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -4141,7 +4180,7 @@
         onosSet.update( addAllValue.split() )
         addResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestAdd,
                              name="setTestAddAll-" + str( i ),
                              args=[ onosSetName, addAllValue ] )
@@ -4155,7 +4194,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         addAllResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if addResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -4175,7 +4214,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -4185,13 +4224,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -4200,7 +4240,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -4209,7 +4249,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -4219,10 +4259,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
+                main.log.error( "ONOS" + node +
                                 " expected a size of " + str( size ) +
                                 " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
@@ -4236,7 +4277,7 @@
         onosSet.intersection_update( retainValue.split() )
         retainResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestRemove,
                              name="setTestRetain-" + str( i ),
                              args=[ onosSetName, retainValue ],
@@ -4251,7 +4292,7 @@
         # main.FALSE = action resulted in no change in set
         # main.ERROR - Some error in executing the function
         retainResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
             if retainResponses[ i ] == main.TRUE:
                 # All is well
                 pass
@@ -4271,7 +4312,7 @@
         size = len( onosSet )
         getResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestGet,
                              name="setTestGet-" + str( i ),
                              args=[ onosSetName ] )
@@ -4281,13 +4322,14 @@
             t.join()
             getResponses.append( t.result )
         getResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if isinstance( getResponses[ i ], list):
                 current = set( getResponses[ i ] )
                 if len( current ) == len( getResponses[ i ] ):
                     # no repeats
                     if onosSet != current:
-                        main.log.error( "ONOS" + str( i + 1 ) +
+                        main.log.error( "ONOS" + node +
                                         " has incorrect view" +
                                         " of set " + onosSetName + ":\n" +
                                         str( getResponses[ i ] ) )
@@ -4296,7 +4338,7 @@
                         getResults = main.FALSE
                 else:
                     # error, set is not a set
-                    main.log.error( "ONOS" + str( i + 1 ) +
+                    main.log.error( "ONOS" + node +
                                     " has repeat elements in" +
                                     " set " + onosSetName + ":\n" +
                                     str( getResponses[ i ] ) )
@@ -4305,7 +4347,7 @@
                 getResults = main.FALSE
         sizeResponses = []
         threads = []
-        for i in range( main.numCtrls ):
+        for i in main.activeNodes:
             t = main.Thread( target=main.CLIs[i].setTestSize,
                              name="setTestSize-" + str( i ),
                              args=[ onosSetName ] )
@@ -4315,11 +4357,11 @@
             t.join()
             sizeResponses.append( t.result )
         sizeResults = main.TRUE
-        for i in range( main.numCtrls ):
+        for i in range( len( main.activeNodes ) ):
+            node = str( main.activeNodes[i] + 1 )
             if size != sizeResponses[ i ]:
                 sizeResults = main.FALSE
-                main.log.error( "ONOS" + str( i + 1 ) +
-                                " expected a size of " +
+                main.log.error( "ONOS" + node + " expected a size of " +
                                 str( size ) + " for set " + onosSetName +
                                 " but got " + str( sizeResponses[ i ] ) )
         retainResults = retainResults and getResults and sizeResults
@@ -4333,7 +4375,8 @@
         tMapValue = "Testing"
         numKeys = 100
         putResult = True
-        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
+        node = main.activeNodes[0]
+        putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
         if len( putResponses ) == 100:
             for i in putResponses:
                 if putResponses[ i ][ 'value' ] != tMapValue:
@@ -4353,10 +4396,10 @@
             getResponses = []
             threads = []
             valueCheck = True
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
                                  name="TMap-get-" + str( i ),
-                                 args=[ "Key" + str ( n ) ] )
+                                 args=[ "Key" + str( n ) ] )
                 threads.append( t )
                 t.start()
             for t in threads:
@@ -4378,7 +4421,8 @@
         tMapValue = "Testing"
         numKeys = 100
         putResult = True
-        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
+        node = main.activeNodes[0]
+        putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue, inMemory=True )
         if len( putResponses ) == 100:
             for i in putResponses:
                 if putResponses[ i ][ 'value' ] != tMapValue:
@@ -4398,10 +4442,10 @@
             getResponses = []
             threads = []
             valueCheck = True
-            for i in range( main.numCtrls ):
+            for i in main.activeNodes:
                 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
                                  name="TMap-get-" + str( i ),
-                                 args=[ "Key" + str ( n ) ],
+                                 args=[ "Key" + str( n ) ],
                                  kwargs={ "inMemory": True } )
                 threads.append( t )
                 t.start()
diff --git a/TestON/tests/HAminorityRestart/HAminorityRestart.topo b/TestON/tests/HAstopNodes/HAstopNodes.topo
similarity index 100%
copy from TestON/tests/HAminorityRestart/HAminorityRestart.topo
copy to TestON/tests/HAstopNodes/HAstopNodes.topo
diff --git a/TestON/tests/HAminorityRestart/README b/TestON/tests/HAstopNodes/README
similarity index 82%
copy from TestON/tests/HAminorityRestart/README
copy to TestON/tests/HAstopNodes/README
index a913f85..ee84051 100644
--- a/TestON/tests/HAminorityRestart/README
+++ b/TestON/tests/HAstopNodes/README
@@ -1,5 +1,5 @@
-This test is designed to verify that an ONOS cluster behaves correctly when
-ONOS nodes die. Currently, we will kill nodes so that each raft partition will
+This test is designed to verify that an ONOS cluster behaves correctly when some
+ONOS nodes are stopped. Currently, we will stop nodes so that each raft partition will
 lose a member, but we make sure that there is always a majority of nodes
 available in each partition.
 
@@ -17,7 +17,9 @@
     - Intents
     - Leadership election
     - Distributed Primitives
-- Kill some ONOS nodes
+- Stop some ONOS nodes
+- Verify ONOS state and functionality
+- Restart nodes
 - Verify ONOS state and functionality
 - Dataplane failures
     - link down and up
diff --git a/TestON/tests/HAminorityRestart/__init__.py b/TestON/tests/HAstopNodes/__init__.py
similarity index 100%
copy from TestON/tests/HAminorityRestart/__init__.py
copy to TestON/tests/HAstopNodes/__init__.py
diff --git a/TestON/tests/HAstopNodes/dependencies/Counters.py b/TestON/tests/HAstopNodes/dependencies/Counters.py
new file mode 100644
index 0000000..455e3e7
--- /dev/null
+++ b/TestON/tests/HAstopNodes/dependencies/Counters.py
@@ -0,0 +1,103 @@
+def __init__( self ):
+    self.default = ''
+
+def consistentCheck():
+    """
+    Checks that TestON counters are consistent across all nodes.
+
+    Returns the tuple (onosCounters, consistent)
+    - onosCounters is the parsed json output of the counters command on all nodes
+    - consistent is main.TRUE if all "TestON" counters are consitent across all
+        nodes or main.FALSE
+    """
+    import json
+    try:
+        correctResults = main.TRUE
+        # Get onos counters results
+        onosCountersRaw = []
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.CLIs[i].counters,
+                             name="counters-" + str( i ) )
+            threads.append( t )
+            t.start()
+        for t in threads:
+            t.join()
+            onosCountersRaw.append( t.result )
+        onosCounters = []
+        for i in range( len( main.activeNodes ) ):
+            try:
+                onosCounters.append( json.loads( onosCountersRaw[i] ) )
+            except ( ValueError, TypeError ):
+                main.log.error( "Could not parse counters response from ONOS" +
+                                str( main.activeNodes[i] + 1 ) )
+                main.log.warn( repr( onosCountersRaw[ i ] ) )
+                return main.FALSE
+
+        testCounters = {}
+        # make a list of all the "TestON-*" counters in ONOS
+        # lookes like a dict whose keys are the name of the ONOS node and values
+        # are a list of the counters. I.E.
+        # { "ONOS1": [ {"name":"TestON-inMemory","value":56},
+        #              {"name":"TestON-Partitions","value":56} ]
+        # }
+        # NOTE: There is an assumtion that all nodes are active
+        #        based on the above for loops
+        for controller in enumerate( onosCounters ):
+            for dbType in controller[1]:
+                for dbName, items in dbType.iteritems():
+                    for item in items:
+                        if 'TestON' in item['name']:
+                            node = 'ONOS' + str( main.activeNodes[ controller[0] ] + 1 )
+                            try:
+                                testCounters[node].append( item )
+                            except KeyError:
+                                testCounters[node] = [ item ]
+        # compare the counters on each node
+        firstV = testCounters.values()[0]
+        tmp = [ v == firstV for k, v in testCounters.iteritems() ]
+        if all( tmp ):
+            consistent = main.TRUE
+        else:
+            consistent = main.FALSE
+            main.log.error( "ONOS nodes have different values for counters:\n" +
+                            testCounters )
+        return ( onosCounters, consistent )
+    except Exception:
+        main.log.exception( "" )
+        main.cleanup()
+        main.exit()
+
+def counterCheck( counterName, counterValue ):
+    """
+    Checks that TestON counters are consistent across all nodes and that
+    specified counter is in ONOS with the given value
+    """
+    import json
+    correctResults = main.TRUE
+    # Get onos counters results and consistentCheck
+    onosCounters, consistent = main.Counters.consistentCheck()
+    # Check for correct values
+    for i in range( len( main.activeNodes ) ):
+        current = onosCounters[i]
+        onosValue = None
+        try:
+            for database in current:
+                database = database.values()[0]
+                for counter in database:
+                    if counter.get( 'name' ) == counterName:
+                        onosValue = counter.get( 'value' )
+                        break
+        except AttributeError, e:
+            node = str( main.activeNodes[i] + 1 )
+            main.log.error( "ONOS" + node + " counters result " +
+                            "is not as expected" )
+            correctResults = main.FALSE
+        if onosValue == counterValue:
+            main.log.info( counterName + " counter value is correct" )
+        else:
+            main.log.error( counterName + " counter value is incorrect," +
+                            " expected value: " + str( counterValue )
+                            + " current value: " + str( onosValue ) )
+            correctResults = main.FALSE
+    return consistent and correctResults
diff --git a/TestON/tests/HAminorityRestart/dependencies/__init__.py b/TestON/tests/HAstopNodes/dependencies/__init__.py
similarity index 100%
copy from TestON/tests/HAminorityRestart/dependencies/__init__.py
copy to TestON/tests/HAstopNodes/dependencies/__init__.py
diff --git a/TestON/tests/HAminorityRestart/dependencies/obelisk.py b/TestON/tests/HAstopNodes/dependencies/obelisk.py
similarity index 99%
copy from TestON/tests/HAminorityRestart/dependencies/obelisk.py
copy to TestON/tests/HAstopNodes/dependencies/obelisk.py
index 4378a9b..d613806 100755
--- a/TestON/tests/HAminorityRestart/dependencies/obelisk.py
+++ b/TestON/tests/HAstopNodes/dependencies/obelisk.py
@@ -67,4 +67,3 @@
 if __name__ == '__main__':
     setLogLevel( 'info' )
     run()
-
diff --git a/TestON/tests/HAminorityRestart/dependencies/onos-gen-partitions b/TestON/tests/HAstopNodes/dependencies/onos-gen-partitions
similarity index 100%
copy from TestON/tests/HAminorityRestart/dependencies/onos-gen-partitions
copy to TestON/tests/HAstopNodes/dependencies/onos-gen-partitions