diff --git a/adapters/adtran_olt/adtran_olt_handler.py b/adapters/adtran_olt/adtran_olt_handler.py
new file mode 100644
index 0000000..ad32b84
--- /dev/null
+++ b/adapters/adtran_olt/adtran_olt_handler.py
@@ -0,0 +1,1400 @@
+# Copyright 2017-present Adtran, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import datetime
+import random
+import xmltodict
+
+from twisted.internet import reactor
+from twisted.internet.defer import returnValue, inlineCallbacks, succeed
+
+from codec.olt_state import OltState
+from adapters.adtran_common.download import Download
+from adapters.adtran_common.flow.flow_entry import FlowEntry
+from net.pio_zmq import PioClient
+from net.pon_zmq import PonClient
+from resources.adtran_olt_resource_manager import AdtranOltResourceMgr
+from adapters.adtran_common.adtran_device_handler import AdtranDeviceHandler
+from resources import adtranolt_platform as platform
+from adapters.adtran_common.net.rcmd import RCmd
+
+from pyvoltha.common.tech_profile.tech_profile import *
+from pyvoltha.common.openflow.utils import ofp, mk_flow_stat, in_port, output, vlan_vid
+from pyvoltha.adapters.common.frameio.frameio import hexify
+from pyvoltha.adapters.extensions.omci.omci import *
+from pyvoltha.protos.voltha_pb2 import Device
+from pyvoltha.protos.common_pb2 import AdminState, OperStatus
+from pyvoltha.protos.device_pb2 import ImageDownload, Image, Port
+from pyvoltha.protos.openflow_13_pb2 import OFPP_MAX, OFPC_GROUP_STATS, OFPC_PORT_STATS, \
+    OFPC_TABLE_STATS, OFPC_FLOW_STATS, ofp_switch_features, ofp_desc
+
+
+class AdtranOltHandler(AdtranDeviceHandler):
+    """
+    The OLT Handler is used to wrap a single instance of a 10G OLT 1-U pizza-box
+    """
+    MIN_OLT_HW_VERSION = datetime.datetime(2017, 1, 5)
+
+    # Full table output
+
+    GPON_OLT_HW_URI = '/restconf/data/gpon-olt-hw'
+    GPON_OLT_HW_STATE_URI = GPON_OLT_HW_URI + ':olt-state'
+    GPON_OLT_HW_CONFIG_URI = GPON_OLT_HW_URI + ':olt'
+    GPON_PON_CONFIG_LIST_URI = GPON_OLT_HW_CONFIG_URI + '/pon'
+
+    # Per-PON info
+
+    GPON_PON_STATE_URI = GPON_OLT_HW_STATE_URI + '/pon={}'        # .format(pon-id)
+    GPON_PON_CONFIG_URI = GPON_PON_CONFIG_LIST_URI + '={}'        # .format(pon-id)
+
+    GPON_ONU_CONFIG_LIST_URI = GPON_PON_CONFIG_URI + '/onus/onu'  # .format(pon-id)
+    GPON_ONU_CONFIG_URI = GPON_ONU_CONFIG_LIST_URI + '={}'        # .format(pon-id,onu-id)
+
+    GPON_TCONT_CONFIG_LIST_URI = GPON_ONU_CONFIG_URI + '/t-conts/t-cont'  # .format(pon-id,onu-id)
+    GPON_TCONT_CONFIG_URI = GPON_TCONT_CONFIG_LIST_URI + '={}'            # .format(pon-id,onu-id,alloc-id)
+
+    GPON_GEM_CONFIG_LIST_URI = GPON_ONU_CONFIG_URI + '/gem-ports/gem-port'  # .format(pon-id,onu-id)
+    GPON_GEM_CONFIG_URI = GPON_GEM_CONFIG_LIST_URI + '={}'                  # .format(pon-id,onu-id,gem-id)
+
+    GPON_PON_DISCOVER_ONU = '/restconf/operations/gpon-olt-hw:discover-onu'
+
+    BASE_ONU_OFFSET = 64
+
+    def __init__(self, **kwargs):
+        super(AdtranOltHandler, self).__init__(**kwargs)
+
+        self.status_poll = None
+        self.status_poll_interval = 5.0
+        self.status_poll_skew = self.status_poll_interval / 10
+        self._pon_agent = None
+        self._pio_agent = None
+        self._ssh_deferred = None
+        self._system_id = None
+        self._download_protocols = None
+        self._download_deferred = None
+        self._downloads = {}        # name -> Download obj
+        self._pio_exception_map = []
+
+        self.downstream_shapping_supported = True      # 1971320F1-ML-4154 and later
+
+        # FIXME:  Remove once we containerize.  Only exists to keep BroadCom OpenOMCI ONU Happy
+        #         when it reaches up our rear and tries to yank out a UNI port number
+        self.platform_class = None
+
+        # To keep broadcom ONU happy
+        self.platform = platform()           # TODO: Remove once tech-profiles & containerization are done !!!
+
+    def __del__(self):
+        # OLT Specific things here.
+        #
+        # If you receive this during 'enable' of the object, you probably threw an
+        # uncaught exception which triggered an errback in the VOLTHA core.
+        d, self.status_poll = self.status_poll, None
+
+        # Clean up base class as well
+        AdtranDeviceHandler.__del__(self)
+
+    def _cancel_deferred(self):
+        d1, self.status_poll = self.status_poll, None
+        d2, self._ssh_deferred = self._ssh_deferred, None
+        d3, self._download_deferred = self._download_deferred, None
+
+        for d in [d1, d2, d3]:
+            try:
+                if d is not None and not d.called:
+                    d.cancel()
+            except:
+                pass
+
+    def __str__(self):
+        return "AdtranOltHandler: {}".format(self.ip_address)
+
+    @property
+    def system_id(self):
+        return self._system_id
+
+    @system_id.setter
+    def system_id(self, value):
+        if self._system_id != value:
+            self._system_id = value
+
+            data = json.dumps({'olt-id': str(value)})
+            uri = AdtranOltHandler.GPON_OLT_HW_CONFIG_URI
+            self.rest_client.request('PATCH', uri, data=data, name='olt-system-id')
+
+    @inlineCallbacks
+    def get_device_info(self, device):
+        """
+        Perform an initial network operation to discover the device hardware
+        and software version. Serial Number would be helpful as well.
+
+        Upon successfully retrieving the information, remember to call the
+        'start_heartbeat' method to keep in contact with the device being managed
+
+        :param device: A voltha.Device object, with possible device-type
+                specific extensions. Such extensions shall be described as part of
+                the device type specification returned by device_types().
+        """
+        from codec.physical_entities_state import PhysicalEntitiesState
+        # TODO: After a CLI 'reboot' command, the device info may get messed up (prints labels and not values)
+        # #     Enter device and type 'show'
+        device = {
+            'model': 'n/a',
+            'hardware_version': 'unknown',
+            'serial_number': 'unknown',
+            'vendor': 'ADTRAN, Inc.',
+            'firmware_version': 'unknown',
+            'running-revision': 'unknown',
+            'candidate-revision': 'unknown',
+            'startup-revision': 'unknown',
+            'software-images': []
+        }
+        if self.is_virtual_olt:
+            returnValue(device)
+
+        try:
+            pe_state = PhysicalEntitiesState(self.netconf_client)
+            self.startup = pe_state.get_state()
+            results = yield self.startup
+
+            if results.ok:
+                modules = pe_state.get_physical_entities('adtn-phys-mod:module')
+
+                if isinstance(modules, list):
+                    module = modules[0]
+
+                    name = str(module.get('model-name', 'n/a')).translate(None, '?')
+                    model = str(module.get('model-number', 'n/a')).translate(None, '?')
+
+                    device['model'] = '{} - {}'.format(name, model) if len(name) > 0 else \
+                        module.get('parent-entity', 'n/a')
+                    device['hardware_version'] = str(module.get('hardware-revision',
+                                                                'n/a')).translate(None, '?')
+                    device['serial_number'] = str(module.get('serial-number',
+                                                             'n/a')).translate(None, '?')
+                    if 'software' in module:
+                        if 'software' in module['software']:
+                            software = module['software']['software']
+                            if isinstance(software, dict):
+                                device['running-revision'] = str(software.get('running-revision',
+                                                                              'n/a')).translate(None, '?')
+                                device['candidate-revision'] = str(software.get('candidate-revision',
+                                                                                'n/a')).translate(None, '?')
+                                device['startup-revision'] = str(software.get('startup-revision',
+                                                                              'n/a')).translate(None, '?')
+                            elif isinstance(software, list):
+                                for sw_item in software:
+                                    sw_type = sw_item.get('name', '').lower()
+                                    if sw_type == 'firmware':
+                                        device['firmware_version'] = str(sw_item.get('running-revision',
+                                                                                     'unknown')).translate(None, '?')
+                                    elif sw_type == 'software':
+                                        for rev_type in ['startup-revision',
+                                                         'running-revision',
+                                                         'candidate-revision']:
+                                            if rev_type in sw_item:
+                                                image = Image(name=rev_type,
+                                                              version=sw_item[rev_type],
+                                                              is_active=(rev_type == 'running-revision'),
+                                                              is_committed=True,
+                                                              is_valid=True,
+                                                              install_datetime='Not Available',
+                                                              hash='Not Available')
+                                                device['software-images'].append(image)
+
+                    # Update features based on version
+                    # Format expected to be similar to:  1971320F1-ML-4154
+
+                    running_version = next((image.version for image in device.get('software-images', list())
+                                           if image.is_active), '').split('-')
+                    if len(running_version) > 2:
+                        try:
+                            self.downstream_shapping_supported = int(running_version[-1]) >= 4154
+                        except ValueError:
+                            pass
+
+        except Exception as e:
+            self.log.exception('dev-info-failure', e=e)
+            raise
+
+        returnValue(device)
+
+    def initialize_resource_manager(self):
+        # Initialize the resource and tech profile managers
+        extra_args = '--olt_model {}'.format(self.resource_manager_key)
+        self.resource_mgr = AdtranOltResourceMgr(self.device_id,
+                                                 self.host_and_port,
+                                                 extra_args,
+                                                 self.default_resource_mgr_device_info)
+        self._populate_tech_profile_per_pon_port()
+
+    @property
+    def default_resource_mgr_device_info(self):
+        class AdtranOltDevInfo(object):
+            def __init__(self, pon_ports):
+                self.technology = "xgspon"
+                self.onu_id_start = 0
+                self.onu_id_end = platform.MAX_ONUS_PER_PON
+                self.alloc_id_start = platform.MIN_TCONT_ALLOC_ID
+                self.alloc_id_end = platform.MAX_TCONT_ALLOC_ID
+                self.gemport_id_start = platform.MIN_GEM_PORT_ID
+                self.gemport_id_end = platform.MAX_GEM_PORT_ID
+                self.pon_ports = len(pon_ports)
+                self.max_tconts = platform.MAX_TCONTS_PER_ONU
+                self.max_gem_ports = platform.MAX_GEM_PORTS_PER_ONU
+                self.intf_ids = pon_ports.keys()    # PON IDs
+
+        return AdtranOltDevInfo(self.southbound_ports)
+
+    def _populate_tech_profile_per_pon_port(self):
+        self.tech_profiles = {intf_id: self.resource_mgr.resource_managers[intf_id].tech_profile
+                              for intf_id in self.resource_mgr.device_info.intf_ids}
+
+        # Make sure we have as many tech_profiles as there are pon ports on
+        # the device
+        assert len(self.tech_profiles) == self.resource_mgr.device_info.pon_ports
+
+    def get_tp_path(self, intf_id, ofp_port_name):
+        # TODO: Should get Table id form the flow, as of now hardcoded to DEFAULT_TECH_PROFILE_TABLE_ID (64)
+        # 'tp_path' contains the suffix part of the tech_profile_instance path.
+        # The prefix to the 'tp_path' should be set to \
+        # TechProfile.KV_STORE_TECH_PROFILE_PATH_PREFIX by the ONU adapter.
+        return self.tech_profiles[intf_id].get_tp_path(DEFAULT_TECH_PROFILE_TABLE_ID,
+                                                       ofp_port_name)
+
+    def delete_tech_profile_instance(self, intf_id, onu_id, logical_port):
+        # Remove the TP instance associated with the ONU
+        ofp_port_name = self.get_ofp_port_name(intf_id, onu_id, logical_port)
+        tp_path = self.get_tp_path(intf_id, ofp_port_name)
+        return self.tech_profiles[intf_id].delete_tech_profile_instance(tp_path)
+
+    def get_ofp_port_name(self, pon_id, onu_id, logical_port_number):
+        parent_port_no = self.pon_id_to_port_number(pon_id)
+        child_device = self.adapter_agent.get_child_device(self.device_id,
+                                                           parent_port_no=parent_port_no, onu_id=onu_id)
+        if child_device is None:
+            self.log.error("could-not-find-child-device", parent_port_no=pon_id, onu_id=onu_id)
+            return None, None
+
+        ports = self.adapter_agent.get_ports(child_device.id, Port.ETHERNET_UNI)
+        port = next((port for port in ports if port.port_no == logical_port_number), None)
+        logical_port = self.adapter_agent.get_logical_port(self.logical_device_id,
+                                                           port.label)
+        ofp_port_name = (logical_port.ofp_port.name, logical_port.ofp_port.port_no)
+
+        return ofp_port_name
+
+    @inlineCallbacks
+    def enumerate_northbound_ports(self, device):
+        """
+        Enumerate all northbound ports of this device.
+
+        :param device: A voltha.Device object, with possible device-type
+                specific extensions.
+        :return: (Deferred or None).
+        """
+        try:
+            # Also get the MAC Address for the OLT
+            command = "ip link | grep -A1 eth0 | sed -n -e 's/^.*ether //p' | awk '{ print $1 }'"
+            rcmd = RCmd(self.ip_address, self.netconf_username, self.netconf_password,
+                        command)
+            address = yield rcmd.execute()
+            self.mac_address = address.replace('\n', '')
+            self.log.info("mac-addr", mac_addr=self.mac_address)
+
+        except Exception as e:
+            log.exception('mac-address', e=e)
+            raise
+
+        try:
+            from codec.ietf_interfaces import IetfInterfacesState
+            from nni_port import MockNniPort
+
+            ietf_interfaces = IetfInterfacesState(self.netconf_client)
+
+            if self.is_virtual_olt:
+                results = MockNniPort.get_nni_port_state_results()
+            else:
+                self.startup = ietf_interfaces.get_state()
+                results = yield self.startup
+
+            ports = ietf_interfaces.get_port_entries(results, 'ethernet')
+            returnValue(ports)
+
+        except Exception as e:
+            log.exception('enumerate_northbound_ports', e=e)
+            raise
+
+    def process_northbound_ports(self, device, results):
+        """
+        Process the results from the 'enumerate_northbound_ports' method.
+
+        :param device: A voltha.Device object, with possible device-type
+                specific extensions.
+        :param results: Results from the 'enumerate_northbound_ports' method that
+                you implemented. The type and contents are up to you to
+        :return: (Deferred or None).
+        """
+        from nni_port import NniPort, MockNniPort
+
+        for port in results.itervalues():
+            port_no = port.get('port_no')
+            assert port_no, 'Port number not found'
+
+            # May already exist if device was not fully reachable when first enabled
+            if port_no not in self.northbound_ports:
+                self.log.info('processing-nni', port_no=port_no, name=port['port_no'])
+                self.northbound_ports[port_no] = NniPort(self, **port) if not self.is_virtual_olt \
+                    else MockNniPort(self, **port)
+
+            if len(self.northbound_ports) >= self.max_nni_ports: # TODO: For now, limit number of NNI ports to make debugging easier
+                break
+
+        self.num_northbound_ports = len(self.northbound_ports)
+
+    def _olt_version(self):
+        #  Version
+        #     0     Unknown
+        #     1     V1 OMCI format
+        #     2     V2 OMCI format
+        #     3     2018-01-11 or later
+        version = 0
+        info = self._rest_support.get('module-info', [dict()])
+        hw_mod_ver_str = next((mod.get('revision') for mod in info
+                               if mod.get('module-name', '').lower() == 'gpon-olt-hw'), None)
+
+        if hw_mod_ver_str is not None:
+            try:
+                from datetime import datetime
+                hw_mod_dt = datetime.strptime(hw_mod_ver_str, '%Y-%m-%d')
+                version = 2 if hw_mod_dt >= datetime(2017, 9, 21) else 2
+
+            except Exception as e:
+                self.log.exception('ver-str-check', e=e)
+
+        return version
+
+    @inlineCallbacks
+    def enumerate_southbound_ports(self, device):
+        """
+        Enumerate all southbound ports of this device.
+
+        :param device: A voltha.Device object, with possible device-type
+                       specific extensions.
+        :return: (Deferred or None).
+        """
+        ###############################################################################
+        # Determine number of southbound ports. We know it is 16, but this keeps this
+        # device adapter generic for our other OLTs up to this point.
+
+        self.startup = self.rest_client.request('GET', self.GPON_PON_CONFIG_LIST_URI,
+                                                'pon-config')
+        try:
+            from codec.ietf_interfaces import IetfInterfacesState
+            from nni_port import MockNniPort
+
+            results = yield self.startup
+
+            ietf_interfaces = IetfInterfacesState(self.netconf_client)
+
+            if self.is_virtual_olt:
+                nc_results = MockNniPort.get_pon_port_state_results()
+            else:
+                self.startup = ietf_interfaces.get_state()
+                nc_results = yield self.startup
+
+            ports = ietf_interfaces.get_port_entries(nc_results, 'xpon')
+            if len(ports) == 0:
+                ports = ietf_interfaces.get_port_entries(nc_results,
+                                                         'channel-termination')
+            for data in results:
+                pon_id = data['pon-id']
+                port = ports[pon_id + 1]
+                port['pon-id'] = pon_id
+                port['admin_state'] = AdminState.ENABLED \
+                    if data.get('enabled', True)\
+                    else AdminState.DISABLED
+
+        except Exception as e:
+            log.exception('enumerate_southbound_ports', e=e)
+            raise
+
+        returnValue(ports)
+
+    def process_southbound_ports(self, device, results):
+        """
+        Process the results from the 'enumerate_southbound_ports' method.
+
+        :param device: A voltha.Device object, with possible device-type
+                specific extensions.
+        :param results: Results from the 'enumerate_southbound_ports' method that
+                you implemented. The type and contents are up to you to
+        :return: (Deferred or None).
+        """
+        from pon_port import PonPort
+
+        for pon in results.itervalues():
+            pon_id = pon.get('pon-id')
+            assert pon_id is not None, 'PON ID not found'
+            if pon['ifIndex'] is None:
+                pon['port_no'] = self.pon_id_to_port_number(pon_id)
+            else:
+                pass        # Need to adjust ONU numbering !!!!
+
+            # May already exist if device was not fully reachable when first enabled
+            if pon_id not in self.southbound_ports:
+                self.southbound_ports[pon_id] = PonPort(self, **pon)
+
+        self.num_southbound_ports = len(self.southbound_ports)
+
+    def pon(self, pon_id):
+        return self.southbound_ports.get(pon_id)
+
+    def complete_device_specific_activation(self, device, reconciling):
+        """
+        Perform an initial network operation to discover the device hardware
+        and software version. Serial Number would be helpful as well.
+
+        This method is called from within the base class's activate generator.
+
+        :param device: A voltha.Device object, with possible device-type
+                specific extensions. Such extensions shall be described as part of
+                the device type specification returned by device_types().
+
+        :param reconciling: (boolean) True if taking over for another VOLTHA
+        """
+        # ZeroMQ clients
+        self._zmq_startup()
+
+        # Download support
+        self._download_deferred = reactor.callLater(0, self._get_download_protocols)
+
+        # Register for adapter messages
+        self.adapter_agent.register_for_inter_adapter_messages()
+
+        # PON Status
+        self.status_poll = reactor.callLater(5, self.poll_for_status)
+        return succeed('Done')
+
+    def on_heatbeat_alarm(self, active):
+        if not active:
+            self.ready_network_access()
+
+    @inlineCallbacks
+    def _get_download_protocols(self):
+        if self._download_protocols is None:
+            try:
+                config = '<filter>' + \
+                          '<file-servers-state xmlns="http://www.adtran.com/ns/yang/adtran-file-servers">' + \
+                           '<profiles>' + \
+                            '<supported-protocol/>' + \
+                           '</profiles>' + \
+                          '</file-servers-state>' + \
+                         '</filter>'
+
+                results = yield self.netconf_client.get(config)
+
+                result_dict = xmltodict.parse(results.data_xml)
+                entries = result_dict['data']['file-servers-state']['profiles']['supported-protocol']
+                self._download_protocols = [entry['#text'].split(':')[-1] for entry in entries
+                                            if '#text' in entry]
+
+            except Exception as e:
+                self.log.exception('protocols', e=e)
+                self._download_protocols = None
+                self._download_deferred = reactor.callLater(10, self._get_download_protocols)
+
+    @inlineCallbacks
+    def ready_network_access(self):
+        # Check for port status
+        command = 'netstat -pan | grep -i 0.0.0.0:{} |  wc -l'.format(self.pon_agent_port)
+        rcmd = RCmd(self.ip_address, self.netconf_username, self.netconf_password, command)
+
+        try:
+            self.log.debug('check-request', command=command)
+            results = yield rcmd.execute()
+            self.log.info('check-results', results=results, result_type=type(results))
+            create_it = int(results) != 1
+
+        except Exception as e:
+            self.log.exception('find', e=e)
+            create_it = True
+
+        if create_it:
+            def v1_method():
+                command = 'mkdir -p /etc/pon_agent; touch /etc/pon_agent/debug.conf; '
+                command += 'ps -ae | grep -i ngpon2_agent; '
+                command += 'service_supervisor stop ngpon2_agent; service_supervisor start ngpon2_agent; '
+                command += 'ps -ae | grep -i ngpon2_agent'
+
+                self.log.debug('create-request', command=command)
+                return RCmd(self.ip_address, self.netconf_username, self.netconf_password, command)
+
+            def v2_v3_method():
+                # Old V2 method
+                # For V2 images, want -> export ZMQ_LISTEN_ON_ANY_ADDRESS=1
+                # For V3+ images, want -> export AGENT_LISTEN_ON_ANY_ADDRESS=1
+
+                # V3 unifies listening port, compatible with v2
+                cmd = "sed --in-place '/add feature/aexport ZMQ_LISTEN_ON_ANY_ADDRESS=1' " \
+                      "/etc/ngpon2_agent/ngpon2_agent_feature_flags; "
+                cmd += "sed --in-place '/add feature/aexport AGENT_LISTEN_ON_ANY_ADDRESS=1' " \
+                      "/etc/ngpon2_agent/ngpon2_agent_feature_flags; "
+
+                # Note: 'ps' commands are to help decorate the logfile with useful info
+                cmd += 'ps -ae | grep -i ngpon2_agent; '
+                cmd += 'service_supervisor stop ngpon2_agent; service_supervisor start ngpon2_agent; '
+                cmd += 'ps -ae | grep -i ngpon2_agent'
+
+                self.log.debug('create-request', command=cmd)
+                return RCmd(self.ip_address, self.netconf_username, self.netconf_password, cmd)
+
+            # Look for version
+            next_run = 15
+            version = v2_v3_method    # NOTE: Only v2 or later supported.
+
+            if version is not None:
+                try:
+                    rcmd = version()
+                    results = yield rcmd.execute()
+                    self.log.info('create-results', results=results, result_type=type(results))
+
+                except Exception as e:
+                    self.log.exception('mkdir-and-restart', e=e)
+        else:
+            next_run = 0
+
+        if next_run > 0:
+            self._ssh_deferred = reactor.callLater(next_run, self.ready_network_access)
+
+        returnValue('retrying' if next_run > 0 else 'ready')
+
+    def _zmq_startup(self):
+        # ZeroMQ clients
+        self._pon_agent = PonClient(self.ip_address,
+                                    port=self.pon_agent_port,
+                                    rx_callback=self.rx_pa_packet)
+
+        try:
+            self._pio_agent = PioClient(self.ip_address,
+                                        port=self.pio_port,
+                                        rx_callback=self.rx_pio_packet)
+        except Exception as e:
+            self._pio_agent = None
+            self.log.exception('pio-agent', e=e)
+
+    def _zmq_shutdown(self):
+        pon, self._pon_agent = self._pon_agent, None
+        pio, self._pio_agent = self._pio_agent, None
+
+        for c in [pon, pio]:
+            if c is not None:
+                try:
+                    c.shutdown()
+                except:
+                    pass
+
+    def _unregister_for_inter_adapter_messages(self):
+        try:
+            self.adapter_agent.unregister_for_inter_adapter_messages()
+        except:
+            pass
+
+    def disable(self):
+        self._cancel_deferred()
+
+        # Drop registration for adapter messages
+        self._unregister_for_inter_adapter_messages()
+        self._zmq_shutdown()
+        self._pio_exception_map = []
+
+        super(AdtranOltHandler, self).disable()
+
+    def reenable(self, done_deferred=None):
+        super(AdtranOltHandler, self).reenable(done_deferred=done_deferred)
+
+        # Only do the re-enable if we fully came up on the very first enable attempt.
+        # If we had not, the base class will have initiated the 'activate' for us
+
+        if self._initial_enable_complete:
+            self._zmq_startup()
+            self.adapter_agent.register_for_inter_adapter_messages()
+            self.status_poll = reactor.callLater(1, self.poll_for_status)
+
+    def reboot(self):
+        if not self._initial_enable_complete:
+            # Never contacted the device on the initial startup, do 'activate' steps instead
+            return
+
+        self._cancel_deferred()
+
+        # Drop registration for adapter messages
+        self._unregister_for_inter_adapter_messages()
+        self._zmq_shutdown()
+
+        # Download supported protocols may change (if new image gets activated)
+        self._download_protocols = None
+
+        super(AdtranOltHandler, self).reboot()
+
+    def _finish_reboot(self, timeout, previous_oper_status, previous_conn_status):
+        super(AdtranOltHandler, self)._finish_reboot(timeout, previous_oper_status, previous_conn_status)
+
+        self.ready_network_access()
+
+        # Download support
+        self._download_deferred = reactor.callLater(0, self._get_download_protocols)
+
+        # Register for adapter messages
+        self.adapter_agent.register_for_inter_adapter_messages()
+        self._zmq_startup()
+
+        self.status_poll = reactor.callLater(5, self.poll_for_status)
+
+    def delete(self):
+        self._cancel_deferred()
+
+        # Drop registration for adapter messages
+        self._unregister_for_inter_adapter_messages()
+        self._zmq_shutdown()
+
+        super(AdtranOltHandler, self).delete()
+
+    def rx_pa_packet(self, packets):
+        if self._pon_agent is not None:
+            for packet in packets:
+                try:
+                    pon_id, onu_id, msg_bytes, is_omci = self._pon_agent.decode_packet(packet)
+
+                    if is_omci:
+                        proxy_address = self._pon_onu_id_to_proxy_address(pon_id, onu_id)
+
+                        if proxy_address is not None:
+                            self.adapter_agent.receive_proxied_message(proxy_address, msg_bytes)
+
+                except Exception as e:
+                    self.log.exception('rx-pon-agent-packet', e=e)
+
+    def _compute_logical_port_no(self, port_no, evc_map, packet):
+        logical_port_no = None
+
+        # Upstream direction?
+        if self.is_pon_port(port_no):
+            #TODO: Validate the evc-map name
+            from python.adapters.adtran.adtran_common.flow.evc_map import EVCMap
+            map_info = EVCMap.decode_evc_map_name(evc_map)
+            logical_port_no = int(map_info.get('ingress-port'))
+
+            if logical_port_no is None:
+                # Get PON
+                pon = self.get_southbound_port(port_no)
+
+                # Examine Packet and decode gvid
+                if packet is not None:
+                    pass
+
+        elif self.is_nni_port(port_no):
+            nni = self.get_northbound_port(port_no)
+            logical_port = nni.get_logical_port() if nni is not None else None
+            logical_port_no = logical_port.ofp_port.port_no if logical_port is not None else None
+
+        # TODO: Need to decode base on port_no & evc_map
+        return logical_port_no
+
+    def rx_pio_packet(self, packets):
+        self.log.debug('rx-packet-in', type=type(packets), data=packets)
+        assert isinstance(packets, list), 'Expected a list of packets'
+
+        # TODO self._pio_agent.socket.socket.closed might be a good check here as well
+        if self.logical_device_id is not None and self._pio_agent is not None:
+            for packet in packets:
+                url_type = self._pio_agent.get_url_type(packet)
+                if url_type == PioClient.UrlType.EVCMAPS_RESPONSE:
+                    exception_map = self._pio_agent.decode_query_response_packet(packet)
+                    self.log.debug('rx-pio-packet', exception_map=exception_map)
+                    # update latest pio exception map
+                    self._pio_exception_map = exception_map
+
+                elif url_type == PioClient.UrlType.PACKET_IN:
+                    try:
+                        from scapy.layers.l2 import Ether, Dot1Q
+                        ifindex, evc_map, packet = self._pio_agent.decode_packet(packet)
+
+                        # convert ifindex to physical port number
+                        # pon port numbers start at 60001 and end at 600016 (16 pons)
+                        if ifindex > 60000 and ifindex < 60017:
+                            port_no = (ifindex - 60000) + 4
+                        # nni port numbers start at 1401 and end at 1404 (16 nnis)
+                        elif ifindex > 1400 and ifindex < 1405:
+                            port_no = ifindex - 1400
+                        else:
+                            raise ValueError('Unknown physical port. ifindex: {}'.format(ifindex))
+
+                        logical_port_no = self._compute_logical_port_no(port_no, evc_map, packet)
+
+                        if logical_port_no is not None:
+                            if self.is_pon_port(port_no) and packet.haslayer(Dot1Q):
+                                # Scrub g-vid
+                                inner_pkt = packet.getlayer(Dot1Q)
+                                assert inner_pkt.haslayer(Dot1Q), 'Expected a C-Tag'
+                                packet = Ether(src=packet.src, dst=packet.dst, type=inner_pkt.type)\
+                                    / inner_pkt.payload
+
+                            self.adapter_agent.send_packet_in(logical_device_id=self.logical_device_id,
+                                                              logical_port_no=logical_port_no,
+                                                              packet=str(packet))
+                        else:
+                            self.log.warn('logical-port-not-found', port_no=port_no, evc_map=evc_map)
+
+                    except Exception as e:
+                        self.log.exception('rx-pio-packet', e=e)
+
+                else:
+                    self.log.warn('packet-in-unknown-url-type', url_type=url_type)
+
+    def packet_out(self, egress_port, msg):
+        """
+        Pass a packet_out message content to adapter so that it can forward it
+        out to the device. This is only called on root devices.
+
+        :param egress_port: egress logical port number
+        :param msg: actual message
+        :return: None        """
+
+        if self.pio_port is not None:
+            from scapy.layers.l2 import Ether, Dot1Q
+            from scapy.layers.inet import UDP
+
+            self.log.debug('sending-packet-out', egress_port=egress_port,
+                           msg=hexify(msg))
+            pkt = Ether(msg)
+
+            # Remove any extra tags
+            while pkt.type == 0x8100:
+                msg_hex = hexify(msg)
+                msg_hex = msg_hex[:24] + msg_hex[32:]
+                bytes = []
+                msg_hex = ''.join(msg_hex.split(" "))
+                for i in range(0, len(msg_hex), 2):
+                    bytes.append(chr(int(msg_hex[i:i+2], 16)))
+
+                msg = ''.join(bytes)
+                pkt = Ether(msg)
+
+            if self._pio_agent is not None:
+                port, ctag, vlan_id, evcmapname = FlowEntry.get_packetout_info(self, egress_port)
+                exceptiontype = None
+                if pkt.type == FlowEntry.EtherType.EAPOL:
+                    exceptiontype = 'eapol'
+                    ctag = self.utility_vlan
+                elif pkt.type == 2:
+                    exceptiontype = 'igmp'
+                elif pkt.type == FlowEntry.EtherType.IPv4:
+                    if UDP in pkt and pkt[UDP].sport == 67 and pkt[UDP].dport == 68:
+                        exceptiontype = 'dhcp'
+
+                if exceptiontype is None:
+                    self.log.warn('packet-out-exceptiontype-unknown', eEtherType=pkt.type)
+
+                elif port is not None and ctag is not None and vlan_id is not None and \
+                     evcmapname is not None and self.pio_exception_exists(evcmapname, exceptiontype):
+
+                    self.log.debug('sending-pio-packet-out', port=port, ctag=ctag, vlan_id=vlan_id,
+                                   evcmapname=evcmapname, exceptiontype=exceptiontype)
+                    out_pkt = (
+                        Ether(src=pkt.src, dst=pkt.dst) /
+                        Dot1Q(vlan=vlan_id) /
+                        Dot1Q(vlan=ctag, type=pkt.type) /
+                        pkt.payload
+                    )
+                    data = self._pio_agent.encode_packet(port, str(out_pkt), evcmapname, exceptiontype)
+                    self.log.debug('pio-packet-out', message=data)
+                    try:
+                        self._pio_agent.send(data)
+
+                    except Exception as e:
+                        self.log.exception('pio-send', egress_port=egress_port, e=e)
+                else:
+                    self.log.warn('packet-out-flow-not-found', egress_port=egress_port)
+
+    def pio_exception_exists(self, name, exp):
+        # verify exception is in the OLT's reported exception map for this evcmap name
+        if exp is None:
+            return False
+        entry = next((entry for entry in self._pio_exception_map if entry['evc-map-name'] == name), None)
+        if entry is None:
+            return False
+        if exp not in entry['exception-types']:
+            return False
+        return True
+
+    def send_packet_exceptions_request(self):
+        if self._pio_agent is not None:
+            request = self._pio_agent.query_request_packet()
+            try:
+                self._pio_agent.send(request)
+
+            except Exception as e:
+                self.log.exception('pio-send', e=e)
+
+    def poll_for_status(self):
+        self.log.debug('Initiating-status-poll')
+
+        device = self.adapter_agent.get_device(self.device_id)
+
+        if device.admin_state == AdminState.ENABLED and\
+                device.oper_status != OperStatus.ACTIVATING and\
+                self.rest_client is not None:
+            uri = AdtranOltHandler.GPON_OLT_HW_STATE_URI
+            name = 'pon-status-poll'
+            self.status_poll = self.rest_client.request('GET', uri, name=name)
+            self.status_poll.addBoth(self.status_poll_complete)
+        else:
+            self.status_poll = reactor.callLater(0, self.status_poll_complete, 'inactive')
+
+    def status_poll_complete(self, results):
+        """
+        Results of the status poll
+        :param results:
+        """
+        from pon_port import PonPort
+
+        if isinstance(results, dict) and 'pon' in results:
+            try:
+                self.log.debug('status-success')
+                for pon_id, pon in OltState(results).pons.iteritems():
+                    pon_port = self.southbound_ports.get(pon_id, None)
+
+                    if pon_port is not None and pon_port.state == PonPort.State.RUNNING:
+                        pon_port.process_status_poll(pon)
+
+            except Exception as e:
+                self.log.exception('PON-status-poll', e=e)
+
+        # Reschedule
+
+        delay = self.status_poll_interval
+        delay += random.uniform(-delay / 10, delay / 10)
+
+        self.status_poll = reactor.callLater(delay, self.poll_for_status)
+
+    def _create_utility_flow(self):
+        nni_port = self.northbound_ports.get(1).port_no
+        pon_port = self.southbound_ports.get(0).port_no
+
+        return mk_flow_stat(
+            priority=200,
+            match_fields=[
+                in_port(nni_port),
+                vlan_vid(ofp.OFPVID_PRESENT + self.utility_vlan)
+            ],
+            actions=[output(pon_port)]
+        )
+
+    @inlineCallbacks
+    def update_flow_table(self, flows, device):
+        """
+        Update the flow table on the OLT.  If an existing flow is not in the list, it needs
+        to be removed from the device.
+
+        :param flows: List of flows that should be installed upon completion of this function
+        :param device: A voltha.Device object, with possible device-type
+                       specific extensions.
+        """
+        self.log.debug('bulk-flow-update', num_flows=len(flows),
+                       device_id=device.id, flows=flows)
+
+        valid_flows = []
+
+        if flows:
+            # Special helper egress Packet In/Out flows
+            special_flow = self._create_utility_flow()
+            valid_flow, evc = FlowEntry.create(special_flow, self)
+
+            if valid_flow is not None:
+                valid_flows.append(valid_flow.flow_id)
+
+            if evc is not None:
+                try:
+                    evc.schedule_install()
+                    self.add_evc(evc)
+
+                except Exception as e:
+                    evc.status = 'EVC Install Exception: {}'.format(e.message)
+                    self.log.exception('EVC-install', e=e)
+
+        # verify exception flows were installed by OLT PET process
+        reactor.callLater(5, self.send_packet_exceptions_request)
+
+        # Now process bulk flows
+        for flow in flows:
+            try:
+                # Try to create an EVC.
+                #
+                # The first result is the flow entry that was created. This could be a match to an
+                # existing flow since it is a bulk update.  None is returned only if no match to
+                # an existing entry is found and decode failed (unsupported field)
+                #
+                # The second result is the EVC this flow should be added to. This could be an
+                # existing flow (so your adding another EVC-MAP) or a brand new EVC (no existing
+                # EVC-MAPs).  None is returned if there are not a valid EVC that can be created YET.
+
+                valid_flow, evc = FlowEntry.create(flow, self)
+
+                if valid_flow is not None:
+                    valid_flows.append(valid_flow.flow_id)
+
+                if evc is not None:
+                    try:
+                        evc.schedule_install()
+                        self.add_evc(evc)
+
+                    except Exception as e:
+                        evc.status = 'EVC Install Exception: {}'.format(e.message)
+                        self.log.exception('EVC-install', e=e)
+
+            except Exception as e:
+                self.log.exception('bulk-flow-update-add', e=e)
+
+        # Now drop all flows from this device that were not in this bulk update
+        try:
+            yield FlowEntry.drop_missing_flows(self, valid_flows)
+
+        except Exception as e:
+            self.log.exception('bulk-flow-update-remove', e=e)
+
+    def remove_from_flow_table(self, _flows):
+        """
+        Remove flows from the device
+
+        :param _flows: (list) Flows
+        """
+        raise NotImplementedError
+
+    def add_to_flow_table(self, _flows):
+        """
+        Remove flows from the device
+
+        :param _flows: (list) Flows
+        """
+        raise NotImplementedError
+
+    def get_ofp_device_info(self, device):
+        """
+        Retrieve the OLT device info. This includes the ofp_desc and
+        ofp_switch_features. The existing ofp structures can be used,
+        or all the attributes get added to the Device definition or a new proto
+        definition gets created. This API will allow the Core to create a
+        LogicalDevice associated with this device (OLT only).
+        :param device: device
+        :return: Proto Message (TBD)
+        """
+        from pyvoltha.protos.inter_container_pb2 import SwitchCapability
+        version = device.images.image[0].version
+
+        return SwitchCapability(
+            desc=ofp_desc(mfr_desc='VOLTHA Project',
+                          hw_desc=device.hardware_version,
+                          sw_desc=version,
+                          serial_num=device.serial_number,
+                          dp_desc='n/a'),
+            switch_features=ofp_switch_features(n_buffers=256,   # TODO fake for now
+                                                n_tables=2,      # TODO ditto
+                                                capabilities=(   # TODO and ditto
+                                                    OFPC_FLOW_STATS |
+                                                    OFPC_TABLE_STATS |
+                                                    OFPC_PORT_STATS |
+                                                    OFPC_GROUP_STATS))
+        )
+
+    def get_ofp_port_info(self, device, port_no):
+        """
+        Retrieve the port info. This includes the ofp_port. The existing ofp
+        structure can be used, or all the attributes get added to the Port
+        definitions or a new proto definition gets created.  This API will allow
+        the Core to create a LogicalPort associated with this device.
+        :param device: device
+        :param port_no: port number
+        :return: Proto Message (TBD)
+        """
+        from pyvoltha.protos.inter_container_pb2 import PortCapability
+        # Since the adapter created the device port then it has the reference of the port to
+        # return the capability.   TODO:  Do a lookup on the NNI port number and return the
+        # appropriate attributes
+        self.log.info('get_ofp_port_info', port_no=port_no,
+                      info=self.ofp_port_no, device_id=device.id)
+
+        nni = self.get_northbound_port(port_no)
+        if nni is not None:
+            lp = nni.get_logical_port()
+            if lp is not None:
+                return PortCapability(port=lp)
+
+    # @inlineCallbacks
+    def send_proxied_message(self, proxy_address, msg):
+        self.log.debug('sending-proxied-message', msg=msg)
+
+        if isinstance(msg, Packet):
+            msg = str(msg)
+
+        if self._pon_agent is not None:
+            pon_id, onu_id = self._proxy_address_to_pon_onu_id(proxy_address)
+
+            pon = self.southbound_ports.get(pon_id)
+
+            if pon is not None and pon.enabled:
+                onu = pon.onu(onu_id)
+
+                if onu is not None and onu.enabled:
+                    data = self._pon_agent.encode_omci_packet(msg, pon_id, onu_id)
+                    try:
+                        self._pon_agent.send(data)
+
+                    except Exception as e:
+                        self.log.exception('pon-agent-send', pon_id=pon_id, onu_id=onu_id, e=e)
+                else:
+                    self.log.debug('onu-invalid-or-disabled', pon_id=pon_id, onu_id=onu_id)
+            else:
+                self.log.debug('pon-invalid-or-disabled', pon_id=pon_id)
+
+    def _onu_offset(self, onu_id):
+        # Start ONU's just past the southbound PON port numbers. Since ONU ID's start
+        # at zero, add one
+        # assert AdtranOltHandler.BASE_ONU_OFFSET > (self.num_northbound_ports + self.num_southbound_ports + 1)
+        assert AdtranOltHandler.BASE_ONU_OFFSET > (4 + self.num_southbound_ports + 1)  # Skip over uninitialized ports
+        return AdtranOltHandler.BASE_ONU_OFFSET + onu_id
+
+    def _pon_onu_id_to_proxy_address(self, pon_id, onu_id):
+        if pon_id in self.southbound_ports:
+            pon = self.southbound_ports[pon_id]
+            onu = pon.onu(onu_id)
+            proxy_address = onu.proxy_address if onu is not None else None
+
+        else:
+            proxy_address = None
+
+        return proxy_address
+
+    def _proxy_address_to_pon_onu_id(self, proxy_address):
+        """
+        Convert the proxy address to the PON-ID and ONU-ID
+        :param proxy_address: (ProxyAddress)
+        :return: (tuple) pon-id, onu-id
+        """
+        onu_id = proxy_address.onu_id
+        pon_id = self._port_number_to_pon_id(proxy_address.channel_id)
+
+        return pon_id, onu_id
+
+    def pon_id_to_port_number(self, pon_id):
+        return pon_id + 1 + 4   # Skip over uninitialized ports
+
+    def _port_number_to_pon_id(self, port):
+        if self.is_uni_port(port):
+            # Convert to OLT device port
+            port = platform.intf_id_from_uni_port_num(port)
+
+        return port - 1 - 4  # Skip over uninitialized ports
+
+    def is_pon_port(self, port):
+        return self._port_number_to_pon_id(port) in self.southbound_ports
+
+    def is_uni_port(self, port):
+            return OFPP_MAX >= port >= (5 << 11)
+
+    def get_southbound_port(self, port):
+        pon_id = self._port_number_to_pon_id(port)
+        return self.southbound_ports.get(pon_id, None)
+
+    def get_northbound_port(self, port):
+        return self.northbound_ports.get(port, None)
+
+    def get_port_name(self, port, logical_name=False):
+        """
+        Get the name for a port
+
+        Port names are used in various ways within and outside of VOLTHA.
+        Typically, the physical port name will be used during device handler conversations
+        with the hardware (REST, NETCONF, ...) while the logical port name is what the
+        outside world (ONOS, SEBA, ...) uses.
+
+        All ports have a physical port name, but only ports exposed through VOLTHA
+        as a logical port will have a logical port name
+        """
+        if self.is_nni_port(port):
+            port = self.get_northbound_port(port)
+            return port.logical_port_name if logical_name else port.physical_port_name
+
+        if self.is_pon_port(port):
+            port = self.get_southbound_port(port)
+            return port.logical_port_name if logical_name else port.physical_port_name
+
+        if self.is_uni_port(port):
+            return 'uni-{}'.format(port)
+
+        if self.is_logical_port(port):
+            raise NotImplemented('Logical OpenFlow ports are not supported')
+
+    def _update_download_status(self, request, download):
+        if download is not None:
+            request.state = download.download_state
+            request.reason = download.failure_reason
+            request.image_state = download.image_state
+            request.additional_info = download.additional_info
+            request.downloaded_bytes = download.downloaded_bytes
+        else:
+            request.state = ImageDownload.DOWNLOAD_UNKNOWN
+            request.reason = ImageDownload.UNKNOWN_ERROR
+            request.image_state = ImageDownload.IMAGE_UNKNOWN
+            request.additional_info = "Download request '{}' not found".format(request.name)
+            request.downloaded_bytes = 0
+
+        self.adapter_agent.update_image_download(request)
+
+    def start_download(self, device, request, done):
+        """
+        This is called to request downloading a specified image into
+        the standby partition of a device based on a NBI call.
+
+        :param device: A Voltha.Device object.
+        :param request: A Voltha.ImageDownload object.
+        :param done: (Deferred) Deferred to fire when done
+        :return: (Deferred) Shall be fired to acknowledge the download.
+        """
+        log.info('image_download', request=request)
+
+        try:
+            if not self._initial_enable_complete:
+                # Never contacted the device on the initial startup, do 'activate' steps instead
+                raise Exception('Device has not finished initial activation')
+
+            if request.name in self._downloads:
+                raise Exception("Download request with name '{}' already exists".
+                                format(request.name))
+            try:
+                download = Download.create(self, request, self._download_protocols)
+
+            except Exception:
+                request.additional_info = 'Download request creation failed due to exception'
+                raise
+
+            try:
+                self._downloads[download.name] = download
+                self._update_download_status(request, download)
+                done.callback('started')
+                return done
+
+            except Exception:
+                request.additional_info = 'Download request startup failed due to exception'
+                del self._downloads[download.name]
+                download.cancel_download(request)
+                raise
+
+        except Exception as e:
+            self.log.exception('create', e=e)
+
+            request.reason = ImageDownload.UNKNOWN_ERROR if self._initial_enable_complete\
+                else ImageDownload.DEVICE_BUSY
+            request.state = ImageDownload.DOWNLOAD_FAILED
+            if not request.additional_info:
+                request.additional_info = e.message
+
+            self.adapter_agent.update_image_download(request)
+
+            # restore admin state to enabled
+            device.admin_state = AdminState.ENABLED
+            self.adapter_agent.update_device(device)
+            raise
+
+    def download_status(self, device, request, done):
+        """
+        This is called to inquire about a requested image download status based
+        on a NBI call.
+
+        The adapter is expected to update the DownloadImage DB object with the
+        query result
+
+        :param device: A Voltha.Device object.
+        :param request: A Voltha.ImageDownload object.
+        :param done: (Deferred) Deferred to fire when done
+
+        :return: (Deferred) Shall be fired to acknowledge
+        """
+        log.info('download_status', request=request)
+        download = self._downloads.get(request.name)
+
+        self._update_download_status(request, download)
+
+        if request.state not in [ImageDownload.DOWNLOAD_STARTED,
+                                 ImageDownload.DOWNLOAD_SUCCEEDED,
+                                 ImageDownload.DOWNLOAD_FAILED]:
+            # restore admin state to enabled
+            device.admin_state = AdminState.ENABLED
+            self.adapter_agent.update_device(device)
+
+        done.callback(request.state)
+        return done
+
+    def cancel_download(self, device, request, done):
+        """
+        This is called to cancel a requested image download based on a NBI
+        call.  The admin state of the device will not change after the
+        download.
+
+        :param device: A Voltha.Device object.
+        :param request: A Voltha.ImageDownload object.
+        :param done: (Deferred) Deferred to fire when done
+
+        :return: (Deferred) Shall be fired to acknowledge
+        """
+        log.info('cancel_download', request=request)
+
+        download = self._downloads.get(request.name)
+
+        if download is not None:
+            del self._downloads[request.name]
+            result = download.cancel_download(request)
+            self._update_download_status(request, download)
+            done.callback(result)
+        else:
+            self._update_download_status(request, download)
+            done.errback(KeyError('Download request not found'))
+
+        if device.admin_state == AdminState.DOWNLOADING_IMAGE:
+            device.admin_state = AdminState.ENABLED
+            self.adapter_agent.update_device(device)
+
+        return done
+
+    def activate_image(self, device, request, done):
+        """
+        This is called to activate a downloaded image from a standby partition
+        into active partition.
+
+        Depending on the device implementation, this call may or may not
+        cause device reboot. If no reboot, then a reboot is required to make
+        the activated image running on device
+
+        :param device: A Voltha.Device object.
+        :param request: A Voltha.ImageDownload object.
+        :param done: (Deferred) Deferred to fire when done
+
+        :return: (Deferred) OperationResponse object.
+        """
+        log.info('activate_image', request=request)
+
+        download = self._downloads.get(request.name)
+        if download is not None:
+            del self._downloads[request.name]
+            result = download.activate_image()
+            self._update_download_status(request, download)
+            done.callback(result)
+        else:
+            self._update_download_status(request, download)
+            done.errback(KeyError('Download request not found'))
+
+        # restore admin state to enabled
+        device.admin_state = AdminState.ENABLED
+        self.adapter_agent.update_device(device)
+        return done
+
+    def revert_image(self, device, request, done):
+        """
+        This is called to deactivate the specified image at active partition,
+        and revert to previous image at standby partition.
+
+        Depending on the device implementation, this call may or may not
+        cause device reboot. If no reboot, then a reboot is required to
+        make the previous image running on device
+
+        :param device: A Voltha.Device object.
+        :param request: A Voltha.ImageDownload object.
+        :param done: (Deferred) Deferred to fire when done
+
+        :return: (Deferred) OperationResponse object.
+        """
+        log.info('revert_image', request=request)
+
+        download = self._downloads.get(request.name)
+        if download is not None:
+            del self._downloads[request.name]
+            result = download.revert_image()
+            self._update_download_status(request, download)
+            done.callback(result)
+        else:
+            self._update_download_status(request, download)
+            done.errback(KeyError('Download request not found'))
+
+        # restore admin state to enabled
+        device.admin_state = AdminState.ENABLED
+        self.adapter_agent.update_device(device)
+        return done
+
+    def add_onu_device(self, pon_id, onu_id, serial_number):
+        onu_device = self.adapter_agent.get_child_device(self.device_id,
+                                                         serial_number=serial_number)
+        if onu_device is not None:
+            return onu_device
+
+        try:
+            # NOTE - channel_id of onu is set to pon_id
+            pon_port = self.pon_id_to_port_number(pon_id)
+            proxy_address = Device.ProxyAddress(device_id=self.device_id,
+                                                channel_id=pon_port,
+                                                onu_id=onu_id,
+                                                onu_session_id=onu_id)
+
+            self.log.debug("added-onu", port_no=pon_id,
+                           onu_id=onu_id, serial_number=serial_number,
+                           proxy_address=proxy_address)
+
+            self.adapter_agent.add_onu_device(
+                parent_device_id=self.device_id,
+                parent_port_no=pon_port,
+                vendor_id=serial_number[:4],
+                proxy_address=proxy_address,
+                root=True,
+                serial_number=serial_number,
+                admin_state=AdminState.ENABLED,
+            )
+
+        except Exception as e:
+            self.log.exception('onu-activation-failed', e=e)
+            return None
+
+    def setup_onu_tech_profile(self, pon_id, onu_id, logical_port_number):
+        # Send ONU Adapter related tech profile information.
+        self.log.debug('add-tech-profile-info')
+
+        uni_id = self.platform.uni_id_from_uni_port(logical_port_number)
+        parent_port_no = self.pon_id_to_port_number(pon_id)
+        onu_device = self.adapter_agent.get_child_device(self.device_id,
+                                                         onu_id=onu_id,
+                                                         parent_port_no=parent_port_no)
+
+        ofp_port_name, ofp_port_no = self.get_ofp_port_name(pon_id, onu_id,
+                                                            logical_port_number)
+        if ofp_port_name is None:
+            self.log.error("port-name-not-found")
+            return
+
+        tp_path = self.get_tp_path(pon_id, ofp_port_name)
+
+        self.log.debug('Load-tech-profile-request-to-onu-handler', tp_path=tp_path)
+
+        msg = {'proxy_address': onu_device.proxy_address, 'uni_id': uni_id,
+               'event': 'download_tech_profile', 'event_data': tp_path}
+
+        # Send the event message to the ONU adapter
+        self.adapter_agent.publish_inter_adapter_message(onu_device.id, msg)
