diff --git a/README.md b/README.md
index 75e5c4e..f1ac476 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,87 @@
-ONOS OLT OpenFlow Control Application
-=====================================
+# org.opencord.org
 
-Build
------
+This ONOS applications is responsible to configure the flows
+required to manage an OLT Device as reported by VOLTHA.
 
-Let's build all the code
+## Configuration
 
+The `org.opencord.olt` application depends on `org.opencord.sadis` and exposes 
+the following configuration:
+
+```shell
+karaf@root > cfg get org.opencord.olt.impl.Olt
+org.opencord.olt.impl.Olt
+    name=defaultBpId, type=string, value=Default, defaultValue=Default, description=Default bandwidth profile id that is used for authentication trap flows.
+    name=flowProcessingThreads, type=integer, value=8, defaultValue=8, description=Number of threads used to process flows.
+    name=multicastServiceName, type=string, value=MC, defaultValue=MC, description=Default multicast service name.
+    name=requeueDelay, type=integer, value=500, defaultValue=500, description=Delay in ms to put an event back in the queue, used to avoid retrying things to often if conditions are not met.
+    name=subscriberProcessingThreads, type=integer, value=8, defaultValue=8, description=Number of threads used to process flows.
+
+karaf@root > cfg get org.opencord.olt.impl.OltFlowService
+org.opencord.olt.impl.OltFlowService
+    name=enableDhcpOnNni, type=boolean, value=true, defaultValue=false, description=Create DHCP trap flow on NNI port(s).
+    name=enablePppoe, type=boolean, value=false, defaultValue=false, description=Send PPPoED authentication trap flows before subscriber provisioning.
+    name=defaultTechProfileId, type=integer, value=64, defaultValue=64, description=Default technology profile id that is used for authentication trap flows.
+    name=enableIgmpOnNni, type=boolean, value=false, defaultValue=false, description=Create IGMP trap flow on NNI port(s).
+    name=enableEapol, type=boolean, value=true, defaultValue=true, description=Send EAPOL authentication trap flows before subscriber provisioning.
+    name=enableDhcpV6, type=boolean, value=false, defaultValue=false, description=Enable flows for DHCP v6 if dhcp is required in sadis config.
+    name=enableDhcpV4, type=boolean, value=true, defaultValue=true, description=Enable flows for DHCP v4 if dhcp is required in sadis config.
+    
+karaf@root > cfg get org.opencord.olt.impl.OltMeterService
+org.opencord.olt.impl.OltMeterService
+    name=deleteMeters, type=boolean, value=true, defaultValue=true, description=Delete meters when reference count drops to zero.
+
+
+```
+
+## CLI commands
+
+```text
+volt-add-subscriber-access                                                           (Adds a subscriber to an access device)
+volt-bpmeter-mappings         (Shows information about programmed meters, including the relation with the Bandwidth Profile)
+volt-failed-subscribers                                                         (Shows subscribers that failed provisioning)
+volt-olts                                                                                    (Shows vOLTs connected to ONOS)
+volt-port-status                                    (Shows information about the OLT ports (default EAPOL, subscriber flows)
+volt-programmed-meters        (Shows information about programmed meters, including the relation with the Bandwidth Profile)
+volt-programmed-subscribers                                                  (Shows subscribers programmed in the dataplane)
+volt-remove-subscriber-access                                                        (Adds a subscriber to an access device)
+volt-requested-subscribers (Shows subscribers programmed by the operator. Their data-plane status depends on the ONU status)
+
+```
+
+## App Design
+
+The `org.opencord.olt` application internal structure reflects the following diagram:
+
+![OLT App Diagram](./assets/diagram.png)
+
+## Install the app on a running ONOS
+
+> _**Prerequisites**_
+> 
+> - A running ONOS cluster (can be a single node cluster)
+> - ONOS REST APIs exposed out of the kubernetes cluster and reachable from your machine (we used port 30120 in the following example)
+
+
+If you want to try out the app on a running ONOS cluster you can follow this procedure: 
+
+1) Build the app (requires Java 11 to be installed)
+    ```shell
     mvn clean install
+    ```
+2) Uninstall the current version of the app:
+    ```shell
+    curl --fail -sSL --user karaf:karaf --noproxy 127.0.0.1  -X DELETE http://127.0.0.1:30120/onos/v1/applications/org.opencord.olt
+    ```
+   You should see the following confirmation message in the logs:
+    ```shell
+    17:15:39.279 INFO  [ApplicationManager] Application org.opencord.olt has been uninstalled
+    ```
+3) Install the new version of the app
+    ```shell
+    curl --fail -sSL --user karaf:karaf --noproxy 127.0.0.1  -X POST -HContent-Type:application/octet-stream http://127.0.0.1:30120/onos/v1/applications?activate=true --data-binary @app/target/olt-app-5.0.0-SNAPSHOT.oar
+    ```
+   you should see:
+    ```shell
+    17:55:37.197 INFO  [ApplicationManager] Application org.opencord.olt has been activated
+    ```
\ No newline at end of file
diff --git a/TEST-README.md b/TEST-README.md
deleted file mode 100644
index 63f8686..0000000
--- a/TEST-README.md
+++ /dev/null
@@ -1,160 +0,0 @@
-How to test technology profile
-------------------------------
-
-- Export ONOS directory:
-
-```
-export ONOS_ROOT=~/voltha-projects/onos
-source $ONOS_ROOT/tools/dev/bash_profile
-```
-
-- Build and run ONOS:
-
-```
-mvn clean install -DskipTests -Dcheckstyle.skip=true OR onos-buck build onos
-ok clean
-```
-
-- Build SADIS and OLT apps:
-
-```
-mvn clean install
-```
-
-- Install and Activate SADIS and OLT apps:
-
-```
-onos-app localhost install ~/voltha-projects/sadis/app/target/sadis-app-3.0.0.oar
-onos-app localhost activate org.opencord.sadis
-
-onos-app localhost install ~/voltha-projects/olt/app/target/olt-app-3.0.1.oar
-onos-app localhost activate org.opencord.olt
-```
-
-- To test with the oldest configuration (as oldest SADIS) - it includes only S and C tags:
-
-```
-onos-netcfg localhost  ~/voltha-projects/olt/app/src/main/resources/cfg.json
-```
-
-- To test AT&T use case:
-    - Note:the tech profile table id is 10 to work with Mininet - if Voltha is used, then it will be 64 or greater value
-
-```
-onos-netcfg localhost  ~/voltha-projects/olt/app/src/main/resources/vlan_cfg.json
-```
-
-- To test DT use case (any vlan):
-    - Note:the tech profile table id is 10 to work with Mininet - if Voltha is used, then it will be 64 or greater value
-
-```
-onos-netcfg localhost  ~/voltha-projects/olt/app/src/main/resources/any_vlan_cfg.json
-```
-
-- To test without VOLTHA, you can use Mininet with UserSwitch and emulate the topology:
-
-```
-sudo mn --custom ~/voltha-projects/olt/app/src/main/resources/custom-topo.py --switch user --controller=remote,ip=127.0.0.1,port=6633
-```
-
-- Run ONOS client:
-
-```
- cd /tmp/onos-1.13.6/apache-karaf-3.0.8/bin
- ./client
-```
-
-- Check devices, flows and ports:
-
-```
-devices
-
-the output (note that: the driver is pmc-olt):
-
-id=of:0000000000000001, available=true, local-status=connected 2s ago, role=MASTER, type=SWITCH, mfr=Stanford University, Ericsson Research and CPqD Research, hw=OpenFlow 1.3 Reference Userspace Switch, sw=Sep 10 2018 16:56:31, serial=1, chassis=1, driver=pmc-olt, channelId=127.0.0.1:36022, locType=none, managementAddress=127.0.0.1, name=of:0000000000000001, protocol=OF_13
-
-flows
-
-the output:
-
-deviceId=of:0000000000000001, flowRuleCount=4
-    id=ac00002f18dba3, state=ADDED, bytes=0, packets=0, duration=0, liveType=UNKNOWN, priority=10000, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:1, ETH_TYPE:eapol], treatment=DefaultTrafficTreatment{immediate=[OUTPUT:CONTROLLER], deferred=[], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
-    id=ac00005512664b, state=ADDED, bytes=0, packets=0, duration=0, liveType=UNKNOWN, priority=10000, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:LOCAL, ETH_TYPE:eapol], treatment=DefaultTrafficTreatment{immediate=[OUTPUT:CONTROLLER], deferred=[], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
-    id=ac00005d0fea43, state=ADDED, bytes=0, packets=0, duration=0, liveType=UNKNOWN, priority=10000, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:2, ETH_TYPE:lldp], treatment=DefaultTrafficTreatment{immediate=[OUTPUT:CONTROLLER], deferred=[], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
-    id=ac0000617983d6, state=ADDED, bytes=0, packets=0, duration=0, liveType=UNKNOWN, priority=10000, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:2, ETH_TYPE:ipv4, IP_PROTO:17, UDP_SRC:68, UDP_DST:67], treatment=DefaultTrafficTreatment{immediate=[OUTPUT:CONTROLLER], deferred=[], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
-
-ports
-
-the output (assume that port 1 is UNI and 2 is NNI):
-
-id=of:0000000000000001, available=true, local-status=connected 7s ago, role=MASTER, type=SWITCH, mfr=Stanford University, Ericsson Research and CPqD Research, hw=OpenFlow 1.3 Reference Userspace Switch, sw=Sep 10 2018 16:56:31, serial=1, chassis=1, driver=pmc-olt, channelId=127.0.0.1:36022, locType=none, managementAddress=127.0.0.1, name=of:0000000000000001, protocol=OF_13
-  port=LOCAL, state=enabled, type=copper, speed=10 , adminState=enabled, portMac=00:00:00:00:00:01, portName=tap:
-  port=1, state=enabled, type=copper, speed=10485 , adminState=enabled, portMac=ba:5d:49:53:9f:d2, portName=s1-eth1
-  port=2, state=enabled, type=copper, speed=10485 , adminState=enabled, portMac=9e:11:ee:ba:4f:f4, portName=s1-eth
-
-```
-
-- Add subscriber to UNI port:
-
-```
-volt-add-subscriber-access of:0000000000000001 1
-```
-
-- The flows when you use cfg.json:
-
-```
-Upstream Flows:
-
-    id=ac000000f780f6, state=ADDED, bytes=0, packets=0, duration=5, liveType=UNKNOWN, priority=1000, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:1, VLAN_VID:0], treatment=DefaultTrafficTreatment{immediate=[VLAN_ID:2], deferred=[], transition=TABLE:1, meter=[], cleared=false, StatTrigger=null, metadata=null}
-    id=ac0000c9fd17bf, state=ADDED, bytes=0, packets=0, duration=5, liveType=UNKNOWN, priority=1000, tableId=1, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:1, VLAN_VID:2], treatment=DefaultTrafficTreatment{immediate=[VLAN_PUSH:vlan, VLAN_ID:4], deferred=[OUTPUT:2], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
-
-Downstream Flows:
-
-    id=ac000022a77664, state=ADDED, bytes=0, packets=0, duration=5, liveType=UNKNOWN, priority=1000, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:2, METADATA:200000001, VLAN_VID:4], treatment=DefaultTrafficTreatment{immediate=[VLAN_POP], deferred=[], transition=TABLE:1, meter=[], cleared=false, StatTrigger=null, metadata=null}
-    id=ac00001801d6d1, state=ADDED, bytes=0, packets=0, duration=5, liveType=UNKNOWN, priority=1000, tableId=1, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:2, VLAN_VID:2], treatment=DefaultTrafficTreatment{immediate=[VLAN_POP, VLAN_ID:0], deferred=[OUTPUT:1], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
-```
-
-- The flows when you use vlan_cfg.json:
-
-```
-Upstream Flows:
-
-    id=ac000000f780f6, state=ADDED, bytes=0, packets=0, duration=6, liveType=UNKNOWN, priority=1000, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:1, VLAN_VID:0], treatment=DefaultTrafficTreatment{immediate=[VLAN_ID:2], deferred=[], transition=TABLE:1, meter=[], cleared=false, StatTrigger=null, metadata=null}
-    id=ac0000c9fd17bf, state=ADDED, bytes=0, packets=0, duration=6, liveType=UNKNOWN, priority=1000, tableId=1, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:1, VLAN_VID:2], treatment=DefaultTrafficTreatment{immediate=[VLAN_PUSH:vlan, VLAN_ID:4], deferred=[OUTPUT:2], transition=TABLE:10, meter=[METER:1], cleared=false, StatTrigger=null, metadata=null}
-
-Downstream Flows:
-
-    id=ac000022a77664, state=ADDED, bytes=0, packets=0, duration=6, liveType=UNKNOWN, priority=1000, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:2, METADATA:200000001, VLAN_VID:4], treatment=DefaultTrafficTreatment{immediate=[VLAN_POP], deferred=[], transition=TABLE:1, meter=[], cleared=false, StatTrigger=null, metadata=null}
-    id=ac00001801d6d1, state=ADDED, bytes=0, packets=0, duration=6, liveType=UNKNOWN, priority=1000, tableId=1, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:2, VLAN_VID:2], treatment=DefaultTrafficTreatment{immediate=[VLAN_POP, VLAN_ID:0], deferred=[OUTPUT:1], transition=TABLE:10, meter=[METER:2], cleared=false, StatTrigger=null, metadata=null}
-
-Upstream Meter:
-
- DefaultMeter{device=of:0000000000000001, cellId=1, appId=org.opencord.olt, unit=KB_PER_SEC, isBurst=true, state=ADDED, bands=[DefaultBand{rate=200000000, burst-size=348000, type=DROP, drop-precedence=null}, DefaultBand{rate=10000000, burst-size=348000, type=DROP, drop-precedence=null}, DefaultBand{rate=10000000, burst-size=0, type=DROP, drop-precedence=null}]}
-
-Downstream Meter:
-
- DefaultMeter{device=of:0000000000000001, cellId=2, appId=org.opencord.olt, unit=KB_PER_SEC, isBurst=true, state=ADDED, bands=[DefaultBand{rate=300000000, burst-size=348000, type=DROP, drop-precedence=null}, DefaultBand{rate=20000000, burst-size=348000, type=DROP, drop-precedence=null}, DefaultBand{rate=30000000, burst-size=0, type=DROP, drop-precedence=null}]}
-```
-
-- The flows when you use any_vlan_cfg.json:
-
-```
-Upstream Flows:
-
-    id=ac000009d37362, state=ADDED, bytes=0, packets=0, duration=3, liveType=UNKNOWN, priority=500, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:1], treatment=DefaultTrafficTreatment{immediate=[NOACTION], deferred=[], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
-    id=ac0000fb6f690a, state=ADDED, bytes=0, packets=0, duration=3, liveType=UNKNOWN, priority=1000, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:1, VLAN_VID:Any], treatment=DefaultTrafficTreatment{immediate=[], deferred=[], transition=TABLE:1, meter=[], cleared=false, StatTrigger=null, metadata=null}
-    id=ac0000076e2984, state=ADDED, bytes=0, packets=0, duration=3, liveType=UNKNOWN, priority=1000, tableId=1, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:1, VLAN_VID:Any], treatment=DefaultTrafficTreatment{immediate=[VLAN_PUSH:qinq, VLAN_ID:4], deferred=[OUTPUT:2], transition=TABLE:10, meter=[METER:1], cleared=false, StatTrigger=null, metadata=null}
-
-Downstream Flows:
-
-    id=ac000022a77664, state=ADDED, bytes=0, packets=0, duration=3, liveType=UNKNOWN, priority=1000, tableId=0, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:2, METADATA:200000001, VLAN_VID:4], treatment=DefaultTrafficTreatment{immediate=[], deferred=[VLAN_POP], transition=TABLE:1, meter=[], cleared=false, StatTrigger=null, metadata=null}
-    id=ac0000911ae9cb, state=ADDED, bytes=0, packets=0, duration=3, liveType=UNKNOWN, priority=1000, tableId=1, appId=org.opencord.olt, payLoad=null, selector=[IN_PORT:2, VLAN_VID:Any], treatment=DefaultTrafficTreatment{immediate=[], deferred=[OUTPUT:1], transition=TABLE:10, meter=[METER:2], cleared=false, StatTrigger=null, metadata=null}
-
-Upstream Meter:
-
- DefaultMeter{device=of:0000000000000001, cellId=1, appId=org.opencord.olt, unit=KB_PER_SEC, isBurst=true, state=ADDED, bands=[DefaultBand{rate=200000000, burst-size=348000, type=DROP, drop-precedence=null}, DefaultBand{rate=10000000, burst-size=348000, type=DROP, drop-precedence=null}, DefaultBand{rate=10000000, burst-size=0, type=DROP, drop-precedence=null}]}
-
-Downstream Meter:
-
- DefaultMeter{device=of:0000000000000001, cellId=2, appId=org.opencord.olt, unit=KB_PER_SEC, isBurst=true, state=ADDED, bands=[DefaultBand{rate=300000000, burst-size=348000, type=DROP, drop-precedence=null}, DefaultBand{rate=20000000, burst-size=348000, type=DROP, drop-precedence=null}, DefaultBand{rate=30000000, burst-size=0, type=DROP, drop-precedence=null}]}
-```
diff --git a/api/pom.xml b/api/pom.xml
index 522aed0..34d69e0 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  ~ Copyright 2016-present Open Networking Foundation
+  ~ Copyright 2021 Open Networking Foundation
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -17,32 +17,21 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
     <parent>
         <artifactId>olt</artifactId>
         <groupId>org.opencord</groupId>
-        <version>4.6.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
+        <version>5.0.0-SNAPSHOT</version>
     </parent>
+    <modelVersion>4.0.0</modelVersion>
 
     <version>${olt.api.version}</version>
     <artifactId>olt-api</artifactId>
     <packaging>bundle</packaging>
 
-    <url>http://opencord.org</url>
-
-    <description>OLT application API</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.opencord</groupId>
-            <artifactId>sadis-api</artifactId>
-            <version>${sadis.api.version}</version>
-            <scope>provided</scope>
-        </dependency>
-    </dependencies>
-
+    <properties>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+    </properties>
     <build>
         <plugins>
             <plugin>
@@ -51,4 +40,4 @@
             </plugin>
         </plugins>
     </build>
-</project>
+</project>
\ No newline at end of file
diff --git a/api/src/main/java/org/opencord/olt/AccessDevicePort.java b/api/src/main/java/org/opencord/olt/AccessDevicePort.java
deleted file mode 100644
index 8a1665d..0000000
--- a/api/src/main/java/org/opencord/olt/AccessDevicePort.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2021-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.opencord.olt;
-
-import org.onosproject.net.AnnotationKeys;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-
-/**
- * OLT device port.
- */
-public class AccessDevicePort {
-
-    Port port;
-    Type type;
-
-    /**
-     * OLT Port Type.
-     */
-    public enum Type {
-        NNI,
-        UNI,
-    }
-
-    /**
-     * Creates an AccessDevicePort with given ONOS port object and OLT port type.
-     *
-     * @param port ONOS port
-     * @param type OLT port type
-     */
-    public AccessDevicePort(Port port, Type type) {
-        this.port = port;
-        this.type = type;
-    }
-
-    /**
-     * Get ONOS Port object.
-     *
-     * @return ONOS port
-     */
-    public Port port() {
-        return this.port;
-    }
-
-    /**
-     * Get OLT port Type.
-     *
-     * @return OLT port type
-     */
-    public Type type() {
-        return this.type;
-    }
-
-    /**
-     * Check port is enabled state on ONOS.
-     *
-     * @return is Access Device Port enabled
-     */
-    public boolean isEnabled() {
-        return this.port.isEnabled();
-    }
-
-    /**
-     * Get Device ID of OLT which the port is connected.
-     *
-     * @return OLT Device ID
-     */
-    public DeviceId deviceId() {
-        return (DeviceId) this.port.element().id();
-    }
-
-    /**
-     * Get port number.
-     *
-     * @return port number
-     */
-    public PortNumber number() {
-        return this.port.number();
-    }
-
-    /**
-     * Get port name which is combination of serial number and uni index.
-     *
-     * @return port name (ex: BBSM00010001-1)
-     */
-    public String name() {
-        return this.port.annotations().value(AnnotationKeys.PORT_NAME);
-    }
-
-    @Override
-    public String toString() {
-        return deviceId().toString() + '/' + number() + '[' + name() + ']';
-    }
-
-}
diff --git a/api/src/main/java/org/opencord/olt/AccessDeviceService.java b/api/src/main/java/org/opencord/olt/AccessDeviceService.java
index 4878d97..9f39715 100644
--- a/api/src/main/java/org/opencord/olt/AccessDeviceService.java
+++ b/api/src/main/java/org/opencord/olt/AccessDeviceService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,93 +16,62 @@
 
 package org.opencord.olt;
 
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
 import org.onlab.packet.VlanId;
 import org.onosproject.event.ListenerService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 
-import com.google.common.collect.ImmutableMap;
-import org.opencord.sadis.UniTagInformation;
+import java.util.List;
 
-/**
- * Service for interacting with an access device (OLT).
- */
-public interface AccessDeviceService
-        extends ListenerService<AccessDeviceEvent, AccessDeviceListener> {
-
+public interface AccessDeviceService extends ListenerService<AccessDeviceEvent, AccessDeviceListener> {
     /**
      * Provisions connectivity for a subscriber on an access device.
-     * Installs flows for all uni tag information
+     * It installs flows for all uni tag information
      *
-     * @param port subscriber's connection point
-     * @return true if successful false otherwise
+     * @param cp subscriber's connection point
+     * @return true if the request is accepted (does not guarantee the subscriber is provisioned)
      */
-    boolean provisionSubscriber(ConnectPoint port);
+    boolean provisionSubscriber(ConnectPoint cp);
 
     /**
-     * Removes provisioned connectivity for a subscriber from an access device.
-     * Removes flows for all uni tag information
-     *
-     * @param port subscriber's connection point
-     * @return true if successful false otherwise
+     * Removes subscriber flows from a given ConnectPoint.
+     * @param cp subscriber's connect point
+     * @return true if the request is accepted (does not guarantee the subscriber is removed)
      */
-    boolean removeSubscriber(ConnectPoint port);
+    boolean removeSubscriber(ConnectPoint cp);
 
     /**
-     * Provisions a uni tag information for the specific subscriber.
-     * It finds the related uni tag information from the subscriber uni tag list
-     * and installs it
-     *
-     * @param subscriberId Identification of the subscriber
-     * @param sTag         additional outer tag on this port
-     * @param cTag         additional inner tag on this port
-     * @param tpId         additional technology profile id
-     * @return true if successful false otherwise
+     * Provisions connectivity for a particular service for a subscriber.
+     * @param cp subscriber's connect point
+     * @param cTag service's cTag
+     * @param sTag service's sTag
+     * @param tpId service's Technology Profile ID
+     * @return true if the request is accepted (does not guarantee the subscriber is provisioned)
      */
-    boolean provisionSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag,
-                                Optional<VlanId> cTag, Optional<Integer> tpId);
+    boolean provisionSubscriber(ConnectPoint cp, VlanId cTag, VlanId sTag, Integer tpId);
 
     /**
-     * Removes a uni tag information for the specific subscriber.
-     * It finds the related uni tag information from the subscriber uni tag list
-     * and remove it
-     *
-     * @param subscriberId Identification of the subscriber
-     * @param sTag         additional outer tag on this port
-     * @param cTag         additional inner tag on this port
-     * @param tpId         additional technology profile id
-     * @return true if successful false otherwise
+     * Removes connectivity for a particular service for a subscriber.
+     * @param cp subscriber's connect point
+     * @param cTag service's cTag
+     * @param sTag service's sTag
+     * @param tpId service's Technology Profile ID
+     * @return true if the request is accepted (does not guarantee the subscriber is removed)
      */
-    boolean removeSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag,
-                             Optional<VlanId> cTag, Optional<Integer> tpId);
+    boolean removeSubscriber(ConnectPoint cp, VlanId cTag, VlanId sTag, Integer tpId);
 
     /**
-     * Returns the list of active OLTs.
-     *
-     * @return a List
+     * Returns a list of connected OLT devices ID.
+     * @return a list of devices
      */
-    List<DeviceId> fetchOlts();
+    List<DeviceId> getConnectedOlts();
 
     /**
-     * Returns information about subscribers that have been programmed in the
-     * data-plane. It shows all uni tag information list of the subscribers even if
-     * these have not been programmed.
+     * Finds the ConnectPoint to which a subscriber is connected.
      *
-     * @return an immutable map of locations and subscriber information
+     * @param id The id of the subscriber, this is the same ID as in Sadis
+     * @return Subscribers ConnectPoint if found else null
      */
-    ImmutableMap<ConnectPoint, Set<UniTagInformation>> getProgSubs();
-
-    /**
-     * Returns information about subscribers that have NOT been programmed in the
-     * data-plane. It shows all uni tag information list of the subscribers even if
-     * these have not been programmed, meaning no flows have been sent to the device.
-     *
-     * @return an immutable map of locations and subscriber information
-     */
-    ImmutableMap<ConnectPoint, Set<UniTagInformation>> getFailedSubs();
+    ConnectPoint findSubscriberConnectPoint(String id);
 
 }
diff --git a/api/src/main/java/org/opencord/olt/AccessSubscriberId.java b/api/src/main/java/org/opencord/olt/AccessSubscriberId.java
deleted file mode 100644
index f85ea0f..0000000
--- a/api/src/main/java/org/opencord/olt/AccessSubscriberId.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2017-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.opencord.olt;
-
-/**
- * Class representing the identifier for a subscriber.
- * It encapsulates the name of the logical port for the subscriber in
- * ONOS.
- * For e.g. if in ONOS you see
- * <pre>
- * onos&gt; ports
- * id=of:00000000c0a83264, available=true, local-status=connected 3m48s ago, role=MASTER, mfr=VOLTHA Projectd,...
- *   port=32, state=enabled, type=fiber, speed=0 , adminState=enabled, portMac=08:00:00:00:00:20, portName=TWSH80808082
- * </pre>
- * the subscriber id would encapsulate the string "TWSH80808082"
- */
-public class AccessSubscriberId {
-    // string representing the identifier
-    String id;
-
-    /**
-     * Creates an AccessSubscriberId with the passed id.
-     *
-     * @param id identifier of the subscriber
-     */
-    public AccessSubscriberId(String id) {
-        this.id = id;
-    }
-
-    /*
-    * (non-Javadoc)
-    *
-    * @see java.lang.Object#hashCode()
-    */
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + (this.id == null ? 0 : this.id.hashCode());
-
-        return result;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(final Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (this.getClass() != obj.getClass()) {
-            return false;
-        }
-
-        final AccessSubscriberId other = (AccessSubscriberId) obj;
-        if (this.id == null) {
-            if (other.id != null) {
-                return false;
-            }
-        } else if (!this.id.equals(other.id)) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /*
-    * (non-Javadoc)
-    *
-    * @see java.lang.Object#toString()
-    */
-    @Override
-    public String toString() {
-        return id;
-    }
-}
diff --git a/api/src/main/java/org/opencord/olt/package-info.java b/api/src/main/java/org/opencord/olt/package-info.java
index f48f829..d6cff7d 100644
--- a/api/src/main/java/org/opencord/olt/package-info.java
+++ b/api/src/main/java/org/opencord/olt/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,6 +15,6 @@
  */
 
 /**
- * OLT application api.
+ * OLT App APIs.
  */
-package org.opencord.olt;
+package org.opencord.olt;
\ No newline at end of file
diff --git a/app/app.xml b/app/app.xml
index da3f106..914f727 100644
--- a/app/app.xml
+++ b/app/app.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  ~ Copyright 2018-present Open Networking Foundation
+  ~ Copyright 2021-present Open Networking Foundation
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -21,8 +21,8 @@
      featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
      features="${project.artifactId}">
     <description>${project.description}</description>
-    <artifact>mvn:${project.groupId}/olt-api/${olt.api.version}</artifact>
     <artifact>mvn:${project.groupId}/olt-impl/${project.version}</artifact>
     <artifact>mvn:${project.groupId}/olt-web/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/olt-api/${project.version}</artifact>
     <artifact>mvn:${project.groupId}/sadis-api/${sadis.api.version}</artifact>
 </app>
diff --git a/app/features.xml b/app/features.xml
index d63d0d7..fffac01 100644
--- a/app/features.xml
+++ b/app/features.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <!--
-  ~ Copyright 2018-present Open Networking Foundation
+  ~ Copyright 2021-present Open Networking Foundation
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -18,9 +18,9 @@
     <feature name="${project.artifactId}" version="${project.version}"
              description="${project.description}">
         <feature>onos-api</feature>
-        <bundle>mvn:${project.groupId}/olt-api/${olt.api.version}</bundle>
         <bundle>mvn:${project.groupId}/olt-impl/${project.version}</bundle>
         <bundle>mvn:${project.groupId}/olt-web/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/olt-api/${project.version}</bundle>
         <bundle>mvn:${project.groupId}/sadis-api/${sadis.api.version}</bundle>
     </feature>
 </features>
diff --git a/app/pom.xml b/app/pom.xml
index 4185d06..4a537c7 100644
--- a/app/pom.xml
+++ b/app/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  ~ Copyright 2016-present Open Networking Foundation
+  ~ Copyright 2021 Open Networking Foundation
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -18,17 +18,17 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <groupId>org.opencord</groupId>
         <artifactId>olt</artifactId>
-        <version>4.6.0-SNAPSHOT</version>
+        <groupId>org.opencord</groupId>
+        <version>5.0.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
-
     <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opencord</groupId>
     <artifactId>olt-app</artifactId>
+    <version>5.0.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
     <description>OLT application for CORD</description>
-
     <properties>
         <onos.app.name>org.opencord.olt</onos.app.name>
         <onos.app.title>OLT Access Management</onos.app.title>
@@ -39,7 +39,6 @@
             CORD OLT Access management application
         </onos.app.readme>
     </properties>
-
     <build>
         <plugins>
             <plugin>
@@ -48,4 +47,4 @@
             </plugin>
         </plugins>
     </build>
-</project>
+</project>
\ No newline at end of file
diff --git a/assets/diagram.png b/assets/diagram.png
new file mode 100644
index 0000000..c46c2b9
--- /dev/null
+++ b/assets/diagram.png
Binary files differ
diff --git a/impl/pom.xml b/impl/pom.xml
index 2c7282b..c3609db 100644
--- a/impl/pom.xml
+++ b/impl/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  ~ Copyright 2016-present Open Networking Foundation
+  ~ Copyright 2021 Open Networking Foundation
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -18,75 +18,79 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <groupId>org.opencord</groupId>
         <artifactId>olt</artifactId>
-        <version>4.6.0-SNAPSHOT</version>
+        <groupId>org.opencord</groupId>
+        <version>5.0.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
-
     <modelVersion>4.0.0</modelVersion>
     <artifactId>olt-impl</artifactId>
+    <version>5.0.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
-    <description>OLT application for CORD</description>
-
     <dependencies>
         <dependency>
-            <groupId>org.opencord</groupId>
-            <artifactId>olt-api</artifactId>
-            <version>${olt.api.version}</version>
-            <scope>compile</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.opencord</groupId>
-            <artifactId>sadis-api</artifactId>
-            <version>${sadis.api.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.onosproject</groupId>
             <artifactId>onos-cli</artifactId>
             <version>${onos.version}</version>
             <scope>provided</scope>
         </dependency>
-
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-osgi</artifactId>
+            <version>${onos.version}</version>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
             <artifactId>onos-api</artifactId>
             <version>${onos.version}</version>
-            <classifier>tests</classifier>
             <scope>test</scope>
+            <classifier>tests</classifier>
         </dependency>
-
         <dependency>
             <groupId>org.onosproject</groupId>
             <artifactId>onos-core-serializers</artifactId>
             <version>${onos.version}</version>
             <scope>provided</scope>
         </dependency>
-
+        <dependency>
+            <groupId>org.opencord</groupId>
+            <artifactId>sadis-api</artifactId>
+            <version>${sadis.api.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.25</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-jdk14</artifactId>
+            <version>1.7.25</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>1.9.5</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.karaf.shell</groupId>
             <artifactId>org.apache.karaf.shell.console</artifactId>
             <scope>provided</scope>
         </dependency>
-
         <dependency>
             <groupId>org.apache.karaf.shell</groupId>
             <artifactId>org.apache.karaf.shell.core</artifactId>
             <scope>provided</scope>
         </dependency>
-
         <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
-            <version>2.10.2</version>
-            <scope>provided</scope>
+            <groupId>org.opencord</groupId>
+            <artifactId>olt-api</artifactId>
+            <version>5.0.0-SNAPSHOT</version>
+            <scope>compile</scope>
         </dependency>
-
     </dependencies>
-
     <build>
         <plugins>
             <plugin>
@@ -104,4 +108,4 @@
             </plugin>
         </plugins>
     </build>
-</project>
+</project>
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/OltUniPortCompleter.java b/impl/src/main/java/org/opencord/olt/cli/OltUniPortCompleter.java
index 68ceca6..98301db 100644
--- a/impl/src/main/java/org/opencord/olt/cli/OltUniPortCompleter.java
+++ b/impl/src/main/java/org/opencord/olt/cli/OltUniPortCompleter.java
@@ -19,34 +19,34 @@
 import org.apache.karaf.shell.api.action.lifecycle.Service;
 import org.onlab.osgi.DefaultServiceDirectory;
 import org.onosproject.cli.net.PortNumberCompleter;
-import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.device.DeviceService;
+import org.opencord.olt.impl.OltDeviceServiceInterface;
+
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
 
 @Service
 public class OltUniPortCompleter extends PortNumberCompleter {
-    private static final String NNI = "nni-";
 
     public OltUniPortCompleter() {
     }
 
     protected List<String> choices() {
+        DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
         DeviceId deviceId = this.lookForDeviceId();
         if (deviceId == null) {
             return Collections.emptyList();
         } else {
-            DeviceService deviceService = (DeviceService) DefaultServiceDirectory.getService(DeviceService.class);
-            return (List) StreamSupport.stream(deviceService.getPorts(deviceId).spliterator(), false)
-                    .filter((port) -> {
-                        return port.isEnabled() && !port.annotations().value(AnnotationKeys.PORT_NAME).startsWith(NNI);
-                    })
-                    .map((port) -> {
-                        return port.number().toString();
-                    }).collect(Collectors.toList());
+            Device device = deviceService.getDevice(DeviceId.deviceId(deviceId.toString()));
+            OltDeviceServiceInterface oltDeviceService =
+                    DefaultServiceDirectory.getService(OltDeviceServiceInterface.class);
+            return deviceService.getPorts(deviceId).stream()
+                    .filter((port) -> port.isEnabled() && !oltDeviceService.isNniPort(device, port.number()))
+                    .map((port) -> port.number().toString())
+                    .collect(Collectors.toList());
         }
     }
 }
diff --git a/impl/src/main/java/org/opencord/olt/cli/ShowBpMeterMappingsCommand.java b/impl/src/main/java/org/opencord/olt/cli/ShowBpMeterMappingsCommand.java
deleted file mode 100644
index eb1b47d..0000000
--- a/impl/src/main/java/org/opencord/olt/cli/ShowBpMeterMappingsCommand.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.opencord.olt.cli;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.net.meter.MeterKey;
-import org.opencord.olt.internalapi.AccessDeviceMeterService;
-
-import java.util.Collection;
-import java.util.Map;
-
-@Service
-@Command(scope = "onos", name = "volt-bpmeter-mappings",
-        description = "Shows information about bandwidthProfile-meterKey (device / meter) mappings")
-public class ShowBpMeterMappingsCommand extends AbstractShellCommand {
-
-    @Override
-    protected void doExecute() {
-        AccessDeviceMeterService service = AbstractShellCommand.get(AccessDeviceMeterService.class);
-        Map<String, Collection<MeterKey>> bpMeterMappings = service.getBpMeterMappings();
-        bpMeterMappings.forEach(this::display);
-    }
-
-    private void display(String bpInfo, Collection<MeterKey> meterKeyList) {
-        meterKeyList.forEach(meterKey ->
-                print("bpInfo=%s deviceId=%s meterId=%s",
-                        bpInfo, meterKey.deviceId(), meterKey.meterId()));
-
-    }
-}
diff --git a/impl/src/main/java/org/opencord/olt/cli/ShowFailedSubscribersCommand.java b/impl/src/main/java/org/opencord/olt/cli/ShowFailedSubscribersCommand.java
index 5d6bf3d..cb40faa 100644
--- a/impl/src/main/java/org/opencord/olt/cli/ShowFailedSubscribersCommand.java
+++ b/impl/src/main/java/org/opencord/olt/cli/ShowFailedSubscribersCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,31 +19,20 @@
 import org.apache.karaf.shell.api.action.Command;
 import org.apache.karaf.shell.api.action.lifecycle.Service;
 import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.net.ConnectPoint;
-import org.opencord.olt.AccessDeviceService;
-import org.opencord.sadis.UniTagInformation;
-
-import java.util.Map;
-import java.util.Set;
-
 /**
- * Shows subscriber information for those subscriber which have been programmed
- * in the data-plane.
+ * Shows failed subscribers on an OLTs.
  */
 @Service
 @Command(scope = "onos", name = "volt-failed-subscribers",
-        description = "Shows subscribers awaiting for programming in the dataplane")
+        description = "Shows subscribers that failed provisioning")
 public class ShowFailedSubscribersCommand extends AbstractShellCommand {
 
     @Override
     protected void doExecute() {
-        AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
-        Map<ConnectPoint, Set<UniTagInformation>> info = service.getFailedSubs();
-        info.forEach(this::display);
+        // NOTE
+        // this command is still available purely for backward compatibility but whilst the old implementation
+        // had a limited number of retries available the new implementation will keep retrying.
+        print("Unimplemented");
     }
 
-    private void display(ConnectPoint cp, Set<UniTagInformation> uniTagInformation) {
-        uniTagInformation.forEach(uniTag ->
-                                          print("location=%s tagInformation=%s", cp, uniTag));
-    }
-}
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/ShowMeterMappings.java b/impl/src/main/java/org/opencord/olt/cli/ShowMeterMappings.java
new file mode 100644
index 0000000..7e2175d
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/cli/ShowMeterMappings.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.cli;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.opencord.olt.impl.MeterData;
+import org.opencord.olt.impl.OltMeterServiceInterface;
+
+import java.util.Map;
+/**
+ * Shows meters to bandwidth profile mappings.
+ */
+@Service
+@Command(scope = "onos", name = "volt-bpmeter-mappings",
+        description = "Shows information about programmed meters, including the relation with the Bandwidth Profile")
+public class ShowMeterMappings extends AbstractShellCommand {
+
+    @Override
+    protected void doExecute() {
+        OltMeterServiceInterface service = AbstractShellCommand.get(OltMeterServiceInterface.class);
+        Map<DeviceId, Map<String, MeterData>> meters = service.getProgrammedMeters();
+        if (meters.isEmpty()) {
+            print("No meters programmed by the olt app");
+        }
+        meters.forEach(this::display);
+    }
+
+    private void display(DeviceId deviceId, Map<String, MeterData> data) {
+        data.forEach((bp, md) ->
+                print("\tbpInfo=%s deviceId=%s meterId=%s",
+                        deviceId, bp, md.getMeterId()));
+
+    }
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/ShowOltCommand.java b/impl/src/main/java/org/opencord/olt/cli/ShowOltCommand.java
index 08aaa48..c379116 100644
--- a/impl/src/main/java/org/opencord/olt/cli/ShowOltCommand.java
+++ b/impl/src/main/java/org/opencord/olt/cli/ShowOltCommand.java
@@ -40,9 +40,9 @@
     protected void doExecute() {
         AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
         if (outputJson()) {
-            print("%s", json(service.fetchOlts()));
+            print("%s", json(service.getConnectedOlts()));
         } else {
-            service.fetchOlts().forEach(did -> print("OLT %s", did));
+            service.getConnectedOlts().forEach(did -> print("OLT %s", did));
         }
 
     }
@@ -62,4 +62,4 @@
         }
         return node;
     }
-}
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/ShowPortStatus.java b/impl/src/main/java/org/opencord/olt/cli/ShowPortStatus.java
new file mode 100644
index 0000000..f3b35a0
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/cli/ShowPortStatus.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cli.net.DeviceIdCompleter;
+import org.onosproject.cli.net.PortNumberCompleter;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.opencord.olt.impl.OltFlowServiceInterface;
+import org.opencord.olt.impl.OltPortStatus;
+import org.opencord.olt.impl.ServiceKey;
+import org.opencord.sadis.UniTagInformation;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Shows ports' status of an OLT.
+ */
+@Service
+@Command(scope = "onos", name = "volt-port-status",
+        description = "Shows information about the OLT ports (default EAPOL, subscriber flows)")
+public class ShowPortStatus extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "deviceId", description = "Access device ID",
+            required = false, multiValued = false)
+    @Completion(DeviceIdCompleter.class)
+    private String strDeviceId = null;
+
+    @Argument(index = 1, name = "port", description = "Subscriber port number",
+            required = false, multiValued = false)
+    @Completion(PortNumberCompleter.class)
+    private String strPort = null;
+
+    @Override
+    protected void doExecute() {
+
+        OltFlowServiceInterface service = AbstractShellCommand.get(OltFlowServiceInterface.class);
+        Map<ServiceKey, OltPortStatus> connectPointStatus = service.getConnectPointStatus();
+        if (connectPointStatus.isEmpty()) {
+            print("No ports handled by the olt app");
+            return;
+        }
+
+        Map<DeviceId, Map<PortNumber, Map<UniTagInformation, OltPortStatus>>> sortedStatus = new HashMap<>();
+
+        DeviceId deviceId = strDeviceId != null ? DeviceId.deviceId(strDeviceId) : null;
+        PortNumber portNumber = strPort != null ? PortNumber.portNumber(strPort) : null;
+
+        connectPointStatus.forEach((sk, fs) -> {
+            if (deviceId != null && !deviceId.equals(sk.getPort().connectPoint()
+                    .deviceId())) {
+                return;
+            }
+            if (portNumber != null && !portNumber.equals(sk.getPort().connectPoint().port())) {
+                return;
+            }
+            sortedStatus.compute(sk.getPort().connectPoint().deviceId(), (id, portMap) -> {
+                if (portMap == null) {
+                    portMap = new HashMap<>();
+                }
+                portMap.compute(sk.getPort().connectPoint().port(), (id2, ps) -> {
+                    if (ps == null) {
+                        ps = new HashMap<>();
+                    }
+                    ps.put(sk.getService(), fs);
+                    return ps;
+                });
+
+                return portMap;
+            });
+        });
+
+        sortedStatus.forEach(this::display);
+    }
+
+    private void display(DeviceId deviceId, Map<PortNumber, Map<UniTagInformation, OltPortStatus>> ports) {
+        print("deviceId=%s, managedPorts=%d", deviceId, ports.size());
+
+        ports.forEach((port, subscribers) -> {
+            print("\tport=%s", port);
+            subscribers.forEach((uti, status) -> {
+                print("\t\tservice=%s defaultEapolStatus=%s subscriberFlowsStatus=%s dhcpStatus=%s",
+                        uti.getServiceName(), status.defaultEapolStatus,
+                        status.subscriberFlowsStatus, status.dhcpStatus);
+            });
+        });
+    }
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/ShowProgrammedMeters.java b/impl/src/main/java/org/opencord/olt/cli/ShowProgrammedMeters.java
new file mode 100644
index 0000000..da2307e
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/cli/ShowProgrammedMeters.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.cli;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.opencord.olt.impl.MeterData;
+import org.opencord.olt.impl.OltMeterServiceInterface;
+
+import java.util.Map;
+/**
+ * Displays the programmed meters through the OLT app.
+ */
+@Service
+@Command(scope = "onos", name = "volt-programmed-meters",
+        description = "Shows information about programmed meters, including the relation with the Bandwidth Profile")
+public class ShowProgrammedMeters extends AbstractShellCommand {
+
+    @Override
+    protected void doExecute() {
+        OltMeterServiceInterface service = AbstractShellCommand.get(OltMeterServiceInterface.class);
+        Map<DeviceId, Map<String, MeterData>> meters = service.getProgrammedMeters();
+        if (meters.isEmpty()) {
+            print("No meters programmed by the olt app");
+            return;
+        }
+        meters.forEach(this::display);
+    }
+
+    private void display(DeviceId deviceId, Map<String, MeterData> data) {
+        print("deviceId=%s, meterCount=%d", deviceId, data.size());
+        data.forEach((bp, md) ->
+                print("\tmeterId=%s bandwidthProfile=%s status=%s",
+                        md.getMeterId(), bp, md.getMeterStatus()));
+
+    }
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/ShowProgrammedMetersCommand.java b/impl/src/main/java/org/opencord/olt/cli/ShowProgrammedMetersCommand.java
deleted file mode 100644
index a7dbd39..0000000
--- a/impl/src/main/java/org/opencord/olt/cli/ShowProgrammedMetersCommand.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.opencord.olt.cli;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.net.meter.MeterKey;
-import org.opencord.olt.internalapi.AccessDeviceMeterService;
-
-import java.util.Set;
-
-/**
- * Shows information about device-meter mappings that have been programmed in the
- * data-plane.
- */
-@Service
-@Command(scope = "onos", name = "volt-programmed-meters",
-        description = "Shows device-meter mappings programmed in the data-plane")
-public class ShowProgrammedMetersCommand extends AbstractShellCommand {
-
-    @Override
-    protected void doExecute() {
-        AccessDeviceMeterService service = AbstractShellCommand.get(AccessDeviceMeterService.class);
-        Set<MeterKey> programmedMeters = service.getProgMeters();
-        programmedMeters.forEach(this::display);
-    }
-
-    private void display(MeterKey meterKey) {
-        print("device=%s meter=%s", meterKey.deviceId(), meterKey.meterId());
-    }
-}
diff --git a/impl/src/main/java/org/opencord/olt/cli/ShowProgrammedSubscribersCommand.java b/impl/src/main/java/org/opencord/olt/cli/ShowProgrammedSubscribersCommand.java
index 413272b..ac8d00d 100644
--- a/impl/src/main/java/org/opencord/olt/cli/ShowProgrammedSubscribersCommand.java
+++ b/impl/src/main/java/org/opencord/olt/cli/ShowProgrammedSubscribersCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,34 +16,60 @@
 
 package org.opencord.olt.cli;
 
+import org.apache.karaf.shell.api.action.Argument;
 import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
 import org.apache.karaf.shell.api.action.lifecycle.Service;
 import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.net.ConnectPoint;
-import org.opencord.olt.AccessDeviceService;
+import org.onosproject.cli.net.DeviceIdCompleter;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.opencord.olt.impl.OltFlowServiceInterface;
+import org.opencord.olt.impl.ServiceKey;
 import org.opencord.sadis.UniTagInformation;
 
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
- * Shows subscriber information for those subscriber which have been programmed
- * in the data-plane.
+ * Shows programmed subscribers.
  */
 @Service
 @Command(scope = "onos", name = "volt-programmed-subscribers",
         description = "Shows subscribers programmed in the dataplane")
 public class ShowProgrammedSubscribersCommand extends AbstractShellCommand {
 
+    @Argument(index = 0, name = "deviceId", description = "Access device ID",
+            required = false, multiValued = false)
+    @Completion(DeviceIdCompleter.class)
+    private String strDeviceId = null;
+
+    @Argument(index = 1, name = "port", description = "Subscriber port number",
+            required = false, multiValued = false)
+    @Completion(OltUniPortCompleter.class)
+    private String strPort = null;
+
     @Override
     protected void doExecute() {
-        AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
-        Map<ConnectPoint, Set<UniTagInformation>> info = service.getProgSubs();
-        info.forEach(this::display);
+        OltFlowServiceInterface service = AbstractShellCommand.get(OltFlowServiceInterface.class);
+        Map<ServiceKey, UniTagInformation> info = service.getProgrammedSubscribers();
+        Set<Map.Entry<ServiceKey, UniTagInformation>> entries = info.entrySet();
+        if (strDeviceId != null && !strDeviceId.isEmpty()) {
+            entries = entries.stream().filter(entry -> entry.getKey().getPort().connectPoint().deviceId()
+                    .equals(DeviceId.deviceId(strDeviceId))).collect(Collectors.toSet());
+        }
+
+        if (strPort != null && !strPort.isEmpty()) {
+            PortNumber portNumber = PortNumber.portNumber(strPort);
+            entries = entries.stream().filter(entry -> entry.getKey().getPort().connectPoint().port()
+                    .equals(portNumber)).collect(Collectors.toSet());
+        }
+
+        entries.forEach(entry -> display(entry.getKey(), entry.getValue()));
     }
 
-    private void display(ConnectPoint cp, Set<UniTagInformation> uniTagInformation) {
-        uniTagInformation.forEach(uniTag ->
-                                          print("location=%s tagInformation=%s", cp, uniTag));
+    private void display(ServiceKey sk, UniTagInformation uniTag) {
+        print("location=%s tagInformation=%s", sk.getPort().connectPoint(), uniTag);
     }
-}
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/ShowRequestedSubscribersCommand.java b/impl/src/main/java/org/opencord/olt/cli/ShowRequestedSubscribersCommand.java
new file mode 100644
index 0000000..37ef532
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/cli/ShowRequestedSubscribersCommand.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cli.net.DeviceIdCompleter;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.opencord.olt.impl.OltFlowServiceInterface;
+import org.opencord.olt.impl.ServiceKey;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Shows requested subscribers.
+ */
+@Service
+@Command(scope = "onos", name = "volt-requested-subscribers",
+        description = "Shows subscribers programmed by the operator. " +
+                "Their data-plane status depends on the ONU status.")
+public class ShowRequestedSubscribersCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "deviceId", description = "Access device ID",
+            required = false, multiValued = false)
+    @Completion(DeviceIdCompleter.class)
+    private String strDeviceId = null;
+
+    @Argument(index = 1, name = "port", description = "Subscriber port number",
+            required = false, multiValued = false)
+    @Completion(OltUniPortCompleter.class)
+    private String strPort = null;
+
+    @Override
+    protected void doExecute() {
+        OltFlowServiceInterface service = AbstractShellCommand.get(OltFlowServiceInterface.class);
+        Map<ServiceKey, Boolean> info = service.getRequestedSubscribers();
+        Set<Map.Entry<ServiceKey, Boolean>> entries = info.entrySet();
+        if (strDeviceId != null && !strDeviceId.isEmpty()) {
+            entries = entries.stream().filter(entry -> entry.getKey().getPort().connectPoint().deviceId()
+                    .equals(DeviceId.deviceId(strDeviceId))).collect(Collectors.toSet());
+        }
+
+        if (strPort != null && !strPort.isEmpty()) {
+            PortNumber portNumber = PortNumber.portNumber(strPort);
+            entries = entries.stream().filter(entry -> entry.getKey().getPort().connectPoint().port()
+                    .equals(portNumber)).collect(Collectors.toSet());
+        }
+
+        entries.forEach(entry -> display(entry.getKey(), entry.getValue()));
+    }
+
+    private void display(ServiceKey sk, Boolean status) {
+        print("location=%s service=%s provisioned=%s", sk.getPort(), sk.getService().getServiceName(), status);
+    }
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/SubscriberAddAllCommand.java b/impl/src/main/java/org/opencord/olt/cli/SubscriberAddAllCommand.java
new file mode 100644
index 0000000..2a1a3c6
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/cli/SubscriberAddAllCommand.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.cli;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cli.net.DeviceIdCompleter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.opencord.olt.AccessDeviceService;
+
+/**
+ * Adds a subscriber to an access device.
+ */
+@Service
+@Command(scope = "onos", name = "volt-add-all-subscriber-access",
+        description = "Adds a subscriber to an access device")
+public class SubscriberAddAllCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "deviceId", description = "Access device ID",
+            required = true, multiValued = false)
+    @Completion(DeviceIdCompleter.class)
+    private String strDeviceId = null;
+
+    @Override
+    protected void doExecute() {
+        AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
+        DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
+        DeviceId deviceId = DeviceId.deviceId(strDeviceId);
+
+        deviceService.getPorts(deviceId).forEach(p -> {
+            if (p.isEnabled()) {
+                PortNumber port = p.number();
+                ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
+                service.provisionSubscriber(connectPoint);
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/SubscriberAddCommand.java b/impl/src/main/java/org/opencord/olt/cli/SubscriberAddCommand.java
index de76903..5eeee4e 100644
--- a/impl/src/main/java/org/opencord/olt/cli/SubscriberAddCommand.java
+++ b/impl/src/main/java/org/opencord/olt/cli/SubscriberAddCommand.java
@@ -28,7 +28,7 @@
 import org.opencord.olt.AccessDeviceService;
 
 /**
- * Adds a subscriber to an access device.
+ * Adds all possible subscribers to an access device.
  */
 @Service
 @Command(scope = "onos", name = "volt-add-subscriber-access",
@@ -48,11 +48,10 @@
     @Override
     protected void doExecute() {
         AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
-
         DeviceId deviceId = DeviceId.deviceId(strDeviceId);
         PortNumber port = PortNumber.portNumber(strPort);
         ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
 
         service.provisionSubscriber(connectPoint);
     }
-}
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/SubscriberRemoveCommand.java b/impl/src/main/java/org/opencord/olt/cli/SubscriberRemoveCommand.java
index 79a7369..cf3da93 100644
--- a/impl/src/main/java/org/opencord/olt/cli/SubscriberRemoveCommand.java
+++ b/impl/src/main/java/org/opencord/olt/cli/SubscriberRemoveCommand.java
@@ -22,18 +22,17 @@
 import org.apache.karaf.shell.api.action.lifecycle.Service;
 import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.cli.net.DeviceIdCompleter;
-import org.onosproject.cli.net.PortNumberCompleter;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 import org.opencord.olt.AccessDeviceService;
 
 /**
- * Adds a subscriber to an access device.
+ * Removes a subscriber to an access device.
  */
 @Service
 @Command(scope = "onos", name = "volt-remove-subscriber-access",
-        description = "Removes a subscriber to an access device")
+        description = "Remove a subscriber from an access device")
 public class SubscriberRemoveCommand extends AbstractShellCommand {
 
     @Argument(index = 0, name = "deviceId", description = "Access device ID",
@@ -43,18 +42,16 @@
 
     @Argument(index = 1, name = "port", description = "Subscriber port number",
             required = true, multiValued = false)
-    @Completion(PortNumberCompleter.class)
+    @Completion(OltUniPortCompleter.class)
     private String strPort = null;
 
     @Override
     protected void doExecute() {
         AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
-
         DeviceId deviceId = DeviceId.deviceId(strDeviceId);
         PortNumber port = PortNumber.portNumber(strPort);
         ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
 
         service.removeSubscriber(connectPoint);
-
     }
-}
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/cli/UniTagAddCommand.java b/impl/src/main/java/org/opencord/olt/cli/UniTagAddCommand.java
index 4eb6495..bd42704 100644
--- a/impl/src/main/java/org/opencord/olt/cli/UniTagAddCommand.java
+++ b/impl/src/main/java/org/opencord/olt/cli/UniTagAddCommand.java
@@ -22,10 +22,10 @@
 import org.apache.karaf.shell.api.action.lifecycle.Service;
 import org.onlab.packet.VlanId;
 import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
 import org.opencord.olt.AccessDeviceService;
-import org.opencord.olt.AccessSubscriberId;
 
-import java.util.Optional;
+import static com.google.common.base.Strings.isNullOrEmpty;
 
 /**
  * Adds a subscriber uni tag.
@@ -37,29 +37,39 @@
 
     @Argument(index = 0, name = "portName", description = "Port name",
             required = true, multiValued = false)
-    private String strPortName = null;
+    private String portName = null;
 
     @Option(name = "--cTag", description = "Inner vlan id",
-            required = false, multiValued = false)
+            required = true, multiValued = false)
     private String strCtag = null;
 
     @Option(name = "--sTag", description = "Outer vlan id",
-            required = false, multiValued = false)
+            required = true, multiValued = false)
     private String strStag = null;
 
     @Option(name = "--tpId", description = "Technology profile id",
-            required = false, multiValued = false)
+            required = true, multiValued = false)
     private String strTpId = null;
 
     @Override
     protected void doExecute() {
 
         AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
-        AccessSubscriberId portName = new AccessSubscriberId(strPortName);
+        ConnectPoint cp = service.findSubscriberConnectPoint(portName);
+        if (cp == null) {
+            log.warn("ConnectPoint not found for {}", portName);
+            print("ConnectPoint not found for %s", portName);
+            return;
+        }
+        if (isNullOrEmpty(strCtag) || isNullOrEmpty(strStag) || isNullOrEmpty(strTpId)) {
+            print("Values for c-tag (%s), s-tag (%s) and technology profile Id (%s) " +
+                          "are required", strCtag, strStag, strTpId);
+            return;
+        }
 
-        Optional<VlanId> cTag = strCtag == null ? Optional.empty() : Optional.of(VlanId.vlanId(strCtag));
-        Optional<VlanId> sTag = strStag == null ? Optional.empty() : Optional.of(VlanId.vlanId(strStag));
-        Optional<Integer> tpId = strTpId == null ? Optional.empty() : Optional.of(Integer.parseInt(strTpId));
-        service.provisionSubscriber(portName, sTag, cTag, tpId);
+        VlanId cTag = VlanId.vlanId(strCtag);
+        VlanId sTag = VlanId.vlanId(strStag);
+        Integer tpId = Integer.valueOf(strTpId);
+        service.provisionSubscriber(cp, cTag, sTag, tpId);
     }
 }
diff --git a/impl/src/main/java/org/opencord/olt/cli/UniTagRemoveCommand.java b/impl/src/main/java/org/opencord/olt/cli/UniTagRemoveCommand.java
index e256914..d05418a 100644
--- a/impl/src/main/java/org/opencord/olt/cli/UniTagRemoveCommand.java
+++ b/impl/src/main/java/org/opencord/olt/cli/UniTagRemoveCommand.java
@@ -22,10 +22,11 @@
 import org.apache.karaf.shell.api.action.lifecycle.Service;
 import org.onlab.packet.VlanId;
 import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
 import org.opencord.olt.AccessDeviceService;
-import org.opencord.olt.AccessSubscriberId;
 
-import java.util.Optional;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
 
 /**
  * Removes a uni tag from a subscriber (portname).
@@ -37,29 +38,39 @@
 
     @Argument(index = 0, name = "portName", description = "Port name",
             required = true, multiValued = false)
-    private String strPortName = null;
+    private String portName = null;
 
     @Option(name = "--cTag", description = "Inner vlan id",
-            required = false, multiValued = false)
+            required = true, multiValued = false)
     private String strCtag = null;
 
     @Option(name = "--sTag", description = "Outer vlan id",
-            required = false, multiValued = false)
+            required = true, multiValued = false)
     private String strStag = null;
 
     @Option(name = "--tpId", description = "Technology profile id",
-            required = false, multiValued = false)
+            required = true, multiValued = false)
     private String strTpId = null;
 
     @Override
     protected void doExecute() {
 
         AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
-        AccessSubscriberId portName = new AccessSubscriberId(strPortName);
+        ConnectPoint cp = service.findSubscriberConnectPoint(portName);
+        if (cp == null) {
+            log.warn("ConnectPoint not found for {}", portName);
+            print("ConnectPoint not found for %s", portName);
+            return;
+        }
+        if (isNullOrEmpty(strCtag) || isNullOrEmpty(strStag) || isNullOrEmpty(strTpId)) {
+            print("Values for c-tag (%s), s-tag (%s) and technology profile Id (%s) " +
+                          "are required", strCtag, strStag, strTpId);
+            return;
+        }
 
-        Optional<VlanId> cTag = strCtag == null ? Optional.empty() : Optional.of(VlanId.vlanId(strCtag));
-        Optional<VlanId> sTag = strStag == null ? Optional.empty() : Optional.of(VlanId.vlanId(strStag));
-        Optional<Integer> tpId = strTpId == null ? Optional.empty() : Optional.of(Integer.parseInt(strTpId));
-        service.removeSubscriber(portName, sTag, cTag, tpId);
+        VlanId cTag = VlanId.vlanId(strCtag);
+        VlanId sTag = VlanId.vlanId(strStag);
+        Integer tpId = Integer.valueOf(strTpId);
+        service.removeSubscriber(cp, cTag, sTag, tpId);
     }
 }
diff --git a/impl/src/main/java/org/opencord/olt/cli/package-info.java b/impl/src/main/java/org/opencord/olt/cli/package-info.java
index b100077..c657d73 100644
--- a/impl/src/main/java/org/opencord/olt/cli/package-info.java
+++ b/impl/src/main/java/org/opencord/olt/cli/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,6 +15,6 @@
  */
 
 /**
- * OLT application handling PMC OLT hardware.
+ * CLI package for OLT application.
  */
-package org.opencord.olt.cli;
+package org.opencord.olt.cli;
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/driver/NokiaOltPipeline.java b/impl/src/main/java/org/opencord/olt/driver/NokiaOltPipeline.java
deleted file mode 100644
index f8b9009..0000000
--- a/impl/src/main/java/org/opencord/olt/driver/NokiaOltPipeline.java
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.opencord.olt.driver;
-
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.RemovalCause;
-import com.google.common.cache.RemovalNotification;
-import com.google.common.collect.Lists;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.commons.lang3.tuple.Pair;
-import org.onlab.osgi.ServiceDirectory;
-import org.onlab.packet.EthType;
-import org.onlab.packet.IPv4;
-import org.onlab.packet.VlanId;
-import org.onlab.util.KryoNamespace;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.behaviour.NextGroup;
-import org.onosproject.net.behaviour.Pipeliner;
-import org.onosproject.net.behaviour.PipelinerContext;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleOperations;
-import org.onosproject.net.flow.FlowRuleOperationsContext;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.EthTypeCriterion;
-import org.onosproject.net.flow.criteria.IPCriterion;
-import org.onosproject.net.flow.criteria.IPProtocolCriterion;
-import org.onosproject.net.flow.criteria.PortCriterion;
-import org.onosproject.net.flow.criteria.VlanIdCriterion;
-import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.flow.instructions.L2ModificationInstruction;
-import org.onosproject.net.flowobjective.FilteringObjective;
-import org.onosproject.net.flowobjective.FlowObjectiveStore;
-import org.onosproject.net.flowobjective.ForwardingObjective;
-import org.onosproject.net.flowobjective.NextObjective;
-import org.onosproject.net.flowobjective.Objective;
-import org.onosproject.net.flowobjective.ObjectiveError;
-import org.onosproject.net.group.DefaultGroupBucket;
-import org.onosproject.net.group.DefaultGroupDescription;
-import org.onosproject.net.group.DefaultGroupKey;
-import org.onosproject.net.group.Group;
-import org.onosproject.net.group.GroupBucket;
-import org.onosproject.net.group.GroupBuckets;
-import org.onosproject.net.group.GroupDescription;
-import org.onosproject.net.group.GroupEvent;
-import org.onosproject.net.group.GroupKey;
-import org.onosproject.net.group.GroupListener;
-import org.onosproject.net.group.GroupService;
-import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.StorageService;
-import org.slf4j.Logger;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Pipeliner for OLT device.
- */
-
-public class NokiaOltPipeline extends AbstractHandlerBehaviour implements Pipeliner {
-
-    private static final Integer QQ_TABLE = 1;
-    private static final short MCAST_VLAN = 4000;
-    private static final String OLTCOOKIES = "olt-cookies-must-be-unique";
-    private static final int EAPOL_FLOW_PRIORITY = 1200;
-    private final Logger log = getLogger(getClass());
-
-    private ServiceDirectory serviceDirectory;
-    private FlowRuleService flowRuleService;
-    private GroupService groupService;
-    private CoreService coreService;
-    private StorageService storageService;
-
-    private DeviceId deviceId;
-    private ApplicationId appId;
-
-
-    protected FlowObjectiveStore flowObjectiveStore;
-
-    private Cache<GroupKey, NextObjective> pendingGroups;
-
-    protected static KryoNamespace appKryo = new KryoNamespace.Builder()
-            .register(KryoNamespaces.API)
-            .register(GroupKey.class)
-            .register(DefaultGroupKey.class)
-            .register(OltPipelineGroup.class)
-            .build("OltPipeline");
-    @Override
-    public void init(DeviceId deviceId, PipelinerContext context) {
-        log.debug("Initiate OLT pipeline");
-        this.serviceDirectory = context.directory();
-        this.deviceId = deviceId;
-
-        flowRuleService = serviceDirectory.get(FlowRuleService.class);
-        coreService = serviceDirectory.get(CoreService.class);
-        groupService = serviceDirectory.get(GroupService.class);
-        flowObjectiveStore = context.store();
-        storageService = serviceDirectory.get(StorageService.class);
-
-        appId = coreService.registerApplication(
-                "org.onosproject.driver.OLTPipeline");
-
-
-        pendingGroups = CacheBuilder.newBuilder()
-                .expireAfterWrite(20, TimeUnit.SECONDS)
-                .removalListener((RemovalNotification<GroupKey, NextObjective> notification) -> {
-                    if (notification.getCause() == RemovalCause.EXPIRED) {
-                        fail(notification.getValue(), ObjectiveError.GROUPINSTALLATIONFAILED);
-                    }
-                }).build();
-
-        groupService.addListener(new InnerGroupListener());
-
-    }
-
-    @Override
-    public void filter(FilteringObjective filter) {
-        Instructions.OutputInstruction output;
-
-        if (filter.meta() != null && !filter.meta().immediate().isEmpty()) {
-            output = (Instructions.OutputInstruction) filter.meta().immediate().stream()
-                    .filter(t -> t.type().equals(Instruction.Type.OUTPUT))
-                    .limit(1)
-                    .findFirst().get();
-
-            if (output == null || !output.port().equals(PortNumber.CONTROLLER)) {
-                log.error("OLT can only filter packet to controller");
-                fail(filter, ObjectiveError.UNSUPPORTED);
-                return;
-            }
-        } else {
-            fail(filter, ObjectiveError.BADPARAMS);
-            return;
-        }
-
-        if (filter.key().type() != Criterion.Type.IN_PORT) {
-            fail(filter, ObjectiveError.BADPARAMS);
-            return;
-        }
-
-        EthTypeCriterion ethType = (EthTypeCriterion)
-                filterForCriterion(filter.conditions(), Criterion.Type.ETH_TYPE);
-
-        if (ethType == null) {
-            fail(filter, ObjectiveError.BADPARAMS);
-            return;
-        }
-
-        if (ethType.ethType().equals(EthType.EtherType.EAPOL.ethType())) {
-            provisionEapol(filter, ethType, output);
-        } else if (ethType.ethType().equals(EthType.EtherType.IPV4.ethType())) {
-            IPProtocolCriterion ipProto = (IPProtocolCriterion)
-                    filterForCriterion(filter.conditions(), Criterion.Type.IP_PROTO);
-            if (ipProto.protocol() == IPv4.PROTOCOL_IGMP) {
-                provisionIgmp(filter, ethType, ipProto, output);
-            } else {
-                log.error("OLT can only filter igmp");
-                fail(filter, ObjectiveError.UNSUPPORTED);
-            }
-        } else {
-            log.error("OLT can only filter eapol and igmp");
-            fail(filter, ObjectiveError.UNSUPPORTED);
-        }
-
-    }
-
-    private void installObjective(FlowRule.Builder ruleBuilder, Objective objective) {
-        FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
-        switch (objective.op()) {
-
-            case ADD:
-                flowBuilder.add(ruleBuilder.build());
-                break;
-            case REMOVE:
-                flowBuilder.remove(ruleBuilder.build());
-                break;
-            default:
-                log.warn("Unknown operation {}", objective.op());
-        }
-
-        flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
-            @Override
-            public void onSuccess(FlowRuleOperations ops) {
-                objective.context().ifPresent(context -> context.onSuccess(objective));
-            }
-
-            @Override
-            public void onError(FlowRuleOperations ops) {
-                objective.context()
-                        .ifPresent(context -> context.onError(objective, ObjectiveError.FLOWINSTALLATIONFAILED));
-            }
-        }));
-    }
-
-    @Override
-    public void forward(ForwardingObjective fwd) {
-
-        if (checkForMulticast(fwd)) {
-            processMulticastRule(fwd);
-            return;
-        }
-
-        if (checkForEapol(fwd)) {
-            log.warn("Discarding EAPOL flow which is not supported on this pipeline");
-            return;
-        }
-
-        TrafficTreatment treatment = fwd.treatment();
-
-        List<Instruction> instructions = treatment.allInstructions();
-
-        Optional<Instruction> vlanIntruction = instructions.stream()
-                .filter(i -> i.type() == Instruction.Type.L2MODIFICATION)
-                .filter(i -> ((L2ModificationInstruction) i).subtype() ==
-                        L2ModificationInstruction.L2SubType.VLAN_PUSH ||
-                        ((L2ModificationInstruction) i).subtype() ==
-                                L2ModificationInstruction.L2SubType.VLAN_POP)
-                .findAny();
-
-        if (vlanIntruction.isPresent()) {
-            L2ModificationInstruction vlanIns =
-                    (L2ModificationInstruction) vlanIntruction.get();
-
-            if (vlanIns.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
-                installUpstreamRules(fwd);
-            } else if (vlanIns.subtype() == L2ModificationInstruction.L2SubType.VLAN_POP) {
-                installDownstreamRules(fwd);
-            } else {
-                log.error("Unknown OLT operation: {}", fwd);
-                fail(fwd, ObjectiveError.UNSUPPORTED);
-                return;
-            }
-
-            pass(fwd);
-        } else {
-            TrafficSelector selector = fwd.selector();
-
-            if (fwd.treatment() != null) {
-                // Deal with SPECIFIC and VERSATILE in the same manner.
-                FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
-                        .forDevice(deviceId)
-                        .withSelector(selector)
-                        .fromApp(fwd.appId())
-                        .withPriority(fwd.priority())
-                        .withTreatment(fwd.treatment());
-
-                if (fwd.permanent()) {
-                    ruleBuilder.makePermanent();
-                } else {
-                    ruleBuilder.makeTemporary(fwd.timeout());
-                }
-                installObjective(ruleBuilder, fwd);
-
-            } else {
-                log.error("No treatment error: {}", fwd);
-                fail(fwd, ObjectiveError.UNSUPPORTED);
-            }
-        }
-
-    }
-
-
-    @Override
-    public void next(NextObjective nextObjective) {
-        if (nextObjective.type() != NextObjective.Type.BROADCAST) {
-            log.error("OLT only supports broadcast groups.");
-            fail(nextObjective, ObjectiveError.BADPARAMS);
-        }
-
-        if (nextObjective.next().size() != 1) {
-            log.error("OLT only supports singleton broadcast groups.");
-            fail(nextObjective, ObjectiveError.BADPARAMS);
-        }
-
-        TrafficTreatment treatment = nextObjective.next().stream().findFirst().get();
-
-
-        GroupBucket bucket = DefaultGroupBucket.createAllGroupBucket(treatment);
-        GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
-
-
-        pendingGroups.put(key, nextObjective);
-
-        switch (nextObjective.op()) {
-            case ADD:
-                GroupDescription groupDesc =
-                        new DefaultGroupDescription(deviceId,
-                                                    GroupDescription.Type.ALL,
-                                                    new GroupBuckets(Collections.singletonList(bucket)),
-                                                    key,
-                                                    null,
-                                                    nextObjective.appId());
-                groupService.addGroup(groupDesc);
-                break;
-            case REMOVE:
-                groupService.removeGroup(deviceId, key, nextObjective.appId());
-                break;
-            case ADD_TO_EXISTING:
-                groupService.addBucketsToGroup(deviceId, key,
-                                               new GroupBuckets(Collections.singletonList(bucket)),
-                                               key, nextObjective.appId());
-                break;
-            case REMOVE_FROM_EXISTING:
-                groupService.removeBucketsFromGroup(deviceId, key,
-                                                    new GroupBuckets(Collections.singletonList(bucket)),
-                                                    key, nextObjective.appId());
-                break;
-            default:
-                log.warn("Unknown next objective operation: {}", nextObjective.op());
-        }
-
-
-    }
-
-    private void processMulticastRule(ForwardingObjective fwd) {
-        if (fwd.nextId() == null) {
-            log.error("Multicast objective does not have a next id");
-            fail(fwd, ObjectiveError.BADPARAMS);
-        }
-
-        GroupKey key = getGroupForNextObjective(fwd.nextId());
-
-        if (key == null) {
-            log.error("Group for forwarding objective missing: {}", fwd);
-            fail(fwd, ObjectiveError.GROUPMISSING);
-        }
-
-        Group group = groupService.getGroup(deviceId, key);
-        TrafficTreatment treatment =
-                buildTreatment(Instructions.createGroup(group.id()));
-
-        FlowRule rule = DefaultFlowRule.builder()
-                .fromApp(fwd.appId())
-                .forDevice(deviceId)
-                .forTable(0)
-                .makePermanent()
-                .withPriority(fwd.priority())
-                .withSelector(fwd.selector())
-                .withTreatment(treatment)
-                .build();
-
-        FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
-        switch (fwd.op()) {
-
-            case ADD:
-                builder.add(rule);
-                break;
-            case REMOVE:
-                builder.remove(rule);
-                break;
-            case ADD_TO_EXISTING:
-            case REMOVE_FROM_EXISTING:
-                break;
-            default:
-                log.warn("Unknown forwarding operation: {}", fwd.op());
-        }
-
-        applyFlowRules(builder, fwd);
-
-    }
-
-    private boolean checkForMulticast(ForwardingObjective fwd) {
-
-        IPCriterion ip = (IPCriterion) filterForCriterion(fwd.selector().criteria(),
-                                                          Criterion.Type.IPV4_DST);
-
-        if (ip == null) {
-            return false;
-        }
-
-        return ip.ip().isMulticast();
-
-    }
-
-    private boolean checkForEapol(ForwardingObjective fwd) {
-        EthTypeCriterion ethType = (EthTypeCriterion)
-                filterForCriterion(fwd.selector().criteria(), Criterion.Type.ETH_TYPE);
-
-        return ethType != null && ethType.ethType().equals(EthType.EtherType.EAPOL.ethType());
-    }
-    private GroupKey getGroupForNextObjective(Integer nextId) {
-        NextGroup next = flowObjectiveStore.getNextGroup(nextId);
-        return appKryo.deserialize(next.data());
-
-    }
-
-    private void installDownstreamRules(ForwardingObjective fwd) {
-        List<Pair<Instruction, Instruction>> vlanOps =
-                vlanOps(fwd,
-                        L2ModificationInstruction.L2SubType.VLAN_POP);
-
-        if (vlanOps == null) {
-            return;
-        }
-
-        Instructions.OutputInstruction output = (Instructions.OutputInstruction) fetchOutput(fwd, "downstream");
-
-        if (output == null) {
-            return;
-        }
-
-        Pair<Instruction, Instruction> popAndRewrite = vlanOps.remove(0);
-
-        TrafficSelector selector = fwd.selector();
-
-        Criterion outerVlan = selector.getCriterion(Criterion.Type.VLAN_VID);
-        Criterion innerVlan = selector.getCriterion(Criterion.Type.INNER_VLAN_VID);
-        Criterion inport = selector.getCriterion(Criterion.Type.IN_PORT);
-        Criterion bullshit = Criteria.matchMetadata(output.port().toLong());
-
-        if (outerVlan == null || innerVlan == null || inport == null) {
-            log.error("Forwarding objective is underspecified: {}", fwd);
-            fail(fwd, ObjectiveError.BADPARAMS);
-            return;
-        }
-
-        Criterion innerVid = Criteria.matchVlanId(((VlanIdCriterion) innerVlan).vlanId());
-
-        FlowRule.Builder outer = DefaultFlowRule.builder()
-                .fromApp(fwd.appId())
-                .forDevice(deviceId)
-                .makePermanent()
-                .withPriority(fwd.priority())
-                .withSelector(buildSelector(inport, outerVlan, bullshit))
-                .withTreatment(buildTreatment(popAndRewrite.getLeft(),
-                                              Instructions.transition(QQ_TABLE)));
-
-        FlowRule.Builder inner = DefaultFlowRule.builder()
-                .fromApp(fwd.appId())
-                .forDevice(deviceId)
-                .forTable(QQ_TABLE)
-                .makePermanent()
-                .withPriority(fwd.priority())
-                .withSelector(buildSelector(inport, innerVid))
-                .withTreatment(buildTreatment(popAndRewrite.getLeft(),
-                                              output));
-
-        applyRules(fwd, inner, outer);
-
-    }
-
-    private boolean hasUntaggedVlanTag(TrafficSelector selector) {
-        Iterator<Criterion> iter = selector.criteria().iterator();
-
-        while (iter.hasNext()) {
-            Criterion criterion = iter.next();
-            if (criterion.type() == Criterion.Type.VLAN_VID &&
-                    ((VlanIdCriterion) criterion).vlanId().toShort() == VlanId.UNTAGGED) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private void installUpstreamRules(ForwardingObjective fwd) {
-        List<Pair<Instruction, Instruction>> vlanOps =
-                vlanOps(fwd,
-                        L2ModificationInstruction.L2SubType.VLAN_PUSH);
-        FlowRule.Builder inner;
-
-        if (vlanOps == null) {
-            return;
-        }
-
-        Instruction output = fetchOutput(fwd, "upstream");
-
-        if (output == null) {
-            return;
-        }
-
-        Pair<Instruction, Instruction> innerPair = vlanOps.remove(0);
-
-        Pair<Instruction, Instruction> outerPair = vlanOps.remove(0);
-
-
-        if (hasUntaggedVlanTag(fwd.selector())) {
-            inner = DefaultFlowRule.builder()
-                    .fromApp(fwd.appId())
-                    .forDevice(deviceId)
-                    .makePermanent()
-                    .withPriority(fwd.priority())
-                    .withSelector(fwd.selector())
-                    .withTreatment(buildTreatment(innerPair.getLeft(),
-                                                  innerPair.getRight(),
-                                                  Instructions.transition(QQ_TABLE)));
-        } else {
-            inner = DefaultFlowRule.builder()
-                    .fromApp(fwd.appId())
-                    .forDevice(deviceId)
-                    .makePermanent()
-                    .withPriority(fwd.priority())
-                    .withSelector(fwd.selector())
-                    .withTreatment(buildTreatment(
-                            innerPair.getRight(),
-                            Instructions.transition(QQ_TABLE)));
-        }
-
-
-        PortCriterion inPort = (PortCriterion)
-                fwd.selector().getCriterion(Criterion.Type.IN_PORT);
-
-        VlanId cVlanId = ((L2ModificationInstruction.ModVlanIdInstruction)
-                innerPair.getRight()).vlanId();
-
-        FlowRule.Builder outer = DefaultFlowRule.builder()
-                .fromApp(fwd.appId())
-                .forDevice(deviceId)
-                .forTable(QQ_TABLE)
-                .makePermanent()
-                .withPriority(fwd.priority())
-                .withSelector(buildSelector(inPort,
-                                            Criteria.matchVlanId(cVlanId)))
-                .withTreatment(buildTreatment(outerPair.getLeft(),
-                                              outerPair.getRight(),
-                                              output));
-
-        applyRules(fwd, inner, outer);
-
-    }
-
-    private Instruction fetchOutput(ForwardingObjective fwd, String direction) {
-        Instruction output = fwd.treatment().allInstructions().stream()
-                .filter(i -> i.type() == Instruction.Type.OUTPUT)
-                .findFirst().orElse(null);
-
-        if (output == null) {
-            log.error("OLT {} rule has no output", direction);
-            fail(fwd, ObjectiveError.BADPARAMS);
-            return null;
-        }
-        return output;
-    }
-
-    private List<Pair<Instruction, Instruction>> vlanOps(ForwardingObjective fwd,
-                                                         L2ModificationInstruction.L2SubType type) {
-
-        List<Pair<Instruction, Instruction>> vlanOps = findVlanOps(
-                fwd.treatment().allInstructions(), type);
-
-        if (vlanOps == null) {
-            String direction = type == L2ModificationInstruction.L2SubType.VLAN_POP
-                    ? "downstream" : "upstream";
-            log.error("Missing vlan operations in {} forwarding: {}", direction, fwd);
-            fail(fwd, ObjectiveError.BADPARAMS);
-            return null;
-        }
-        return vlanOps;
-    }
-
-
-    private List<Pair<Instruction, Instruction>> findVlanOps(List<Instruction> instructions,
-                                                             L2ModificationInstruction.L2SubType type) {
-
-        List<Instruction> vlanPushs = findL2Instructions(
-                type,
-                instructions);
-        List<Instruction> vlanSets = findL2Instructions(
-                L2ModificationInstruction.L2SubType.VLAN_ID,
-                instructions);
-
-        if (vlanPushs.size() != vlanSets.size()) {
-            return null;
-        }
-
-        List<Pair<Instruction, Instruction>> pairs = Lists.newArrayList();
-
-        for (int i = 0; i < vlanPushs.size(); i++) {
-            pairs.add(new ImmutablePair<>(vlanPushs.get(i), vlanSets.get(i)));
-        }
-        return pairs;
-    }
-
-    private List<Instruction> findL2Instructions(L2ModificationInstruction.L2SubType subType,
-                                                 List<Instruction> actions) {
-        return actions.stream()
-                .filter(i -> i.type() == Instruction.Type.L2MODIFICATION)
-                .filter(i -> ((L2ModificationInstruction) i).subtype() == subType)
-                .collect(Collectors.toList());
-    }
-
-    private void provisionEapol(FilteringObjective filter,
-                                EthTypeCriterion ethType,
-                                Instructions.OutputInstruction output) {
-
-        TrafficSelector selector = buildSelector(filter.key(), ethType);
-        TrafficTreatment treatment = buildTreatment(output);
-        buildAndApplyRule(filter, selector, treatment, EAPOL_FLOW_PRIORITY);
-
-    }
-
-    private void provisionIgmp(FilteringObjective filter, EthTypeCriterion ethType,
-                               IPProtocolCriterion ipProto,
-                               Instructions.OutputInstruction output) {
-        TrafficSelector selector = buildSelector(filter.key(), ethType, ipProto);
-        TrafficTreatment treatment = buildTreatment(output);
-        buildAndApplyRule(filter, selector, treatment);
-    }
-
-    private void buildAndApplyRule(FilteringObjective filter, TrafficSelector selector,
-                                   TrafficTreatment treatment) {
-        buildAndApplyRule(filter, selector, treatment, filter.priority());
-    }
-
-    private void buildAndApplyRule(FilteringObjective filter, TrafficSelector selector,
-                                   TrafficTreatment treatment, int priority) {
-        FlowRule rule = DefaultFlowRule.builder()
-                .fromApp(filter.appId())
-                .forDevice(deviceId)
-                .forTable(0)
-                .makePermanent()
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(priority)
-                .build();
-
-        FlowRuleOperations.Builder opsBuilder = FlowRuleOperations.builder();
-
-        switch (filter.type()) {
-            case PERMIT:
-                opsBuilder.add(rule);
-                break;
-            case DENY:
-                opsBuilder.remove(rule);
-                break;
-            default:
-                log.warn("Unknown filter type : {}", filter.type());
-                fail(filter, ObjectiveError.UNSUPPORTED);
-        }
-
-        applyFlowRules(opsBuilder, filter);
-    }
-
-    private void applyRules(ForwardingObjective fwd,
-                            FlowRule.Builder inner, FlowRule.Builder outer) {
-        FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
-        switch (fwd.op()) {
-            case ADD:
-                builder.add(inner.build()).add(outer.build());
-                break;
-            case REMOVE:
-                builder.remove(inner.build()).remove(outer.build());
-                break;
-            case ADD_TO_EXISTING:
-                break;
-            case REMOVE_FROM_EXISTING:
-                break;
-            default:
-                log.warn("Unknown forwarding operation: {}", fwd.op());
-        }
-
-        applyFlowRules(builder, fwd);
-    }
-
-    private void applyFlowRules(FlowRuleOperations.Builder builder,
-                                Objective objective) {
-        flowRuleService.apply(builder.build(new FlowRuleOperationsContext() {
-            @Override
-            public void onSuccess(FlowRuleOperations ops) {
-                pass(objective);
-            }
-
-            @Override
-            public void onError(FlowRuleOperations ops) {
-                fail(objective, ObjectiveError.FLOWINSTALLATIONFAILED);
-            }
-        }));
-    }
-
-    private Criterion filterForCriterion(Collection<Criterion> criteria, Criterion.Type type) {
-        return criteria.stream()
-                .filter(c -> c.type().equals(type))
-                .limit(1)
-                .findFirst().orElse(null);
-    }
-
-    private TrafficSelector buildSelector(Criterion... criteria) {
-
-
-        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
-
-        for (Criterion c : criteria) {
-            sBuilder.add(c);
-        }
-
-        return sBuilder.build();
-    }
-
-    private TrafficTreatment buildTreatment(Instruction... instructions) {
-
-
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-
-        for (Instruction i : instructions) {
-            tBuilder.add(i);
-        }
-
-        return tBuilder.build();
-    }
-
-
-    private void fail(Objective obj, ObjectiveError error) {
-        obj.context().ifPresent(context -> context.onError(obj, error));
-    }
-
-    private void pass(Objective obj) {
-        obj.context().ifPresent(context -> context.onSuccess(obj));
-    }
-
-
-    private class InnerGroupListener implements GroupListener {
-        @Override
-        public void event(GroupEvent event) {
-            if (event.type() == GroupEvent.Type.GROUP_ADDED || event.type() == GroupEvent.Type.GROUP_UPDATED) {
-                GroupKey key = event.subject().appCookie();
-
-                NextObjective obj = pendingGroups.getIfPresent(key);
-                if (obj != null) {
-                    flowObjectiveStore.putNextGroup(obj.id(), new OltPipelineGroup(key));
-                    pass(obj);
-                    pendingGroups.invalidate(key);
-                }
-            }
-        }
-    }
-
-    private static class OltPipelineGroup implements NextGroup {
-
-        private final GroupKey key;
-
-        public OltPipelineGroup(GroupKey key) {
-            this.key = key;
-        }
-
-        public GroupKey key() {
-            return key;
-        }
-
-        @Override
-        public byte[] data() {
-            return appKryo.serialize(key);
-        }
-
-    }
-
-    @Override
-    public List<String> getNextMappings(NextGroup nextGroup) {
-        // TODO Implementation deferred to vendor
-        return null;
-    }
-}
diff --git a/impl/src/main/java/org/opencord/olt/driver/OltPipeline.java b/impl/src/main/java/org/opencord/olt/driver/OltPipeline.java
index 459526c..29d234b 100644
--- a/impl/src/main/java/org/opencord/olt/driver/OltPipeline.java
+++ b/impl/src/main/java/org/opencord/olt/driver/OltPipeline.java
@@ -1152,7 +1152,9 @@
     // Builds the batch using the accumulated flow rules
     private void sendFilters(List<Pair<FilteringObjective, FlowRule>> pairs) {
         FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder();
-        log.debug("Sending batch of {} filter-objs", pairs.size());
+        if (log.isDebugEnabled()) {
+            log.debug("Sending batch of {} filter-objs", pairs.size());
+        }
         List<Objective> filterObjs = Lists.newArrayList();
         // Iterates over all accumulated flow rules and then build an unique batch
         pairs.forEach(pair -> {
@@ -1161,12 +1163,16 @@
             switch (filter.type()) {
                 case PERMIT:
                     flowOpsBuilder.add(rule);
-                    log.debug("Applying add filter-obj {} to device: {}", filter.id(), deviceId);
+                    if (log.isTraceEnabled()) {
+                        log.trace("Applying add filter-obj {} to device: {}", filter.id(), deviceId);
+                    }
                     filterObjs.add(filter);
                     break;
                 case DENY:
                     flowOpsBuilder.remove(rule);
-                    log.debug("Deleting flow rule {} to device: {}", rule, deviceId);
+                    if (log.isTraceEnabled()) {
+                        log.trace("Deleting flow rule {} from device: {}", rule, deviceId);
+                    }
                     filterObjs.add(filter);
                     break;
                 default:
diff --git a/impl/src/main/java/org/opencord/olt/impl/AccessDevicePort.java b/impl/src/main/java/org/opencord/olt/impl/AccessDevicePort.java
new file mode 100644
index 0000000..b6d2213
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/AccessDevicePort.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.opencord.olt.impl;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Port;
+
+import java.util.Objects;
+
+/**
+ * OLT device port.
+ */
+public class AccessDevicePort {
+
+    private ConnectPoint cp;
+    private String name;
+
+    /**
+     * Creates an AccessDevicePort with given ONOS port.
+     *
+     * @param port ONOS port
+     */
+    public AccessDevicePort(Port port) {
+        this.cp = ConnectPoint.deviceConnectPoint(port.element().id() + "/" + port.number().toLong());
+        this.name = OltUtils.getPortName(port);
+    }
+
+    /**
+     * Creates an AccessDevicePort with given ONOS connectPoint and name.
+     *
+     * @param cp ONOS connect point
+     * @param name OLT port name
+     */
+    public AccessDevicePort(ConnectPoint cp, String name) {
+        this.cp = cp;
+        this.name = name;
+    }
+
+    /**
+     * Get ONOS ConnectPoint object.
+     *
+     * @return ONOS connect point
+     */
+    public ConnectPoint connectPoint() {
+        return this.cp;
+    }
+
+    /**
+     * Get OLT port name which is combination of serial number and uni index.
+     *
+     * @return OLT port name (ex: BBSM00010001-1)
+     */
+    public String name() {
+        return this.name;
+    }
+
+    @Override
+    public String toString() {
+        return cp.toString() + '[' + name + ']';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        AccessDevicePort that = (AccessDevicePort) o;
+        return Objects.equals(cp, that.cp) &&
+                Objects.equals(name, that.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(cp, name);
+    }
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/ConsistentHasher.java b/impl/src/main/java/org/opencord/olt/impl/ConsistentHasher.java
deleted file mode 100644
index 52e9b96..0000000
--- a/impl/src/main/java/org/opencord/olt/impl/ConsistentHasher.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2020-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.opencord.olt.impl;
-
-import com.google.common.hash.Hashing;
-import org.onosproject.cluster.NodeId;
-
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Returns a server hosting a given key based on consistent hashing.
- */
-public class ConsistentHasher {
-
-    private static class Entry implements Comparable<Entry> {
-        private final NodeId server;
-        private final int hash;
-
-        public Entry(NodeId server, int hash) {
-            this.server = server;
-            this.hash = hash;
-        }
-
-        public Entry(int hash) {
-            server = null;
-            this.hash = hash;
-        }
-
-        @Override
-        public int compareTo(Entry o) {
-            if (this.hash > o.hash) {
-                return 1;
-            } else if (this.hash < o.hash) {
-                return -1;
-            } // else
-            return 0;
-        }
-    }
-
-    private final int weight;
-
-    private List<Entry> table;
-
-    /**
-     * Creates a new hasher with the given list of servers.
-     *
-     * @param servers list of servers
-     * @param weight weight
-     */
-    public ConsistentHasher(List<NodeId> servers, int weight) {
-        this.weight = weight;
-
-        this.table = new ArrayList<>();
-
-        servers.forEach(this::addServer);
-    }
-
-    /**
-     * Adds a new server to the list of servers.
-     *
-     * @param server server ID
-     */
-    public synchronized void addServer(NodeId server) {
-        // Add weight number of buckets for each server
-        for (int i = 0; i < weight; i++) {
-            String label = server.toString() + i;
-            int hash = getHash(label);
-            Entry e = new Entry(server, hash);
-            table.add(e);
-        }
-
-        Collections.sort(table);
-    }
-
-    /**
-     * Removes a server from the list of servers.
-     *
-     * @param server server ID
-     */
-    public synchronized void removeServer(NodeId server) {
-        table.removeIf(e -> e.server.equals(server));
-    }
-
-    /**
-     * Hashes a given input string and finds that server that should
-     * handle the given ID.
-     *
-     * @param s input
-     * @return server ID
-     */
-    public synchronized NodeId hash(String s) {
-        Entry temp = new Entry(getHash(s));
-
-        int pos = Collections.binarySearch(this.table, temp);
-
-        // translate a negative not-found result into the closest following match
-        if (pos < 0) {
-            pos = Math.abs(pos + 1);
-        }
-
-        // wraparound if the hash was after the last entry in the table
-        if (pos == this.table.size()) {
-            pos = 0;
-        }
-
-        return table.get(pos).server;
-    }
-
-    private int getHash(String s) {
-        // stable, uniformly-distributed hash
-        return Hashing.murmur3_128().hashString(s, Charset.defaultCharset()).asInt();
-    }
-}
diff --git a/impl/src/main/java/org/opencord/olt/impl/DiscoveredSubscriber.java b/impl/src/main/java/org/opencord/olt/impl/DiscoveredSubscriber.java
new file mode 100644
index 0000000..4280eaf
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/DiscoveredSubscriber.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.onosproject.net.Device;
+import org.onosproject.net.Port;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+
+import java.util.Objects;
+
+import static org.opencord.olt.impl.OltUtils.portWithName;
+
+/**
+ * Contains a subscriber's information and status for a specific device and port.
+ */
+public class DiscoveredSubscriber {
+
+    /**
+     * Describe whether the subscriber needs to be added or removed.
+     */
+    public enum Status {
+        ADDED,
+        REMOVED,
+    }
+
+    public Port port;
+    public Device device;
+    public Enum<Status> status;
+    public boolean hasSubscriber;
+    public SubscriberAndDeviceInformation subscriberAndDeviceInformation;
+
+    /**
+     * Creates the class with the proper information.
+     *
+     * @param device        the device of the subscriber
+     * @param port          the port
+     * @param status        the status for this specific subscriber
+     * @param hasSubscriber is the subscriber present
+     * @param si            the information about the tags/dhcp and other info.
+     */
+    public DiscoveredSubscriber(Device device, Port port, Status status, boolean hasSubscriber,
+                                SubscriberAndDeviceInformation si) {
+        this.device = device;
+        this.port = port;
+        this.status = status;
+        this.hasSubscriber = hasSubscriber;
+        subscriberAndDeviceInformation = si;
+    }
+
+    /**
+     * Returns the port name for the subscriber.
+     *
+     * @return the port name.
+     */
+    public String portName() {
+        return OltUtils.getPortName(port);
+    }
+
+    @Override
+    public String toString() {
+
+        return String.format("%s (status: %s, provisionSubscriber: %s)",
+                portWithName(this.port),
+                this.status, this.hasSubscriber
+        );
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        DiscoveredSubscriber that = (DiscoveredSubscriber) o;
+        return hasSubscriber == that.hasSubscriber &&
+                port.equals(that.port) &&
+                device.equals(that.device) &&
+                status.equals(that.status);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(port, device, status, hasSubscriber, subscriberAndDeviceInformation);
+    }
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/MeterData.java b/impl/src/main/java/org/opencord/olt/impl/MeterData.java
new file mode 100644
index 0000000..208383d
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/MeterData.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.onosproject.net.meter.MeterCellId;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterState;
+
+import java.util.Objects;
+
+/**
+ * Class containing Meter Data.
+ */
+public class MeterData {
+    private MeterCellId meterCellId;
+    private MeterState meterStatus;
+    private String bandwidthProfileName;
+
+    public MeterData(MeterCellId meterCellId, MeterState meterStatus, String bandwidthProfile) {
+        this.meterCellId = meterCellId;
+        this.meterStatus = meterStatus;
+        this.bandwidthProfileName = bandwidthProfile;
+    }
+
+    public void setMeterCellId(MeterCellId meterCellId) {
+        this.meterCellId = meterCellId;
+    }
+
+    public void setMeterStatus(MeterState meterStatus) {
+        this.meterStatus = meterStatus;
+    }
+
+    public MeterId getMeterId() {
+        return (MeterId) meterCellId;
+    }
+
+    public MeterCellId getMeterCellId() {
+        return meterCellId;
+    }
+
+    public MeterState getMeterStatus() {
+        return meterStatus;
+    }
+
+    public String getBandwidthProfileName() {
+        return bandwidthProfileName;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        MeterData meterData = (MeterData) o;
+        return Objects.equals(meterCellId, meterData.meterCellId) &&
+                meterStatus == meterData.meterStatus &&
+                Objects.equals(bandwidthProfileName, meterData.bandwidthProfileName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(meterCellId, meterStatus, bandwidthProfileName);
+    }
+
+    @Override
+    public String toString() {
+        return "MeterData{" +
+                "meterCellId=" + meterCellId +
+                ", meterStatus=" + meterStatus +
+                ", bandwidthProfile='" + bandwidthProfileName + '\'' +
+                '}';
+    }
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/Olt.java b/impl/src/main/java/org/opencord/olt/impl/Olt.java
index 74c5811..747a0b4 100644
--- a/impl/src/main/java/org/opencord/olt/impl/Olt.java
+++ b/impl/src/main/java/org/opencord/olt/impl/Olt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,18 +15,11 @@
  */
 package org.opencord.olt.impl;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Sets;
-import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 import org.onlab.util.KryoNamespace;
 import org.onosproject.cfg.ComponentConfigService;
-import org.onosproject.cluster.ClusterEvent;
-import org.onosproject.cluster.ClusterEventListener;
 import org.onosproject.cluster.ClusterService;
-import org.onosproject.cluster.ControllerNode;
 import org.onosproject.cluster.LeadershipService;
-import org.onosproject.cluster.NodeId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.event.AbstractListenerManager;
@@ -35,36 +28,17 @@
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
 import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.DriverService;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flowobjective.FlowObjectiveService;
-import org.onosproject.net.flowobjective.ForwardingObjective;
-import org.onosproject.net.flowobjective.Objective;
-import org.onosproject.net.flowobjective.ObjectiveContext;
-import org.onosproject.net.flowobjective.ObjectiveError;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.meter.MeterId;
-import org.onosproject.store.primitives.DefaultConsistentMap;
 import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.ConsistentMultimap;
 import org.onosproject.store.service.Serializer;
 import org.onosproject.store.service.StorageService;
 import org.opencord.olt.AccessDeviceEvent;
 import org.opencord.olt.AccessDeviceListener;
-import org.opencord.olt.AccessDevicePort;
 import org.opencord.olt.AccessDeviceService;
-import org.opencord.olt.AccessSubscriberId;
-import org.opencord.olt.internalapi.AccessDeviceFlowService;
-import org.opencord.olt.internalapi.AccessDeviceMeterService;
-import org.opencord.sadis.BandwidthProfileInformation;
 import org.opencord.sadis.BaseInformationService;
 import org.opencord.sadis.SadisService;
 import org.opencord.sadis.SubscriberAndDeviceInformation;
@@ -78,73 +52,60 @@
 import org.osgi.service.component.annotations.ReferenceCardinality;
 import org.osgi.service.component.annotations.ReferencePolicy;
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Dictionary;
+import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Properties;
 import java.util.Set;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Strings.isNullOrEmpty;
-import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static java.util.stream.Collectors.*;
 import static org.onlab.util.Tools.get;
 import static org.onlab.util.Tools.groupedThreads;
+import static org.opencord.olt.impl.OltUtils.getPortName;
+import static org.opencord.olt.impl.OltUtils.portWithName;
 import static org.opencord.olt.impl.OsgiPropertyConstants.*;
-import static org.slf4j.LoggerFactory.getLogger;
 
 /**
- * Provisions rules on access devices.
+ * OLT Application.
  */
 @Component(immediate = true,
         property = {
                 DEFAULT_BP_ID + ":String=" + DEFAULT_BP_ID_DEFAULT,
                 DEFAULT_MCAST_SERVICE_NAME + ":String=" + DEFAULT_MCAST_SERVICE_NAME_DEFAULT,
-                EAPOL_DELETE_RETRY_MAX_ATTEMPS + ":Integer=" +
-                        EAPOL_DELETE_RETRY_MAX_ATTEMPS_DEFAULT,
-                PROVISION_DELAY + ":Integer=" + PROVISION_DELAY_DEFAULT,
+                FLOW_PROCESSING_THREADS + ":Integer=" + FLOW_PROCESSING_THREADS_DEFAULT,
+                SUBSCRIBER_PROCESSING_THREADS + ":Integer=" + SUBSCRIBER_PROCESSING_THREADS_DEFAULT,
+                REQUEUE_DELAY + ":Integer=" + REQUEUE_DELAY_DEFAULT
         })
 public class Olt
         extends AbstractListenerManager<AccessDeviceEvent, AccessDeviceListener>
         implements AccessDeviceService {
-    private static final String SADIS_NOT_RUNNING = "Sadis is not running.";
-    private static final String APP_NAME = "org.opencord.olt";
-
-    private static final short EAPOL_DEFAULT_VLAN = 4091;
-    private static final String NO_UPLINK_PORT = "No uplink port found for OLT device {}";
-
-    public static final int HASH_WEIGHT = 10;
-    public static final long PENDING_SUBS_MAP_TIMEOUT_MILLIS = 30000L;
-
-    private final Logger log = getLogger(getClass());
-
-    private static final String NNI = "nni-";
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected FlowObjectiveService flowObjectiveService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected DeviceService deviceService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ComponentConfigService cfgService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected CoreService coreService;
+    protected MastershipService mastershipService;
 
-    //Dependency on driver service is to ensure correct startup order
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected DriverService driverService;
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected LeadershipService leadershipService;
 
     @Reference(cardinality = ReferenceCardinality.OPTIONAL,
             bind = "bindSadisService",
@@ -153,31 +114,23 @@
     protected volatile SadisService sadisService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected AccessDeviceFlowService oltFlowService;
+    protected OltDeviceServiceInterface oltDeviceService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected AccessDeviceMeterService oltMeterService;
+    protected OltFlowServiceInterface oltFlowService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected OltMeterServiceInterface oltMeterService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected StorageService storageService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected ClusterService clusterService;
+    protected CoreService coreService;
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected MastershipService mastershipService;
+    protected ApplicationId appId;
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected LeadershipService leadershipService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected FlowRuleService flowRuleService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected ComponentConfigService componentConfigService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected HostService hostService;
+    private static final String ONOS_OLT_SERVICE = "onos/olt-service";
 
     /**
      * Default bandwidth profile id that is used for authentication trap flows.
@@ -190,456 +143,322 @@
     protected String multicastServiceName = DEFAULT_MCAST_SERVICE_NAME_DEFAULT;
 
     /**
-     * Default amounts of eapol retry.
+     * Number of threads used to process flows.
      **/
-    protected int eapolDeleteRetryMaxAttempts = EAPOL_DELETE_RETRY_MAX_ATTEMPS_DEFAULT;
+    protected int flowProcessingThreads = FLOW_PROCESSING_THREADS_DEFAULT;
 
     /**
-     * Delay between EAPOL removal and data plane flows provisioning.
+     * Number of threads used to process flows.
+     **/
+    protected int subscriberProcessingThreads = SUBSCRIBER_PROCESSING_THREADS_DEFAULT;
+
+    /**
+     * Delay in ms to put an event back in the queue, used to avoid retrying things to often if conditions are not met.
+     **/
+    protected int requeueDelay = REQUEUE_DELAY_DEFAULT;
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * A queue to asynchronously process events.
      */
-    protected int provisionDelay = PROVISION_DELAY_DEFAULT;
-
-    private final DeviceListener deviceListener = new InternalDeviceListener();
-    private final ClusterEventListener clusterListener = new InternalClusterListener();
-    private final HostListener hostListener = new InternalHostListener();
-
-    private ConsistentHasher hasher;
+    protected Map<ConnectPoint, LinkedBlockingQueue<DiscoveredSubscriber>> eventsQueues;
 
     protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
-    private BaseInformationService<BandwidthProfileInformation> bpService;
 
-    private ExecutorService oltInstallers = Executors.newFixedThreadPool(4,
-                                                                         groupedThreads("onos/olt-service",
-                                                                                        "olt-installer-%d"));
+    /**
+     * Listener for OLT devices events.
+     */
+    protected OltDeviceListener deviceListener = new OltDeviceListener();
+    protected ScheduledExecutorService discoveredSubscriberExecutor =
+            Executors.newSingleThreadScheduledExecutor(groupedThreads("onos/olt",
+                    "discovered-cp-%d", log));
 
-    protected ExecutorService eventExecutor;
-    protected ExecutorService hostEventExecutor;
-    protected ExecutorService retryExecutor;
-    protected ScheduledExecutorService provisionExecutor;
+    protected ScheduledExecutorService queueExecutor =
+            Executors.newSingleThreadScheduledExecutor(groupedThreads("onos/olt",
+                    "discovered-cp-restore-%d", log));
 
-    private ConsistentMultimap<ConnectPoint, UniTagInformation> programmedSubs;
-    private ConsistentMultimap<ConnectPoint, UniTagInformation> failedSubs;
+    /**
+     * Executor used to defer flow provisioning to a different thread pool.
+     */
+    protected ExecutorService flowsExecutor;
 
-    protected Map<DeviceId, BlockingQueue<SubscriberFlowInfo>> pendingSubscribersForDevice;
-    private ConsistentMultimap<ConnectPoint, SubscriberFlowInfo> waitingMacSubscribers;
+    /**
+     * Executor used to defer subscriber handling from API call to a different thread pool.
+     */
+    protected ExecutorService subscriberExecutor;
+
+    private static final String APP_NAME = "org.opencord.olt";
+
+    private final ReentrantReadWriteLock queueLock = new ReentrantReadWriteLock();
+    private final Lock queueWriteLock = queueLock.writeLock();
+    private final Lock queueReadLock = queueLock.readLock();
 
     @Activate
-    public void activate(ComponentContext context) {
-        eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/olt",
-                                                                        "events-%d", log));
-        hostEventExecutor = Executors.newFixedThreadPool(8, groupedThreads("onos/olt", "mac-events-%d", log));
-        retryExecutor = Executors.newCachedThreadPool();
-        provisionExecutor = Executors.newSingleThreadScheduledExecutor(groupedThreads("onos/olt",
-                "provision-%d", log));
+    protected void activate(ComponentContext context) {
+        cfgService.registerProperties(getClass());
 
         modified(context);
-        ApplicationId appId = coreService.registerApplication(APP_NAME);
-        componentConfigService.registerProperties(getClass());
 
+        appId = coreService.registerApplication(APP_NAME);
         KryoNamespace serializer = KryoNamespace.newBuilder()
                 .register(KryoNamespaces.API)
+                .register(ConnectPoint.class)
+                .register(DiscoveredSubscriber.class)
+                .register(DiscoveredSubscriber.Status.class)
+                .register(SubscriberAndDeviceInformation.class)
                 .register(UniTagInformation.class)
-                .register(SubscriberFlowInfo.class)
-                .register(AccessDevicePort.class)
-                .register(AccessDevicePort.Type.class)
                 .register(LinkedBlockingQueue.class)
                 .build();
 
-        programmedSubs = storageService.<ConnectPoint, UniTagInformation>consistentMultimapBuilder()
-                .withName("volt-programmed-subs")
+        eventsQueues = storageService.<ConnectPoint, LinkedBlockingQueue<DiscoveredSubscriber>>consistentMapBuilder()
+                .withName("volt-subscriber-queues")
+                .withApplicationId(appId)
                 .withSerializer(Serializer.using(serializer))
-                .withApplicationId(appId)
-                .build();
-
-        failedSubs = storageService.<ConnectPoint, UniTagInformation>consistentMultimapBuilder()
-                .withName("volt-failed-subs")
-                .withSerializer(Serializer.using(serializer))
-                .withApplicationId(appId)
-                .build();
-
-        KryoNamespace macSerializer = KryoNamespace.newBuilder()
-                .register(KryoNamespaces.API)
-                .register(SubscriberFlowInfo.class)
-                .register(AccessDevicePort.class)
-                .register(AccessDevicePort.Type.class)
-                .register(UniTagInformation.class)
-                .build();
-
-        waitingMacSubscribers = storageService.<ConnectPoint, SubscriberFlowInfo>consistentMultimapBuilder()
-                .withName("volt-waiting-mac-subs")
-                .withSerializer(Serializer.using(macSerializer))
-                .withApplicationId(appId)
-                .build();
-        //TODO possibly use consistent multimap with compute on key and element to avoid
-        // lock on all objects of the map, while instead obtaining and releasing the lock
-        // on a per subscriber basis.
-        pendingSubscribersForDevice = new DefaultConsistentMap<>(
-                storageService.<DeviceId, BlockingQueue<SubscriberFlowInfo>>consistentMapBuilder()
-                .withName("volt-pending-subs")
-                .withSerializer(Serializer.using(serializer))
-                .withApplicationId(appId)
-                .buildAsyncMap(), PENDING_SUBS_MAP_TIMEOUT_MILLIS).asJavaMap();
-        eventDispatcher.addSink(AccessDeviceEvent.class, listenerRegistry);
-
-        if (sadisService != null) {
-            subsService = sadisService.getSubscriberInfoService();
-            bpService = sadisService.getBandwidthProfileService();
-        } else {
-            log.warn(SADIS_NOT_RUNNING);
-        }
-
-        List<NodeId> readyNodes = clusterService.getNodes().stream()
-                .filter(c -> clusterService.getState(c.id()) == ControllerNode.State.READY)
-                .map(ControllerNode::id)
-                .collect(toList());
-        hasher = new ConsistentHasher(readyNodes, HASH_WEIGHT);
-        clusterService.addListener(clusterListener);
-
-        // look for all provisioned devices in Sadis and create EAPOL flows for the
-        // UNI ports
-        Iterable<Device> devices = deviceService.getDevices();
-        for (Device d : devices) {
-            if (isLocalLeader(d.id())) {
-                checkAndCreateDeviceFlows(d);
-            }
-        }
+                .build().asJavaMap();
 
         deviceService.addListener(deviceListener);
-        hostService.addListener(hostListener);
-        log.info("Started with Application ID {}", appId.id());
+
+        discoveredSubscriberExecutor.execute(this::processDiscoveredSubscribers);
+        eventDispatcher.addSink(AccessDeviceEvent.class, listenerRegistry);
+        log.info("Started");
+
+        deviceListener.handleExistingPorts();
     }
 
     @Deactivate
-    public void deactivate() {
-        componentConfigService.unregisterProperties(getClass(), false);
-        clusterService.removeListener(clusterListener);
-        deviceService.removeListener(deviceListener);
-        hostService.removeListener(hostListener);
-        eventDispatcher.removeSink(AccessDeviceEvent.class);
-        eventExecutor.shutdown();
-        hostEventExecutor.shutdown();
-        retryExecutor.shutdown();
-        provisionExecutor.shutdown();
+    protected void deactivate(ComponentContext context) {
+        cfgService.unregisterProperties(getClass(), false);
+        discoveredSubscriberExecutor.shutdown();
+        flowsExecutor.shutdown();
+        subscriberExecutor.shutdown();
+        deviceListener.deactivate();
         log.info("Stopped");
     }
 
     @Modified
     public void modified(ComponentContext context) {
         Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
-
-        try {
+        if (context != null) {
             String bpId = get(properties, DEFAULT_BP_ID);
             defaultBpId = isNullOrEmpty(bpId) ? defaultBpId : bpId;
 
             String mcastSN = get(properties, DEFAULT_MCAST_SERVICE_NAME);
             multicastServiceName = isNullOrEmpty(mcastSN) ? multicastServiceName : mcastSN;
 
-            String eapolDeleteRetryNew = get(properties, EAPOL_DELETE_RETRY_MAX_ATTEMPS);
-            eapolDeleteRetryMaxAttempts = isNullOrEmpty(eapolDeleteRetryNew) ? EAPOL_DELETE_RETRY_MAX_ATTEMPS_DEFAULT :
-                    Integer.parseInt(eapolDeleteRetryNew.trim());
+            String flowThreads = get(properties, FLOW_PROCESSING_THREADS);
+            int oldFlowProcessingThreads = flowProcessingThreads;
+            flowProcessingThreads = isNullOrEmpty(flowThreads) ?
+                    oldFlowProcessingThreads : Integer.parseInt(flowThreads.trim());
 
-            log.debug("OLT properties: DefaultBpId: {}, MulticastServiceName: {}, EapolDeleteRetryMaxAttempts: {}",
-                      defaultBpId, multicastServiceName, eapolDeleteRetryMaxAttempts);
+            if (flowsExecutor == null || oldFlowProcessingThreads != flowProcessingThreads) {
+                if (flowsExecutor != null) {
+                    flowsExecutor.shutdown();
+                }
+                flowsExecutor = Executors.newFixedThreadPool(flowProcessingThreads,
+                        groupedThreads(ONOS_OLT_SERVICE,
+                                "flows-installer-%d"));
+            }
 
-        } catch (Exception e) {
-            log.error("Error while modifying the properties", e);
-            defaultBpId = DEFAULT_BP_ID_DEFAULT;
-            multicastServiceName = DEFAULT_MCAST_SERVICE_NAME_DEFAULT;
+            String subscriberThreads = get(properties, SUBSCRIBER_PROCESSING_THREADS);
+            int oldSubscriberProcessingThreads = subscriberProcessingThreads;
+            subscriberProcessingThreads = isNullOrEmpty(subscriberThreads) ?
+                    oldSubscriberProcessingThreads : Integer.parseInt(subscriberThreads.trim());
+
+            if (subscriberExecutor == null || oldSubscriberProcessingThreads != subscriberProcessingThreads) {
+                if (subscriberExecutor != null) {
+                    subscriberExecutor.shutdown();
+                }
+                subscriberExecutor = Executors.newFixedThreadPool(subscriberProcessingThreads,
+                        groupedThreads(ONOS_OLT_SERVICE,
+                                "subscriber-installer-%d"));
+            }
+
+            String queueDelay = get(properties, REQUEUE_DELAY);
+            requeueDelay = isNullOrEmpty(queueDelay) ?
+                    REQUEUE_DELAY_DEFAULT : Integer.parseInt(queueDelay.trim());
         }
+        log.info("Modified. Values = {}: {}, {}: {}, " +
+                        "{}:{}, {}:{}, {}:{}",
+                DEFAULT_BP_ID, defaultBpId,
+                DEFAULT_MCAST_SERVICE_NAME, multicastServiceName,
+                FLOW_PROCESSING_THREADS, flowProcessingThreads,
+                SUBSCRIBER_PROCESSING_THREADS, subscriberProcessingThreads,
+                REQUEUE_DELAY, requeueDelay);
     }
 
-    protected void bindSadisService(SadisService service) {
-        sadisService = service;
-        bpService = sadisService.getBandwidthProfileService();
-        subsService = sadisService.getSubscriberInfoService();
-        log.info("Sadis-service binds to onos.");
-    }
-
-    protected void unbindSadisService(SadisService service) {
-        sadisService = null;
-        bpService = null;
-        subsService = null;
-        log.info("Sadis-service unbinds from onos.");
-    }
 
     @Override
-    public boolean provisionSubscriber(ConnectPoint connectPoint) {
-        log.info("Call to provision subscriber at {}", connectPoint);
-        DeviceId deviceId = connectPoint.deviceId();
-        Port subscriberPortOnos = deviceService.getPort(deviceId, connectPoint.port());
-        checkNotNull(subscriberPortOnos, "Invalid connect point:" + connectPoint);
-        AccessDevicePort subscriberPort = new AccessDevicePort(subscriberPortOnos, AccessDevicePort.Type.UNI);
+    public boolean provisionSubscriber(ConnectPoint cp) {
+        subscriberExecutor.submit(() -> {
+            Device device = deviceService.getDevice(cp.deviceId());
+            Port port = deviceService.getPort(device.id(), cp.port());
+            AccessDevicePort accessDevicePort = new AccessDevicePort(port);
 
-        if (isSubscriberInstalled(connectPoint)) {
-            log.warn("Subscriber at {} already provisioned or in the process .."
-                    + " not taking any more action", connectPoint);
-            return true;
-        }
-
-        // Find the subscriber config at this connect point
-        SubscriberAndDeviceInformation sub = getSubscriber(connectPoint);
-        if (sub == null) {
-            log.warn("No subscriber found for {}", connectPoint);
-            return false;
-        }
-
-        // Get the uplink port
-        AccessDevicePort uplinkPort = getUplinkPort(deviceService.getDevice(deviceId));
-        if (uplinkPort == null) {
-            log.warn(NO_UPLINK_PORT, deviceId);
-            return false;
-        }
-
-        // delete Eapol authentication flow with default bandwidth
-        // wait until Eapol rule with defaultBpId is removed to install subscriber-based rules
-        // retry deletion if it fails/times-out
-        retryExecutor.execute(new DeleteEapolInstallSub(subscriberPort, uplinkPort, sub, 1));
-        return true;
-    }
-
-    // returns true if subscriber is programmed or in the process of being programmed
-    private boolean isSubscriberInstalled(ConnectPoint connectPoint) {
-        Collection<? extends UniTagInformation> uniTagInformationSet =
-                programmedSubs.get(connectPoint).value();
-        if (!uniTagInformationSet.isEmpty()) {
-            return true;
-        }
-        //Check if the subscriber is already getting provisioned
-        // so we do not provision twice
-        AtomicBoolean isPending = new AtomicBoolean(false);
-        pendingSubscribersForDevice.computeIfPresent(connectPoint.deviceId(), (id, infos) -> {
-            for (SubscriberFlowInfo fi : infos) {
-                if (fi.getUniPort().equals(connectPoint.port())) {
-                    log.debug("Subscriber is already pending, {}", fi);
-                    isPending.set(true);
-                    break;
-                }
+            if (oltDeviceService.isNniPort(device, port.number())) {
+                log.warn("will not provision a subscriber on the NNI {}", accessDevicePort);
+                return false;
             }
-            return infos;
+
+            log.info("Provisioning subscriber on {}", accessDevicePort);
+
+            if (oltFlowService.isSubscriberServiceProvisioned(accessDevicePort)) {
+                log.error("Subscriber on {} is already provisioned", accessDevicePort);
+                return false;
+            }
+
+            SubscriberAndDeviceInformation si = subsService.get(getPortName(port));
+            if (si == null) {
+                log.error("Subscriber information not found in sadis for port {}", accessDevicePort);
+                return false;
+            }
+            DiscoveredSubscriber sub = new DiscoveredSubscriber(device, port,
+                    DiscoveredSubscriber.Status.ADDED, true, si);
+
+            // NOTE we need to keep a list of the subscribers that are provisioned on a port,
+            // regardless of the flow status
+            si.uniTagList().forEach(uti -> {
+                ServiceKey sk = new ServiceKey(accessDevicePort, uti);
+                oltFlowService.updateProvisionedSubscriberStatus(sk, true);
+            });
+
+            addSubscriberToQueue(sub);
+            return true;
         });
-
-        return isPending.get();
-    }
-
-    private class DeleteEapolInstallSub implements Runnable {
-        AccessDevicePort subscriberPort;
-        AccessDevicePort uplinkPort;
-        SubscriberAndDeviceInformation sub;
-        private int attemptNumber;
-
-        DeleteEapolInstallSub(AccessDevicePort subscriberPort, AccessDevicePort uplinkPort,
-                              SubscriberAndDeviceInformation sub,
-                              int attemptNumber) {
-            this.subscriberPort = subscriberPort;
-            this.uplinkPort = uplinkPort;
-            this.sub = sub;
-            this.attemptNumber = attemptNumber;
-        }
-
-        @Override
-        public void run() {
-            CompletableFuture<ObjectiveError> filterFuture = new CompletableFuture<>();
-            oltFlowService.processEapolFilteringObjectives(subscriberPort,
-                                                     defaultBpId, Optional.empty(), filterFuture,
-                                                     VlanId.vlanId(EAPOL_DEFAULT_VLAN),
-                                                     false);
-            filterFuture.thenAcceptAsync(filterStatus -> {
-                if (filterStatus == null) {
-                    log.info("Default eapol flow deleted in attempt {} of {}"
-                            + "... provisioning subscriber flows on {}",
-                            attemptNumber, eapolDeleteRetryMaxAttempts, subscriberPort);
-
-                    // FIXME this is needed to prevent that default EAPOL flow removal and
-                    // data plane flows install are received by the device at the same time
-                    provisionExecutor.schedule(
-                            () -> provisionUniTagList(subscriberPort, uplinkPort, sub),
-                            provisionDelay, TimeUnit.MILLISECONDS);
-                } else {
-                    if (attemptNumber <= eapolDeleteRetryMaxAttempts) {
-                        log.warn("The filtering future failed {} for subscriber on {}"
-                                + "... retrying {} of {} attempts",
-                                 filterStatus, subscriberPort, attemptNumber, eapolDeleteRetryMaxAttempts);
-                        retryExecutor.execute(
-                                         new DeleteEapolInstallSub(subscriberPort, uplinkPort, sub,
-                                                                   attemptNumber + 1));
-                    } else {
-                        log.error("The filtering future failed {} for subscriber on {}"
-                                + "after {} attempts. Subscriber provisioning failed",
-                                  filterStatus, subscriberPort, eapolDeleteRetryMaxAttempts);
-                        sub.uniTagList().forEach(ut ->
-                                failedSubs.put(
-                                        new ConnectPoint(subscriberPort.deviceId(), subscriberPort.number()), ut));
-                    }
-                }
-            });
-        }
-
-    }
-
-    @Override
-    public boolean removeSubscriber(ConnectPoint connectPoint) {
-        Port subscriberPort = deviceService.getPort(connectPoint);
-        if (subscriberPort == null) {
-            log.error("Subscriber port not found at: {}", connectPoint);
-            return false;
-        }
-        return removeSubscriber(new AccessDevicePort(subscriberPort, AccessDevicePort.Type.UNI));
-    }
-
-    private boolean removeSubscriber(AccessDevicePort subscriberPort) {
-        log.info("Call to un-provision subscriber at {}", subscriberPort);
-        //TODO we need to check if the subscriber is pending
-        // Get the subscriber connected to this port from the local cache
-        // If we don't know about the subscriber there's no need to remove it
-        DeviceId deviceId = subscriberPort.deviceId();
-
-        ConnectPoint connectPoint = new ConnectPoint(deviceId, subscriberPort.number());
-        Collection<? extends UniTagInformation> uniTagInformationSet = programmedSubs.get(connectPoint).value();
-        if (uniTagInformationSet == null || uniTagInformationSet.isEmpty()) {
-            log.warn("Subscriber on connectionPoint {} was not previously programmed, " +
-                             "no need to remove it", connectPoint);
-            return true;
-        }
-
-        // Get the uplink port
-        AccessDevicePort uplinkPort = getUplinkPort(deviceService.getDevice(deviceId));
-        if (uplinkPort == null) {
-            log.warn(NO_UPLINK_PORT, deviceId);
-            return false;
-        }
-
-        for (UniTagInformation uniTag : uniTagInformationSet) {
-
-            if (multicastServiceName.equals(uniTag.getServiceName())) {
-                continue;
-            }
-
-            unprovisionVlans(uplinkPort, subscriberPort, uniTag);
-
-            // remove eapol with subscriber bandwidth profile
-            Optional<String> upstreamOltBw = uniTag.getUpstreamOltBandwidthProfile() == null ?
-                    Optional.empty() : Optional.of(uniTag.getUpstreamOltBandwidthProfile());
-            oltFlowService.processEapolFilteringObjectives(subscriberPort,
-                                                           uniTag.getUpstreamBandwidthProfile(),
-                                                           upstreamOltBw,
-                                                           null, uniTag.getPonCTag(), false);
-
-            if (subscriberPort.port() != null && subscriberPort.isEnabled()) {
-                // reinstall eapol with default bandwidth profile
-                oltFlowService.processEapolFilteringObjectives(subscriberPort, defaultBpId, Optional.empty(),
-                        null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
-            } else {
-                log.debug("Port {} is no longer enabled or it's unavailable. Not "
-                                  + "reprogramming default eapol flow", connectPoint);
-            }
-        }
+        //NOTE this only means we have taken the request in, nothing more.
         return true;
     }
 
-
     @Override
-    public boolean provisionSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag,
-                                       Optional<VlanId> cTag, Optional<Integer> tpId) {
+    public boolean removeSubscriber(ConnectPoint cp) {
+        subscriberExecutor.submit(() -> {
+            Device device = deviceService.getDevice(DeviceId.deviceId(cp.deviceId().toString()));
+            Port port = deviceService.getPort(device.id(), cp.port());
+            AccessDevicePort accessDevicePort = new AccessDevicePort(port);
 
-        log.info("Provisioning subscriber using subscriberId {}, sTag {}, cTag {}, tpId {}",
-                subscriberId, sTag, cTag, tpId);
-
-        // Check if we can find the connect point to which this subscriber is connected
-        ConnectPoint cp = findSubscriberConnectPoint(subscriberId.toString());
-        if (cp == null) {
-            log.warn("ConnectPoint for {} not found", subscriberId);
-            return false;
-        }
-        AccessDevicePort subscriberPort = new AccessDevicePort(deviceService.getPort(cp), AccessDevicePort.Type.UNI);
-
-        if (!sTag.isPresent() && !cTag.isPresent()) {
-            return provisionSubscriber(cp);
-        } else if (sTag.isPresent() && cTag.isPresent() && tpId.isPresent()) {
-            AccessDevicePort uplinkPort = getUplinkPort(deviceService.getDevice(cp.deviceId()));
-            if (uplinkPort == null) {
-                log.warn(NO_UPLINK_PORT, cp.deviceId());
+            if (oltDeviceService.isNniPort(device, port.number())) {
+                log.warn("will not un-provision a subscriber on the NNI {}",
+                        accessDevicePort);
                 return false;
             }
 
-            //delete Eapol authentication flow with default bandwidth
-            //wait until Eapol rule with defaultBpId is removed to install subscriber-based rules
-            //install subscriber flows
-            CompletableFuture<ObjectiveError> filterFuture = new CompletableFuture<>();
-            oltFlowService.processEapolFilteringObjectives(subscriberPort, defaultBpId, Optional.empty(),
-                    filterFuture, VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
-            filterFuture.thenAcceptAsync(filterStatus -> {
-                if (filterStatus == null) {
-                    provisionUniTagInformation(uplinkPort, subscriberPort, cTag.get(), sTag.get(), tpId.get());
-                }
+            log.info("Un-provisioning subscriber on {}", accessDevicePort);
+
+            if (!oltFlowService.isSubscriberServiceProvisioned(accessDevicePort)) {
+                log.error("Subscriber on {} is not provisioned", accessDevicePort);
+                return false;
+            }
+
+            SubscriberAndDeviceInformation si = subsService.get(getPortName(port));
+            if (si == null) {
+                log.error("Subscriber information not found in sadis for port {}",
+                        accessDevicePort);
+                // NOTE that we are returning true so that the subscriber is removed from the queue
+                // and we can move on provisioning others
+                return false;
+            }
+            DiscoveredSubscriber sub = new DiscoveredSubscriber(device, port,
+                    DiscoveredSubscriber.Status.REMOVED, true, si);
+
+            // NOTE we need to keep a list of the subscribers that are provisioned on a port,
+            // regardless of the flow status
+            si.uniTagList().forEach(uti -> {
+                ServiceKey sk = new ServiceKey(accessDevicePort, uti);
+                oltFlowService.updateProvisionedSubscriberStatus(sk, false);
             });
+
+            addSubscriberToQueue(sub);
             return true;
-        } else {
-            log.warn("Provisioning failed for subscriber: {}", subscriberId);
+        });
+        //NOTE this only means we have taken the request in, nothing more.
+        return true;
+    }
+
+    @Override
+    public boolean provisionSubscriber(ConnectPoint cp, VlanId cTag, VlanId sTag, Integer tpId) {
+        log.debug("Provisioning subscriber on {}, with cTag {}, stag {}, tpId {}",
+                cp, cTag, sTag, tpId);
+        Device device = deviceService.getDevice(cp.deviceId());
+        Port port = deviceService.getPort(device.id(), cp.port());
+        AccessDevicePort accessDevicePort = new AccessDevicePort(port);
+
+        if (oltDeviceService.isNniPort(device, port.number())) {
+            log.warn("will not provision a subscriber on the NNI {}", accessDevicePort);
             return false;
         }
-    }
 
-    @Override
-    public boolean removeSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag,
-                                    Optional<VlanId> cTag, Optional<Integer> tpId) {
-        // Check if we can find the connect point to which this subscriber is connected
-        ConnectPoint cp = findSubscriberConnectPoint(subscriberId.toString());
-        if (cp == null) {
-            log.warn("ConnectPoint for {} not found", subscriberId);
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        UniTagInformation specificService = getUniTagInformation(getPortName(port), cTag, sTag, tpId);
+        if (specificService == null) {
+            log.error("Can't find Information for subscriber on {}, with cTag {}, " +
+                    "stag {}, tpId {}", cp, cTag, sTag, tpId);
             return false;
         }
-        AccessDevicePort subscriberPort = new AccessDevicePort(deviceService.getPort(cp), AccessDevicePort.Type.UNI);
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        uniTagInformationList.add(specificService);
+        si.setUniTagList(uniTagInformationList);
+        DiscoveredSubscriber sub = new DiscoveredSubscriber(device, port,
+                DiscoveredSubscriber.Status.ADDED, true, si);
 
-        if (!sTag.isPresent() && !cTag.isPresent()) {
-            return removeSubscriber(cp);
-        } else if (sTag.isPresent() && cTag.isPresent() && tpId.isPresent()) {
-            // Get the uplink port
-            AccessDevicePort uplinkPort = getUplinkPort(deviceService.getDevice(cp.deviceId()));
-            if (uplinkPort == null) {
-                log.warn(NO_UPLINK_PORT, cp.deviceId());
-                return false;
-            }
-
-            Optional<UniTagInformation> tagInfo = getUniTagInformation(subscriberPort, cTag.get(),
-                    sTag.get(), tpId.get());
-            if (!tagInfo.isPresent()) {
-                log.warn("UniTagInformation does not exist for {}, cTag {}, sTag {}, tpId {}",
-                        subscriberPort, cTag, sTag, tpId);
-                return false;
-            }
-
-            unprovisionVlans(uplinkPort, subscriberPort, tagInfo.get());
-            return true;
-        } else {
-            log.warn("Removing subscriber is not possible - please check the provided information" +
-                             "for the subscriber: {}", subscriberId);
+        // NOTE we need to keep a list of the subscribers that are provisioned on a port,
+        // regardless of the flow status
+        ServiceKey sk = new ServiceKey(accessDevicePort, specificService);
+        if (oltFlowService.isSubscriberServiceProvisioned(sk)) {
+            log.error("Subscriber on {} is already provisioned", sk);
             return false;
         }
+        oltFlowService.updateProvisionedSubscriberStatus(sk, true);
+
+        addSubscriberToQueue(sub);
+        return true;
     }
 
     @Override
-    public ImmutableMap<ConnectPoint, Set<UniTagInformation>> getProgSubs() {
-        return programmedSubs.stream()
-                .collect(collectingAndThen(
-                        groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toSet())),
-                        ImmutableMap::copyOf));
+    public boolean removeSubscriber(ConnectPoint cp, VlanId cTag, VlanId sTag, Integer tpId) {
+        log.debug("Un-provisioning subscriber on {} with cTag {}, stag {}, tpId {}",
+                cp, cTag, sTag, tpId);
+        Device device = deviceService.getDevice(cp.deviceId());
+        Port port = deviceService.getPort(device.id(), cp.port());
+        AccessDevicePort accessDevicePort = new AccessDevicePort(port);
+
+        if (oltDeviceService.isNniPort(device, port.number())) {
+            log.warn("will not un-provision a subscriber on the NNI {}",
+                    accessDevicePort);
+            return false;
+        }
+
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        UniTagInformation specificService = getUniTagInformation(getPortName(port), cTag, sTag, tpId);
+        if (specificService == null) {
+            log.error("Can't find Information for subscriber on {}, with cTag {}, " +
+                    "stag {}, tpId {}", cp, cTag, sTag, tpId);
+            return false;
+        }
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        uniTagInformationList.add(specificService);
+        si.setUniTagList(uniTagInformationList);
+        DiscoveredSubscriber sub = new DiscoveredSubscriber(device, port,
+                DiscoveredSubscriber.Status.ADDED, true, si);
+
+        // NOTE we need to keep a list of the subscribers that are provisioned on a port,
+        // regardless of the flow status
+        ServiceKey sk = new ServiceKey(accessDevicePort, specificService);
+        if (!oltFlowService.isSubscriberServiceProvisioned(sk)) {
+            log.error("Subscriber on {} is not provisioned", sk);
+            return false;
+        }
+        oltFlowService.updateProvisionedSubscriberStatus(sk, false);
+
+        addSubscriberToQueue(sub);
+        return true;
     }
 
     @Override
-    public ImmutableMap<ConnectPoint, Set<UniTagInformation>> getFailedSubs() {
-        return failedSubs.stream()
-                .collect(collectingAndThen(
-                        groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toSet())),
-                        ImmutableMap::copyOf));
-    }
-
-    @Override
-    public List<DeviceId> fetchOlts() {
-        // look through all the devices and find the ones that are OLTs as per Sadis
+    public List<DeviceId> getConnectedOlts() {
         List<DeviceId> olts = new ArrayList<>();
         Iterable<Device> devices = deviceService.getDevices();
         for (Device d : devices) {
-            if (getOltInfo(d) != null) {
+            if (oltDeviceService.isOlt(d)) {
                 // So this is indeed an OLT device
                 olts.add(d.id());
             }
@@ -648,19 +467,20 @@
     }
 
     /**
-     * Finds the connect point to which a subscriber is connected.
+     * Finds the connect-point to which a subscriber is connected.
      *
      * @param id The id of the subscriber, this is the same ID as in Sadis
      * @return Subscribers ConnectPoint if found else null
      */
-    private ConnectPoint findSubscriberConnectPoint(String id) {
+    @Override
+    public ConnectPoint findSubscriberConnectPoint(String id) {
 
         Iterable<Device> devices = deviceService.getDevices();
         for (Device d : devices) {
             for (Port p : deviceService.getPorts(d.id())) {
                 log.trace("Comparing {} with {}", p.annotations().value(AnnotationKeys.PORT_NAME), id);
                 if (p.annotations().value(AnnotationKeys.PORT_NAME).equals(id)) {
-                    log.debug("Found on device {} port {}", d.id(), p.number());
+                    log.debug("Found on {}", portWithName(p));
                     return new ConnectPoint(d.id(), p.number());
                 }
             }
@@ -668,584 +488,96 @@
         return null;
     }
 
-    /**
-     * Gets the context of the bandwidth profile information for the given parameter.
-     *
-     * @param bandwidthProfile the bandwidth profile id
-     * @return the context of the bandwidth profile information
-     */
-    private BandwidthProfileInformation getBandwidthProfileInformation(String bandwidthProfile) {
-        if (bpService == null) {
-            log.warn(SADIS_NOT_RUNNING);
-            return null;
-        }
-        if (bandwidthProfile == null) {
-            return null;
-        }
-        return bpService.get(bandwidthProfile);
-    }
+    protected void processDiscoveredSubscribers() {
+        log.info("Started processDiscoveredSubscribers loop");
+        while (true) {
+            Set<ConnectPoint> discoveredCps;
+            try {
+                queueReadLock.lock();
+                discoveredCps = eventsQueues.keySet();
+            } catch (Exception e) {
+                log.error("Cannot read keys from queue map", e);
+                return;
+            } finally {
+                queueReadLock.unlock();
+            }
 
-    /**
-     * Removes subscriber vlan flows.
-     *
-     * @param uplink         uplink port of the OLT
-     * @param subscriberPort uni port
-     * @param uniTag         uni tag information
-     */
-    private void unprovisionVlans(AccessDevicePort uplink, AccessDevicePort subscriberPort, UniTagInformation uniTag) {
-        log.info("Unprovisioning vlans for {} at {}", uniTag, subscriberPort);
-        DeviceId deviceId = subscriberPort.deviceId();
+            discoveredCps.forEach(cp -> {
+                LinkedBlockingQueue<DiscoveredSubscriber> eventsQueue;
 
-        CompletableFuture<ObjectiveError> downFuture = new CompletableFuture<>();
-        CompletableFuture<ObjectiveError> upFuture = new CompletableFuture<>();
-
-        VlanId deviceVlan = uniTag.getPonSTag();
-        VlanId subscriberVlan = uniTag.getPonCTag();
-
-        MeterId upstreamMeterId = oltMeterService
-                .getMeterIdFromBpMapping(deviceId, uniTag.getUpstreamBandwidthProfile());
-        MeterId downstreamMeterId = oltMeterService
-                .getMeterIdFromBpMapping(deviceId, uniTag.getDownstreamBandwidthProfile());
-        MeterId upstreamOltMeterId = oltMeterService
-                .getMeterIdFromBpMapping(deviceId, uniTag.getUpstreamOltBandwidthProfile());
-        MeterId downstreamOltMeterId = oltMeterService
-                .getMeterIdFromBpMapping(deviceId, uniTag.getDownstreamOltBandwidthProfile());
-
-        Optional<SubscriberFlowInfo> waitingMacSubFlowInfo =
-                getAndRemoveWaitingMacSubFlowInfoForCTag(new ConnectPoint(deviceId, subscriberPort.number()),
-                        subscriberVlan);
-        if (waitingMacSubFlowInfo.isPresent()) {
-            // only dhcp objectives applied previously, so only dhcp uninstallation objective will be processed
-            log.debug("Waiting MAC service removed and dhcp uninstallation objective will be processed. " +
-                    "waitingMacSubFlowInfo:{}", waitingMacSubFlowInfo.get());
-            CompletableFuture<ObjectiveError> dhcpFuture = new CompletableFuture<>();
-            oltFlowService.processDhcpFilteringObjectives(subscriberPort,
-                    upstreamMeterId, upstreamOltMeterId, uniTag, false, true, Optional.of(dhcpFuture));
-            dhcpFuture.thenAcceptAsync(dhcpStatus -> {
-                AccessDeviceEvent.Type type;
-                if (dhcpStatus == null) {
-                    type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTERED;
-                    log.debug("Dhcp uninstallation objective was processed successfully for cTag {}, sTag {}, " +
-                                    "tpId {} and Device/Port:{}", uniTag.getPonCTag(), uniTag.getPonSTag(),
-                            uniTag.getTechnologyProfileId(), subscriberPort);
-                    updateProgrammedSubscriber(subscriberPort, uniTag, false);
-                } else {
-                    type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTRATION_FAILED;
-                    log.error("Dhcp uninstallation objective was failed for cTag {}, sTag {}, " +
-                                    "tpId {} and Device/Port:{} :{}", uniTag.getPonCTag(), uniTag.getPonSTag(),
-                            uniTag.getTechnologyProfileId(), subscriberPort, dhcpStatus);
+                try {
+                    queueReadLock.lock();
+                    eventsQueue = eventsQueues.get(cp);
+                } catch (Exception e) {
+                    log.error("Cannot get key from queue map", e);
+                    return;
+                } finally {
+                    queueReadLock.unlock();
                 }
-                post(new AccessDeviceEvent(type, deviceId, subscriberPort.port(),
-                        deviceVlan, subscriberVlan, uniTag.getTechnologyProfileId()));
-            });
-            return;
-        } else {
-            log.debug("There is no waiting MAC service for {} and subscriberVlan: {}", subscriberPort, subscriberVlan);
-        }
 
-        ForwardingObjective.Builder upFwd =
-                oltFlowService.createUpBuilder(uplink, subscriberPort, upstreamMeterId, upstreamOltMeterId, uniTag);
-
-        Optional<MacAddress> macAddress = getMacAddress(deviceId, subscriberPort, uniTag);
-        ForwardingObjective.Builder downFwd =
-                oltFlowService.createDownBuilder(uplink, subscriberPort, downstreamMeterId, downstreamOltMeterId,
-                        uniTag, macAddress);
-
-        oltFlowService.processIgmpFilteringObjectives(subscriberPort, upstreamMeterId, upstreamOltMeterId, uniTag,
-                false, true);
-        oltFlowService.processDhcpFilteringObjectives(subscriberPort,
-                upstreamMeterId, upstreamOltMeterId, uniTag, false, true, Optional.empty());
-        oltFlowService.processPPPoEDFilteringObjectives(subscriberPort, upstreamMeterId, upstreamOltMeterId, uniTag,
-                false, true);
-
-        flowObjectiveService.forward(deviceId, upFwd.remove(new ObjectiveContext() {
-            @Override
-            public void onSuccess(Objective objective) {
-                upFuture.complete(null);
-            }
-
-            @Override
-            public void onError(Objective objective, ObjectiveError error) {
-                upFuture.complete(error);
-            }
-        }));
-
-        flowObjectiveService.forward(deviceId, downFwd.remove(new ObjectiveContext() {
-            @Override
-            public void onSuccess(Objective objective) {
-                downFuture.complete(null);
-            }
-
-            @Override
-            public void onError(Objective objective, ObjectiveError error) {
-                downFuture.complete(error);
-            }
-        }));
-
-        upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
-            AccessDeviceEvent.Type type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTERED;
-            if (upStatus == null && downStatus == null) {
-                log.debug("Uni tag information is unregistered successfully for cTag {}, sTag {}, tpId {} on {}",
-                        uniTag.getPonCTag(), uniTag.getPonSTag(), uniTag.getTechnologyProfileId(), subscriberPort);
-                updateProgrammedSubscriber(subscriberPort, uniTag, false);
-            } else if (downStatus != null) {
-                log.error("Subscriber with vlan {} on {} failed downstream uninstallation: {}",
-                          subscriberVlan, subscriberPort, downStatus);
-                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTRATION_FAILED;
-            } else if (upStatus != null) {
-                log.error("Subscriber with vlan {} on {} failed upstream uninstallation: {}",
-                          subscriberVlan, subscriberPort, upStatus);
-                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTRATION_FAILED;
-            }
-            post(new AccessDeviceEvent(type, deviceId, subscriberPort.port(), deviceVlan, subscriberVlan,
-                                       uniTag.getTechnologyProfileId()));
-        }, oltInstallers);
-    }
-
-    private Optional<SubscriberFlowInfo> getAndRemoveWaitingMacSubFlowInfoForCTag(ConnectPoint cp, VlanId cTag) {
-        SubscriberFlowInfo returnSubFlowInfo = null;
-        Collection<? extends SubscriberFlowInfo> subFlowInfoSet = waitingMacSubscribers.get(cp).value();
-        for (SubscriberFlowInfo subFlowInfo : subFlowInfoSet) {
-            if (subFlowInfo.getTagInfo().getPonCTag().equals(cTag)) {
-                returnSubFlowInfo = subFlowInfo;
-                break;
-            }
-        }
-        if (returnSubFlowInfo != null) {
-            waitingMacSubscribers.remove(cp, returnSubFlowInfo);
-            return Optional.of(returnSubFlowInfo);
-        }
-        return Optional.empty();
-    }
-
-    /**
-     * Adds subscriber vlan flows, dhcp, eapol and igmp trap flows for the related uni port.
-     *
-     * @param subPort      the connection point of the subscriber
-     * @param uplinkPort   uplink port of the OLT (the nni port)
-     * @param sub          subscriber information that includes s, c tags, tech profile and bandwidth profile references
-     */
-    private void provisionUniTagList(AccessDevicePort subPort, AccessDevicePort uplinkPort,
-                                     SubscriberAndDeviceInformation sub) {
-
-        log.debug("Provisioning vlans for subscriber on {}", subPort);
-        if (log.isTraceEnabled()) {
-            log.trace("Subscriber informations {}", sub);
-        }
-
-        if (sub.uniTagList() == null || sub.uniTagList().isEmpty()) {
-            log.warn("Unitaglist doesn't exist for the subscriber {} on {}", sub.id(), subPort);
-            return;
-        }
-
-        for (UniTagInformation uniTag : sub.uniTagList()) {
-            handleSubscriberFlows(uplinkPort, subPort, uniTag);
-        }
-    }
-
-    /**
-     * Finds the uni tag information and provisions the found information.
-     * If the uni tag information is not found, returns
-     *
-     * @param uplinkPort     the nni port
-     * @param subscriberPort the uni port
-     * @param innerVlan      the pon c tag
-     * @param outerVlan      the pon s tag
-     * @param tpId           the technology profile id
-     */
-    private void provisionUniTagInformation(AccessDevicePort uplinkPort,
-                                            AccessDevicePort subscriberPort,
-                                            VlanId innerVlan,
-                                            VlanId outerVlan,
-                                            Integer tpId) {
-
-        Optional<UniTagInformation> gotTagInformation = getUniTagInformation(subscriberPort, innerVlan,
-                outerVlan, tpId);
-        if (!gotTagInformation.isPresent()) {
-            return;
-        }
-        UniTagInformation tagInformation = gotTagInformation.get();
-        handleSubscriberFlows(uplinkPort, subscriberPort, tagInformation);
-    }
-
-    private void updateProgrammedSubscriber(AccessDevicePort port, UniTagInformation tagInformation, boolean add) {
-        if (add) {
-            programmedSubs.put(new ConnectPoint(port.deviceId(), port.number()), tagInformation);
-        } else {
-            programmedSubs.remove(new ConnectPoint(port.deviceId(), port.number()), tagInformation);
-        }
-    }
-
-    /**
-     * Installs a uni tag information flow.
-     *
-     * @param uplinkPort     the nni port
-     * @param subscriberPort the uni port
-     * @param tagInfo        the uni tag information
-     */
-    private void handleSubscriberFlows(AccessDevicePort uplinkPort, AccessDevicePort subscriberPort,
-                                       UniTagInformation tagInfo) {
-        log.debug("Provisioning vlan-based flows for the uniTagInformation {} on {}", tagInfo, subscriberPort);
-        DeviceId deviceId = subscriberPort.deviceId();
-
-        if (multicastServiceName.equals(tagInfo.getServiceName())) {
-            // IGMP flows are taken care of along with VOD service
-            // Please note that for each service, Subscriber Registered event will be sent
-            post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTERED, deviceId,
-                    subscriberPort.port(), tagInfo.getPonSTag(), tagInfo.getPonCTag(),
-                    tagInfo.getTechnologyProfileId()));
-            return;
-        }
-
-        BandwidthProfileInformation upstreamBpInfo =
-                getBandwidthProfileInformation(tagInfo.getUpstreamBandwidthProfile());
-        BandwidthProfileInformation downstreamBpInfo =
-                getBandwidthProfileInformation(tagInfo.getDownstreamBandwidthProfile());
-        BandwidthProfileInformation upstreamOltBpInfo =
-                getBandwidthProfileInformation(tagInfo.getUpstreamOltBandwidthProfile());
-        BandwidthProfileInformation downstreamOltBpInfo =
-                getBandwidthProfileInformation(tagInfo.getDownstreamOltBandwidthProfile());
-        if (upstreamBpInfo == null) {
-            log.warn("No meter installed since no Upstream BW Profile definition found for "
-                             + "ctag {} stag {} tpId {} on {}",
-                     tagInfo.getPonCTag(), tagInfo.getPonSTag(), tagInfo.getTechnologyProfileId(), subscriberPort);
-            return;
-        }
-        if (downstreamBpInfo == null) {
-            log.warn("No meter installed since no Downstream BW Profile definition found for "
-                             + "ctag {} stag {} tpId {} on {}",
-                     tagInfo.getPonCTag(), tagInfo.getPonSTag(),
-                     tagInfo.getTechnologyProfileId(), subscriberPort);
-            return;
-        }
-        if ((upstreamOltBpInfo != null && downstreamOltBpInfo == null) ||
-                (upstreamOltBpInfo == null && downstreamOltBpInfo != null)) {
-            log.warn("No meter installed since only one olt BW Profile definition found for "
-                            + "ctag {} stag {} tpId {} and Device/port: {}:{}",
-                    tagInfo.getPonCTag(), tagInfo.getPonSTag(),
-                    tagInfo.getTechnologyProfileId(), deviceId,
-                    subscriberPort);
-            return;
-        }
-
-        MeterId upOltMeterId = null;
-        MeterId downOltMeterId = null;
-
-        // check for meterIds for the upstream and downstream bandwidth profiles
-        MeterId upMeterId = oltMeterService
-                .getMeterIdFromBpMapping(deviceId, upstreamBpInfo.id());
-        MeterId downMeterId = oltMeterService
-                .getMeterIdFromBpMapping(deviceId, downstreamBpInfo.id());
-
-        if (upstreamOltBpInfo != null) {
-            // Multi UNI service
-            upOltMeterId = oltMeterService
-                    .getMeterIdFromBpMapping(deviceId, upstreamOltBpInfo.id());
-            downOltMeterId = oltMeterService
-                    .getMeterIdFromBpMapping(deviceId, downstreamOltBpInfo.id());
-        } else {
-            // NOT Multi UNI service
-            log.debug("OLT bandwidth profiles fields are set to ONU bandwidth profiles");
-            upstreamOltBpInfo = upstreamBpInfo;
-            downstreamOltBpInfo = downstreamBpInfo;
-            upOltMeterId = upMeterId;
-            downOltMeterId = downMeterId;
-        }
-        SubscriberFlowInfo fi = new SubscriberFlowInfo(uplinkPort, subscriberPort,
-                                                       tagInfo, downMeterId, upMeterId, downOltMeterId, upOltMeterId,
-                                                       downstreamBpInfo.id(), upstreamBpInfo.id(),
-                                                       downstreamOltBpInfo.id(), upstreamOltBpInfo.id());
-
-        if (upMeterId != null && downMeterId != null && upOltMeterId != null && downOltMeterId != null) {
-            log.debug("Meters are existing for upstream {} and downstream {} on {}",
-                    upstreamBpInfo.id(), downstreamBpInfo.id(), subscriberPort);
-            handleSubFlowsWithMeters(fi);
-        } else {
-            log.debug("Adding {} on {} to pending subs", fi, subscriberPort);
-            // one or both meters are not ready. It's possible they are in the process of being
-            // created for other subscribers that share the same bandwidth profile.
-            pendingSubscribersForDevice.compute(deviceId, (id, queue) -> {
-                if (queue == null) {
-                    queue = new LinkedBlockingQueue<>();
-                }
-                queue.add(fi);
-                log.info("Added {} to pending subscribers on {}", fi, subscriberPort);
-                return queue;
-            });
-
-            List<BandwidthProfileInformation> bws = new ArrayList<>();
-            // queue up the meters to be created
-            if (upMeterId == null) {
-                log.debug("Missing meter for upstream {} on {}", upstreamBpInfo.id(), subscriberPort);
-                bws.add(upstreamBpInfo);
-            }
-            if (downMeterId == null) {
-                log.debug("Missing meter for downstream {} on {}", downstreamBpInfo.id(), subscriberPort);
-                bws.add(downstreamBpInfo);
-            }
-            if (upOltMeterId == null) {
-                log.debug("Missing meter for upstreamOlt {} on {}", upstreamOltBpInfo.id(), subscriberPort);
-                bws.add(upstreamOltBpInfo);
-            }
-            if (downOltMeterId == null) {
-                log.debug("Missing meter for downstreamOlt {} on {}", downstreamOltBpInfo.id(), subscriberPort);
-                bws.add(downstreamOltBpInfo);
-            }
-            bws.stream().distinct().forEach(bw -> checkAndCreateDevMeter(deviceId, bw));
-        }
-    }
-
-    private void checkAndCreateDevMeter(DeviceId deviceId, BandwidthProfileInformation bwpInfo) {
-        log.debug("Checking and Creating Meter with {} on {}", bwpInfo, deviceId);
-        if (bwpInfo == null) {
-            log.error("Can't create meter. Bandwidth profile is null for device : {}", deviceId);
-            return;
-        }
-        //If false the meter is already being installed, skipping installation
-        if (!oltMeterService.checkAndAddPendingMeter(deviceId, bwpInfo)) {
-            log.debug("Meter is already being installed on {} for {}", deviceId, bwpInfo);
-            return;
-        }
-        createMeter(deviceId, bwpInfo);
-    }
-
-    private void createMeter(DeviceId deviceId, BandwidthProfileInformation bwpInfo) {
-        log.info("Creating Meter with {} on {}", bwpInfo, deviceId);
-        CompletableFuture<Object> meterFuture = new CompletableFuture<>();
-
-        MeterId meterId = oltMeterService.createMeter(deviceId, bwpInfo,
-                                                      meterFuture);
-
-        meterFuture.thenAcceptAsync(result -> {
-            log.info("Meter Future for {} has completed", meterId);
-            pendingSubscribersForDevice.compute(deviceId, (id, queue) -> {
-                // iterate through the subscribers on hold
-                if (queue != null && !queue.isEmpty()) {
-                    while (true) {
-                        //TODO this might return the reference and not the actual object so
-                        // it can be actually swapped underneath us.
-                        SubscriberFlowInfo fi = queue.peek();
-                        if (fi == null) {
-                            log.info("No more subscribers pending on {}", deviceId);
-                            queue = new LinkedBlockingQueue<>();
-                            break;
-                        }
-                        if (result == null) {
-                            // meter install sent to device
-                            log.debug("Meter {} installed for bw {} on {}", meterId, bwpInfo, deviceId);
-
-                            MeterId upMeterId = oltMeterService
-                                    .getMeterIdFromBpMapping(deviceId, fi.getUpBpInfo());
-                            MeterId downMeterId = oltMeterService
-                                    .getMeterIdFromBpMapping(deviceId, fi.getDownBpInfo());
-                            MeterId upOltMeterId = oltMeterService
-                                    .getMeterIdFromBpMapping(deviceId, fi.getUpOltBpInfo());
-                            MeterId downOltMeterId = oltMeterService
-                                    .getMeterIdFromBpMapping(deviceId, fi.getDownOltBpInfo());
-                            if (upMeterId != null && downMeterId != null &&
-                                    upOltMeterId != null && downOltMeterId != null) {
-                                log.debug("Provisioning subscriber after meter {} " +
-                                                  "installation and all meters are present " +
-                                                  "upstream {} , downstream {} , oltUpstream {} " +
-                                                  "and oltDownstream {} on {}",
-                                          meterId, upMeterId, downMeterId, upOltMeterId,
-                                          downOltMeterId, fi.getUniPort());
-                                // put in the meterIds  because when fi was first
-                                // created there may or may not have been a meterId
-                                // depending on whether the meter was created or
-                                // not at that time.
-                                //TODO possibly spawn this in a separate thread.
-                                fi.setUpMeterId(upMeterId);
-                                fi.setDownMeterId(downMeterId);
-                                fi.setUpOltMeterId(upOltMeterId);
-                                fi.setDownOltMeterId(downOltMeterId);
-                                handleSubFlowsWithMeters(fi);
-                                queue.remove(fi);
-                            } else {
-                                log.debug("Not all meters for {} are yet installed up {}, " +
-                                                 "down {}, oltUp {}, oltDown {}", fi, upMeterId,
-                                         downMeterId, upOltMeterId, downOltMeterId);
-                            }
-                            oltMeterService.removeFromPendingMeters(deviceId, bwpInfo);
-                        } else {
-                            // meter install failed
-                            log.error("Addition of subscriber {} on {} failed due to meter " +
-                                              "{} with result {}", fi, fi.getUniPort(), meterId, result);
-                            oltMeterService.removeFromPendingMeters(deviceId, bwpInfo);
-                            queue.remove(fi);
-                        }
+                if (!oltDeviceService.isLocalLeader(cp.deviceId())) {
+                    // if we're not local leader for this device, ignore this queue
+                    if (log.isTraceEnabled()) {
+                        log.trace("Ignoring queue on CP {} as not master of the device", cp);
                     }
-                } else {
-                    log.info("No pending subscribers on {}", deviceId);
-                    queue = new LinkedBlockingQueue<>();
-                }
-                return queue;
-            });
-        });
-
-    }
-
-    /**
-     * Add subscriber flows given meter information for both upstream and
-     * downstream directions.
-     *
-     * @param subscriberFlowInfo relevant information for subscriber
-     */
-    private void handleSubFlowsWithMeters(SubscriberFlowInfo subscriberFlowInfo) {
-        log.info("Provisioning subscriber flows based on {}", subscriberFlowInfo);
-        UniTagInformation tagInfo = subscriberFlowInfo.getTagInfo();
-        if (tagInfo.getIsDhcpRequired()) {
-            Optional<MacAddress> macAddress =
-                    getMacAddress(subscriberFlowInfo.getDevId(), subscriberFlowInfo.getUniPort(), tagInfo);
-            if (subscriberFlowInfo.getTagInfo().getEnableMacLearning()) {
-                ConnectPoint cp = new ConnectPoint(subscriberFlowInfo.getDevId(),
-                        subscriberFlowInfo.getUniPort().number());
-                if (macAddress.isPresent()) {
-                    log.debug("MAC Address {} obtained for {}", macAddress.get(), subscriberFlowInfo);
-                } else {
-                    waitingMacSubscribers.put(cp, subscriberFlowInfo);
-                    log.debug("Adding sub to waiting mac map: {}", subscriberFlowInfo);
+                    return;
                 }
 
-                CompletableFuture<ObjectiveError> dhcpFuture = new CompletableFuture<>();
-                oltFlowService.processDhcpFilteringObjectives(subscriberFlowInfo.getUniPort(),
-                        subscriberFlowInfo.getUpId(), subscriberFlowInfo.getUpOltId(),
-                        tagInfo, true, true, Optional.of(dhcpFuture));
-                dhcpFuture.thenAcceptAsync(dhcpStatus -> {
-                    if (dhcpStatus != null) {
-                        log.error("Dhcp Objective failed for {}: {}", subscriberFlowInfo, dhcpStatus);
-                        if (macAddress.isEmpty()) {
-                            waitingMacSubscribers.remove(cp, subscriberFlowInfo);
+                flowsExecutor.execute(() -> {
+                    if (!eventsQueue.isEmpty()) {
+                        // we do not remove the event from the queue until it has been processed
+                        // in that way we guarantee that events are processed in order
+                        DiscoveredSubscriber sub = eventsQueue.peek();
+                        if (sub == null) {
+                            // the queue is empty
+                            return;
                         }
-                        post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTRATION_FAILED,
-                                subscriberFlowInfo.getDevId(), subscriberFlowInfo.getUniPort().port(),
-                                tagInfo.getPonSTag(), tagInfo.getPonCTag(), tagInfo.getTechnologyProfileId()));
-                    } else {
-                        log.debug("Dhcp Objective success for: {}", subscriberFlowInfo);
-                        if (macAddress.isPresent()) {
-                            continueProvisioningSubs(subscriberFlowInfo, macAddress);
+
+                        if (log.isTraceEnabled()) {
+                            log.trace("Processing subscriber on port {} with status {}",
+                                    portWithName(sub.port), sub.status);
+                        }
+
+                        if (sub.hasSubscriber) {
+                            // this is a provision subscriber call
+                            if (oltFlowService.handleSubscriberFlows(sub, defaultBpId, multicastServiceName)) {
+                                if (log.isTraceEnabled()) {
+                                    log.trace("Provisioning of subscriber on {} completed",
+                                            portWithName(sub.port));
+                                }
+                                removeSubscriberFromQueue(sub);
+                            }
+                        } else {
+                            // this is a port event (ENABLED/DISABLED)
+                            // means no subscriber was provisioned on that port
+
+                            if (!deviceService.isAvailable(sub.device.id()) ||
+                                    deviceService.getPort(sub.device.id(), sub.port.number()) == null) {
+                                // If the device is not connected or the port is not available do nothing
+                                // This can happen when we disable and then immediately delete the device,
+                                // the queue is populated but the meters and flows are already gone
+                                // thus there is nothing left to do
+                                return;
+                            }
+
+                            if (oltFlowService.handleBasicPortFlows(sub, defaultBpId, defaultBpId)) {
+                                if (log.isTraceEnabled()) {
+                                    log.trace("Processing of port {} completed",
+                                            portWithName(sub.port));
+                                }
+                                removeSubscriberFromQueue(sub);
+                            }
                         }
                     }
                 });
-            } else {
-                log.debug("Dynamic MAC Learning disabled, so will not learn for: {}", subscriberFlowInfo);
-                // dhcp flows will handle after data plane flows
-                continueProvisioningSubs(subscriberFlowInfo, macAddress);
-            }
-        } else {
-            // dhcp not required for this service
-            continueProvisioningSubs(subscriberFlowInfo, Optional.empty());
-        }
-    }
+            });
 
-    private void continueProvisioningSubs(SubscriberFlowInfo subscriberFlowInfo, Optional<MacAddress> macAddress) {
-        AccessDevicePort uniPort = subscriberFlowInfo.getUniPort();
-        log.debug("Provisioning subscriber flows on {} based on {}", uniPort, subscriberFlowInfo);
-        UniTagInformation tagInfo = subscriberFlowInfo.getTagInfo();
-        CompletableFuture<ObjectiveError> upFuture = new CompletableFuture<>();
-        CompletableFuture<ObjectiveError> downFuture = new CompletableFuture<>();
-
-        ForwardingObjective.Builder upFwd =
-                oltFlowService.createUpBuilder(subscriberFlowInfo.getNniPort(), uniPort, subscriberFlowInfo.getUpId(),
-                        subscriberFlowInfo.getUpOltId(), subscriberFlowInfo.getTagInfo());
-        flowObjectiveService.forward(subscriberFlowInfo.getDevId(), upFwd.add(new ObjectiveContext() {
-            @Override
-            public void onSuccess(Objective objective) {
-                log.debug("Upstream HSIA flow {} installed successfully on {}", subscriberFlowInfo, uniPort);
-                upFuture.complete(null);
-            }
-
-            @Override
-            public void onError(Objective objective, ObjectiveError error) {
-                upFuture.complete(error);
-            }
-        }));
-
-        ForwardingObjective.Builder downFwd =
-                oltFlowService.createDownBuilder(subscriberFlowInfo.getNniPort(), uniPort,
-                        subscriberFlowInfo.getDownId(), subscriberFlowInfo.getDownOltId(),
-                        subscriberFlowInfo.getTagInfo(), macAddress);
-        flowObjectiveService.forward(subscriberFlowInfo.getDevId(), downFwd.add(new ObjectiveContext() {
-            @Override
-            public void onSuccess(Objective objective) {
-                log.debug("Downstream HSIA flow {} installed successfully on {}", subscriberFlowInfo, uniPort);
-                downFuture.complete(null);
-            }
-
-            @Override
-            public void onError(Objective objective, ObjectiveError error) {
-                downFuture.complete(error);
-            }
-        }));
-
-        upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
-            AccessDeviceEvent.Type type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTERED;
-            if (downStatus != null) {
-                log.error("Flow with innervlan {} and outerVlan {} on {} failed downstream installation: {}",
-                        tagInfo.getPonCTag(), tagInfo.getPonSTag(), uniPort, downStatus);
-                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTRATION_FAILED;
-            } else if (upStatus != null) {
-                log.error("Flow with innervlan {} and outerVlan {} on {} failed upstream installation: {}",
-                        tagInfo.getPonCTag(), tagInfo.getPonSTag(), uniPort, upStatus);
-                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTRATION_FAILED;
-            } else {
-                log.debug("Upstream and downstream data plane flows are installed successfully on {}", uniPort);
-                Optional<String> upstreamOltBw = tagInfo.getUpstreamOltBandwidthProfile() == null ?
-                        Optional.empty() : Optional.of(tagInfo.getUpstreamOltBandwidthProfile());
-                oltFlowService.processEapolFilteringObjectives(uniPort, tagInfo.getUpstreamBandwidthProfile(),
-                                                               upstreamOltBw, null,
-                        tagInfo.getPonCTag(), true);
-
-                if (!tagInfo.getEnableMacLearning()) {
-                    oltFlowService.processDhcpFilteringObjectives(uniPort, subscriberFlowInfo.getUpId(),
-                            subscriberFlowInfo.getUpOltId(), tagInfo, true, true, Optional.empty());
-                }
-
-                oltFlowService.processIgmpFilteringObjectives(uniPort, subscriberFlowInfo.getUpId(),
-                        subscriberFlowInfo.getUpOltId(), tagInfo, true, true);
-
-                oltFlowService.processPPPoEDFilteringObjectives(uniPort, subscriberFlowInfo.getUpId(),
-                        subscriberFlowInfo.getUpOltId(), tagInfo, true, true);
-
-                updateProgrammedSubscriber(uniPort, tagInfo, true);
-            }
-            post(new AccessDeviceEvent(type, subscriberFlowInfo.getDevId(), uniPort.port(),
-                                       tagInfo.getPonSTag(), tagInfo.getPonCTag(),
-                                       tagInfo.getTechnologyProfileId()));
-        }, oltInstallers);
-    }
-
-    /**
-     * Gets mac address from tag info if present, else checks the host service.
-     *
-     * @param deviceId device ID
-     * @param port uni port
-     * @param tagInformation tag info
-     * @return MAC Address of subscriber
-     */
-    private Optional<MacAddress> getMacAddress(DeviceId deviceId, AccessDevicePort port,
-                                               UniTagInformation tagInformation) {
-        if (isMacAddressValid(tagInformation)) {
-            log.debug("Got MAC Address {} from the uniTagInformation for {} and cTag {}",
-                    tagInformation.getConfiguredMacAddress(), port, tagInformation.getPonCTag());
-            return Optional.of(MacAddress.valueOf(tagInformation.getConfiguredMacAddress()));
-        } else if (tagInformation.getEnableMacLearning()) {
-            Optional<Host> optHost = hostService.getConnectedHosts(new ConnectPoint(deviceId, port.number()))
-                    .stream().filter(host -> host.vlan().equals(tagInformation.getPonCTag())).findFirst();
-            if (optHost.isPresent()) {
-                log.debug("Got MAC Address {} from the hostService for {} and cTag {}",
-                        optHost.get().mac(), port, tagInformation.getPonCTag());
-                return Optional.of(optHost.get().mac());
+            try {
+                TimeUnit.MILLISECONDS.sleep(requeueDelay);
+            } catch (InterruptedException e) {
+                continue;
             }
         }
-        log.debug("Could not obtain MAC Address for {} and cTag {}", port, tagInformation.getPonCTag());
-        return Optional.empty();
-    }
-
-    private boolean isMacAddressValid(UniTagInformation tagInformation) {
-        return tagInformation.getConfiguredMacAddress() != null &&
-                !tagInformation.getConfiguredMacAddress().trim().equals("") &&
-                !MacAddress.NONE.equals(MacAddress.valueOf(tagInformation.getConfiguredMacAddress()));
     }
 
     /**
@@ -1253,26 +585,26 @@
      * using the pon c tag, pon s tag and the technology profile id
      * May return Optional<null>
      *
-     * @param port        port of the subscriber
+     * @param portName  port of the subscriber
      * @param innerVlan pon c tag
      * @param outerVlan pon s tag
      * @param tpId      the technology profile id
      * @return the found uni tag information
      */
-    private Optional<UniTagInformation> getUniTagInformation(AccessDevicePort port, VlanId innerVlan,
-                                                             VlanId outerVlan, int tpId) {
+    private UniTagInformation getUniTagInformation(String portName, VlanId innerVlan,
+                                                   VlanId outerVlan, int tpId) {
         log.debug("Getting uni tag information for {}, innerVlan: {}, outerVlan: {}, tpId: {}",
-                port, innerVlan, outerVlan, tpId);
-        SubscriberAndDeviceInformation subInfo = getSubscriber(new ConnectPoint(port.deviceId(), port.number()));
+                portName, innerVlan, outerVlan, tpId);
+        SubscriberAndDeviceInformation subInfo = subsService.get(portName);
         if (subInfo == null) {
-            log.warn("Subscriber information doesn't exist for {}", port);
-            return Optional.empty();
+            log.warn("Subscriber information doesn't exist for {}", portName);
+            return null;
         }
 
         List<UniTagInformation> uniTagList = subInfo.uniTagList();
         if (uniTagList == null) {
-            log.warn("Uni tag list is not found for the subscriber {} on {}", subInfo.id(), port);
-            return Optional.empty();
+            log.warn("Uni tag list is not found for the subscriber {} on {}", subInfo.id(), portName);
+            return null;
         }
 
         UniTagInformation service = null;
@@ -1286,438 +618,298 @@
 
         if (service == null) {
             log.warn("SADIS doesn't include the service with ponCtag {} ponStag {} and tpId {} on {}",
-                     innerVlan, outerVlan, tpId, port);
-            return Optional.empty();
-        }
-
-        return Optional.of(service);
-    }
-
-    /**
-     * Creates trap flows for device, including DHCP and LLDP trap on NNI and
-     * EAPOL trap on the UNIs, if device is present in Sadis config.
-     *
-     * @param dev Device to look for
-     */
-    private void checkAndCreateDeviceFlows(Device dev) {
-        // check if this device is provisioned in Sadis
-        SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
-        log.info("checkAndCreateDeviceFlows: deviceInfo {}", deviceInfo);
-
-        if (deviceInfo != null) {
-            log.debug("Driver for device {} is {}", dev.id(),
-                     driverService.getDriver(dev.id()));
-            for (Port p : deviceService.getPorts(dev.id())) {
-                if (PortNumber.LOCAL.equals(p.number()) || !p.isEnabled()) {
-                    continue;
-                }
-                if (isUniPort(dev, p)) {
-                    AccessDevicePort port = new AccessDevicePort(p, AccessDevicePort.Type.UNI);
-                    if (!programmedSubs.containsKey(new ConnectPoint(dev.id(), p.number()))) {
-                        log.info("Creating Eapol on {}", port);
-                        oltFlowService.processEapolFilteringObjectives(port, defaultBpId, Optional.empty(),
-                                null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
-                    } else {
-                        log.debug("Subscriber Eapol on {} is already provisioned, not installing default", port);
-                    }
-                } else {
-                    AccessDevicePort port = new AccessDevicePort(p, AccessDevicePort.Type.NNI);
-                    oltFlowService.processNniFilteringObjectives(port, true);
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Get the uplink for of the OLT device.
-     * <p>
-     * This assumes that the OLT has a single uplink port. When more uplink ports need to be supported
-     * this logic needs to be changed
-     *
-     * @param dev Device to look for
-     * @return The uplink Port of the OLT
-     */
-    private AccessDevicePort getUplinkPort(Device dev) {
-        // check if this device is provisioned in Sadis
-        SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
-        log.trace("getUplinkPort: deviceInfo {}", deviceInfo);
-        if (deviceInfo == null) {
-            log.warn("Device {} is not configured in SADIS .. cannot fetch device"
-                             + " info", dev.id());
+                    innerVlan, outerVlan, tpId, portName);
             return null;
         }
-        // Return the port that has been configured as the uplink port of this OLT in Sadis
-        Optional<Port> optionalPort = deviceService.getPorts(dev.id()).stream()
-                .filter(port -> isNniPort(port) ||
-                        (port.number().toLong() == deviceInfo.uplinkPort()))
-                .findFirst();
-        if (optionalPort.isPresent()) {
-            log.trace("getUplinkPort: Found port {}", optionalPort.get());
-            return new AccessDevicePort(optionalPort.get(), AccessDevicePort.Type.NNI);
-        }
 
-        log.warn("getUplinkPort: " + NO_UPLINK_PORT, dev.id());
-        return null;
+        return service;
     }
 
-    /**
-     * Return the subscriber on a port.
-     *
-     * @param cp ConnectPoint on which to find the subscriber
-     * @return subscriber if found else null
-     */
-    protected SubscriberAndDeviceInformation getSubscriber(ConnectPoint cp) {
-        if (subsService == null) {
-            log.warn(SADIS_NOT_RUNNING);
-            return null;
-        }
-        Port port = deviceService.getPort(cp);
-        checkNotNull(port, "Invalid connect point");
-        String portName = port.annotations().value(AnnotationKeys.PORT_NAME);
-        return subsService.get(portName);
+    protected void bindSadisService(SadisService service) {
+        sadisService = service;
+        subsService = sadisService.getSubscriberInfoService();
+
+        log.info("Sadis-service binds to onos.");
     }
 
-    /**
-     * Checks whether the given port of the device is a uni port or not.
-     *
-     * @param d the access device
-     * @param p the port of the device
-     * @return true if the given port is a uni port
-     */
-    private boolean isUniPort(Device d, Port p) {
-        AccessDevicePort ulPort = getUplinkPort(d);
-        if (ulPort != null) {
-            return (ulPort.number().toLong() != p.number().toLong());
-        }
-        //handles a special case where NNI port is misconfigured in SADIS and getUplinkPort(d) returns null
-        //checks whether the port name starts with nni- which is the signature of an NNI Port
-        if (p.annotations().value(AnnotationKeys.PORT_NAME) != null &&
-                p.annotations().value(AnnotationKeys.PORT_NAME).startsWith(NNI)) {
-            log.error("NNI port number {} is not matching with configured value", p.number().toLong());
-            return false;
-        }
-        return true;
+    protected void unbindSadisService(SadisService service) {
+        deviceService.removeListener(deviceListener);
+        deviceListener = null;
+        sadisService = null;
+        subsService = null;
+        log.info("Sadis-service unbinds from onos.");
     }
 
-    /**
-     * Gets the given device details from SADIS.
-     * If the device is not found, returns null
-     *
-     * @param dev the access device
-     * @return the olt information
-     */
-    private SubscriberAndDeviceInformation getOltInfo(Device dev) {
-        if (subsService == null) {
-            log.warn(SADIS_NOT_RUNNING);
-            return null;
+    protected void addSubscriberToQueue(DiscoveredSubscriber sub) {
+        ConnectPoint cp = new ConnectPoint(sub.device.id(), sub.port.number());
+        LinkedBlockingQueue<DiscoveredSubscriber> q = null;
+        try {
+            queueReadLock.lock();
+            q = eventsQueues.getOrDefault(cp, new LinkedBlockingQueue<>());
+        } finally {
+            queueReadLock.unlock();
         }
-        String devSerialNo = dev.serialNumber();
-        return subsService.get(devSerialNo);
-    }
-
-    /**
-     * Checks for mastership or falls back to leadership on deviceId.
-     * If the device is available use mastership,
-     * otherwise fallback on leadership.
-     * Leadership on the device topic is needed because the master can be NONE
-     * in case the device went away, we still need to handle events
-     * consistently
-     */
-    private boolean isLocalLeader(DeviceId deviceId) {
-        if (deviceService.isAvailable(deviceId)) {
-            return mastershipService.isLocalMaster(deviceId);
+        if (!q.contains(sub)) {
+            log.info("Adding subscriber to queue: {} with status {} and subscriber {}",
+                    portWithName(sub.port), sub.status, sub.hasSubscriber);
+            q.add(sub);
         } else {
-            // Fallback with Leadership service - device id is used as topic
-            NodeId leader = leadershipService.runForLeadership(
-                    deviceId.toString()).leaderNodeId();
-            // Verify if this node is the leader
-            return clusterService.getLocalNode().id().equals(leader);
+            log.debug("Not adding subscriber to queue as already present: {} with status {}",
+                    portWithName(sub.port), sub.status);
+            // no need to update the queue in the map if nothing has changed
+            return;
+        }
+        try {
+            queueWriteLock.lock();
+            eventsQueues.put(cp, q);
+        } catch (UnsupportedOperationException | ClassCastException |
+                NullPointerException | IllegalArgumentException e) {
+            log.error("Cannot add subscriber to queue: {}", e.getMessage());
+        } finally {
+            queueWriteLock.unlock();
         }
     }
 
-    private boolean isNniPort(Port port) {
-        if (port.annotations().keys().contains(AnnotationKeys.PORT_NAME)) {
-            return port.annotations().value(AnnotationKeys.PORT_NAME).contains(NNI);
+    protected void removeSubscriberFromQueue(DiscoveredSubscriber sub) {
+        ConnectPoint cp = new ConnectPoint(sub.device.id(), sub.port.number());
+        LinkedBlockingQueue<DiscoveredSubscriber> q = null;
+        if (log.isTraceEnabled()) {
+            log.trace("removing subscriber {} from queue", sub);
         }
-        return false;
-    }
-
-    private class InternalHostListener implements HostListener {
-        @Override
-        public void event(HostEvent event) {
-            hostEventExecutor.execute(() -> {
-                Host host = event.subject();
-                switch (event.type()) {
-                    case HOST_ADDED:
-                        ConnectPoint cp = new ConnectPoint(host.location().deviceId(), host.location().port());
-                        Optional<SubscriberFlowInfo> optSubFlowInfo =
-                                getAndRemoveWaitingMacSubFlowInfoForCTag(cp, host.vlan());
-                        if (optSubFlowInfo.isPresent()) {
-                            log.debug("Continuing provisioning for waiting mac service. event: {}", event);
-                            continueProvisioningSubs(optSubFlowInfo.get(), Optional.of(host.mac()));
-                        } else {
-                            log.debug("There is no waiting mac sub. event: {}", event);
-                        }
-                        break;
-                    case HOST_UPDATED:
-                        if (event.prevSubject() != null && !event.prevSubject().mac().equals(event.subject().mac())) {
-                            log.debug("Subscriber's MAC address changed from {} to {}. " +
-                                            "devId/portNumber: {}/{} vlan: {}", event.prevSubject().mac(),
-                                    event.subject().mac(), host.location().deviceId(), host.location().port(),
-                                    host.vlan());
-                            // TODO handle subscriber MAC Address changed
-                        } else {
-                            log.debug("Unhandled HOST_UPDATED event: {}", event);
-                        }
-                        break;
-                    default:
-                        log.debug("Unhandled host event received. event: {}", event);
-                }
-            });
+        try {
+            queueReadLock.lock();
+            q = eventsQueues.get(cp);
+        } finally {
+            queueReadLock.unlock();
+        }
+        if (q == null) {
+            log.warn("Cannot find queue for connectPoint {}", cp);
+            return;
+        }
+        boolean removed = q.remove(sub);
+        if (!removed) {
+            log.warn("Subscriber {} has not been removed from queue, is it still there? {}", sub, q);
+            return;
+        } else {
+            log.debug("Subscriber {} has been removed from the queue", sub);
         }
 
-        @Override
-        public boolean isRelevant(HostEvent event) {
-            return isLocalLeader(event.subject().location().deviceId());
+        try {
+            queueWriteLock.lock();
+            eventsQueues.remove(cp); // am I needed??
+            eventsQueues.put(cp, q);
+        } catch (UnsupportedOperationException | ClassCastException |
+                NullPointerException | IllegalArgumentException e) {
+            log.error("Cannot remove subscriber {} from queue: {}", sub, e.getMessage());
+        } finally {
+            queueWriteLock.unlock();
         }
     }
 
-    private class InternalDeviceListener implements DeviceListener {
-        private Set<DeviceId> programmedDevices = Sets.newConcurrentHashSet();
+    protected class OltDeviceListener
+            implements DeviceListener {
+
+        private final Logger log = LoggerFactory.getLogger(getClass());
+        protected ExecutorService eventExecutor;
+
+        /**
+         * Builds the listener with all the proper services and information needed.
+         */
+        public OltDeviceListener() {
+            this.eventExecutor = Executors.newFixedThreadPool(flowProcessingThreads,
+                    groupedThreads("onos/olt-device-listener-event", "event-%d", log));
+        }
+
+        public void deactivate() {
+            this.eventExecutor.shutdown();
+        }
 
         @Override
         public void event(DeviceEvent event) {
             eventExecutor.execute(() -> {
-                DeviceId devId = event.subject().id();
-                Device dev = event.subject();
-                Port p = event.port();
-                DeviceEvent.Type eventType = event.type();
-
-                if (DeviceEvent.Type.PORT_STATS_UPDATED.equals(eventType) ||
-                        DeviceEvent.Type.DEVICE_SUSPENDED.equals(eventType) ||
-                        DeviceEvent.Type.DEVICE_UPDATED.equals(eventType)) {
-                    return;
-                }
-
-                boolean isLocalLeader = isLocalLeader(devId);
-                // Only handle the event if the device belongs to us
-                if (!isLocalLeader && event.type().equals(DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED)
-                        && !deviceService.isAvailable(devId) && deviceService.getPorts(devId).isEmpty()) {
-                    log.info("Cleaning local state for non master instance upon " +
-                                     "device disconnection {}", devId);
-                    // Since no mastership of the device is present upon disconnection
-                    // the method in the FlowRuleManager only empties the local copy
-                    // of the DeviceFlowTable thus this method needs to get called
-                    // on every instance, see how it's done in the InternalDeviceListener
-                    // in FlowRuleManager: no mastership check for purgeOnDisconnection
-                    handleDeviceDisconnection(dev, false, false);
-                    return;
-                } else if (!isLocalLeader) {
-                    log.debug("Not handling event because instance is not leader for {}", devId);
-                    return;
-                }
-
-                log.debug("OLT got {} event for {}/{}", eventType, event.subject(), event.port());
-
-                if (getOltInfo(dev) == null) {
-                    // it's possible that we got an event for a previously
-                    // programmed OLT that is no longer available in SADIS
-                    // we let such events go through
-                    if (!programmedDevices.contains(devId)) {
-                        log.warn("No device info found for {}, this is either "
-                                         + "not an OLT or not known to sadis", dev);
-                        return;
-                    }
-                }
-                AccessDevicePort port = null;
-                if (p != null) {
-                    if (isUniPort(dev, p)) {
-                        port = new AccessDevicePort(p, AccessDevicePort.Type.UNI);
-                    } else {
-                        port = new AccessDevicePort(p, AccessDevicePort.Type.NNI);
-                    }
-                }
-
+                boolean isOlt = oltDeviceService.isOlt(event.subject());
+                DeviceId deviceId = event.subject().id();
                 switch (event.type()) {
-                    //TODO: Port handling and bookkeeping should be improved once
-                    // olt firmware handles correct behaviour.
-                    case PORT_ADDED:
-                        if (!deviceService.isAvailable(devId)) {
-                            log.warn("Received {} for disconnected device {}, ignoring", event, devId);
-                            return;
-                        }
-                        if (port.type().equals(AccessDevicePort.Type.UNI)) {
-                            post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_ADDED, devId, port.port()));
-
-                            if (port.isEnabled() && !port.number().equals(PortNumber.LOCAL)) {
-                                log.info("eapol will be sent for port added {}", port);
-                                oltFlowService.processEapolFilteringObjectives(port, defaultBpId, Optional.empty(),
-                                                                               null,
-                                                                               VlanId.vlanId(EAPOL_DEFAULT_VLAN),
-                                                                               true);
-                            }
-                        } else {
-                            SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
-                            if (deviceInfo != null) {
-                                oltFlowService.processNniFilteringObjectives(port, true);
-                            }
-                        }
-                        break;
-                    case PORT_REMOVED:
-                        if (port.type().equals(AccessDevicePort.Type.UNI)) {
-                            // if no subscriber is provisioned we need to remove the default EAPOL
-                            // if a subscriber was provisioned the default EAPOL will not be there and we can skip.
-                            // The EAPOL with subscriber tag will be removed by removeSubscriber call.
-                            Collection<? extends UniTagInformation> uniTagInformationSet =
-                                    programmedSubs.get(new ConnectPoint(port.deviceId(), port.number())).value();
-                            if (uniTagInformationSet == null || uniTagInformationSet.isEmpty()) {
-                                log.info("No subscriber provisioned on port {} in PORT_REMOVED event, " +
-                                                 "removing default EAPOL flow", port);
-                                oltFlowService.processEapolFilteringObjectives(port, defaultBpId, Optional.empty(),
-                                        null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
-                            } else {
-                                removeSubscriber(port);
-                            }
-
-                            post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_REMOVED, devId, port.port()));
-                        }
-                        break;
-                    case PORT_UPDATED:
-                        if (!deviceService.isAvailable(devId)) {
-                            log.warn("Received {} for disconnected device {}, ignoring", event, devId);
-                            return;
-                        }
-                        if (port.type().equals(AccessDevicePort.Type.NNI)) {
-                            SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
-                            if (deviceInfo != null && port.isEnabled()) {
-                                log.debug("NNI {} enabled", port);
-                                oltFlowService.processNniFilteringObjectives(port, true);
-                            }
-                            return;
-                        }
-                        ConnectPoint cp = new ConnectPoint(devId, port.number());
-                        Collection<? extends UniTagInformation> uniTagInformationSet = programmedSubs.get(cp).value();
-                        if (uniTagInformationSet == null || uniTagInformationSet.isEmpty()) {
-                            if (!port.number().equals(PortNumber.LOCAL)) {
-                                log.info("eapol will be {} updated for {} with default vlan {}",
-                                         (port.isEnabled()) ? "added" : "removed", port, EAPOL_DEFAULT_VLAN);
-                                oltFlowService.processEapolFilteringObjectives(port, defaultBpId, Optional.empty(),
-                                        null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), port.isEnabled());
-                            }
-                        } else {
-                            log.info("eapol will be {} updated for {}", (port.isEnabled()) ? "added" : "removed",
-                                     port);
-                            for (UniTagInformation uniTag : uniTagInformationSet) {
-                                oltFlowService.processEapolFilteringObjectives(port,
-                                        uniTag.getUpstreamBandwidthProfile(),
-                                        Optional.of(uniTag.getUpstreamOltBandwidthProfile()),
-                                        null, uniTag.getPonCTag(), port.isEnabled());
-                            }
-                        }
-                        if (port.isEnabled()) {
-                            post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_ADDED, devId, port.port()));
-                        } else {
-                            post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_REMOVED, devId, port.port()));
-                        }
-                        break;
+                    case PORT_STATS_UPDATED:
                     case DEVICE_ADDED:
-                        handleDeviceConnection(dev, true);
-                        break;
-                    case DEVICE_REMOVED:
-                        handleDeviceDisconnection(dev, true, true);
-                        break;
-                    case DEVICE_AVAILABILITY_CHANGED:
-                        if (deviceService.isAvailable(devId)) {
-                            log.info("Handling available device: {}", dev.id());
-                            handleDeviceConnection(dev, false);
-                        } else {
-                            if (deviceService.getPorts(devId).isEmpty()) {
-                                log.info("Handling controlled device disconnection .. "
-                                                 + "flushing all state for dev:{}", devId);
-                                handleDeviceDisconnection(dev, true, false);
-                            } else {
-                                log.info("Disconnected device has available ports .. "
-                                                 + "assuming temporary disconnection, "
-                                                 + "retaining state for device {}", devId);
-                            }
-                        }
-                        break;
-                    default:
-                        log.debug("Not handling event {}", event);
                         return;
+                    case PORT_ADDED:
+                    case PORT_UPDATED:
+                    case PORT_REMOVED:
+                        if (!isOlt) {
+                            log.trace("Ignoring event {}, this is not an OLT device", deviceId);
+                            return;
+                        }
+                        if (!oltDeviceService.isLocalLeader(deviceId)) {
+                            log.trace("Device {} is not local to this node", deviceId);
+                            return;
+                        }
+                        // port added, updated and removed are treated in the same way as we only care whether the port
+                        // is enabled or not
+                        handleOltPort(event.type(), event.subject(), event.port());
+                        return;
+                    case DEVICE_AVAILABILITY_CHANGED:
+                        if (!isOlt) {
+                            log.trace("Ignoring event {}, this is not an OLT device", deviceId);
+                            return;
+                        }
+                        if (deviceService.isAvailable(deviceId)) {
+                            if (!oltDeviceService.isLocalLeader(deviceId)) {
+                                if (log.isTraceEnabled()) {
+                                    log.trace("Device {} is not local to this node, not handling available device",
+                                            deviceId);
+                                }
+                            } else {
+                                log.info("Handling available device: {}", deviceId);
+                                handleExistingPorts();
+                            }
+                        } else if (!deviceService.isAvailable(deviceId) && deviceService.getPorts(deviceId).isEmpty()) {
+                            // NOTE that upon disconnection there is no mastership on the device,
+                            // and we should anyway clear the local cache of the flows/meters across instances.
+                            // We're only clearing the device if there are no available ports,
+                            // otherwise we assume it's a temporary disconnection
+                            log.info("Device {} availability changed to false and ports are empty, " +
+                                    "purging meters and flows", deviceId);
+                            //NOTE all the instances will call these methods
+                            oltFlowService.purgeDeviceFlows(deviceId);
+                            oltMeterService.purgeDeviceMeters(deviceId);
+                            clearQueueForDevice(deviceId);
+                        } else {
+                            log.info("Device {} availability changed to false, but ports are still available, " +
+                                            "assuming temporary disconnection. Ports: {}",
+                                    deviceId, deviceService.getPorts(deviceId));
+                        }
+                        return;
+                    case DEVICE_REMOVED:
+                        if (!isOlt) {
+                            log.trace("Ignoring event {}, this is not an OLT device", deviceId);
+                            return;
+                        }
+                        log.info("Device {} Removed, purging meters and flows", deviceId);
+                        oltFlowService.purgeDeviceFlows(deviceId);
+                        oltMeterService.purgeDeviceMeters(deviceId);
+                        clearQueueForDevice(deviceId);
+                        return;
+                    default:
+                        if (log.isTraceEnabled()) {
+                            log.trace("Not handling event: {}, ", event);
+                        }
                 }
             });
         }
 
-        private void sendUniEvent(Device device, AccessDeviceEvent.Type eventType) {
-            deviceService.getPorts(device.id()).stream()
-                    .filter(p -> !PortNumber.LOCAL.equals(p.number()))
-                    .filter(p -> isUniPort(device, p))
-                    .forEach(p -> post(new AccessDeviceEvent(eventType, device.id(), p)));
-        }
-
-        private void handleDeviceDisconnection(Device device, boolean sendDisconnectedEvent, boolean sendUniEvent) {
-            programmedDevices.remove(device.id());
-            removeAllSubscribers(device.id());
-            removeWaitingMacSubs(device.id());
-            //Handle case where OLT disconnects during subscriber provisioning
-            pendingSubscribersForDevice.remove(device.id());
-            oltFlowService.clearDeviceState(device.id());
-
-            //Complete meter and flow purge
-            flowRuleService.purgeFlowRules(device.id());
-            oltMeterService.clearMeters(device.id());
-            if (sendDisconnectedEvent) {
-                post(new AccessDeviceEvent(
-                        AccessDeviceEvent.Type.DEVICE_DISCONNECTED, device.id(),
-                        null, null, null));
-            }
-            if (sendUniEvent) {
-                sendUniEvent(device, AccessDeviceEvent.Type.UNI_REMOVED);
+        protected void clearQueueForDevice(DeviceId devId) {
+            try {
+                queueWriteLock.lock();
+                Iterator<Map.Entry<ConnectPoint, LinkedBlockingQueue<DiscoveredSubscriber>>> iter =
+                        eventsQueues.entrySet().iterator();
+                while (iter.hasNext()) {
+                    Map.Entry<ConnectPoint, LinkedBlockingQueue<DiscoveredSubscriber>> entry = iter.next();
+                    if (entry.getKey().deviceId().equals(devId)) {
+                        eventsQueues.remove(entry.getKey());
+                    }
+                }
+            } finally {
+                queueWriteLock.unlock();
             }
         }
 
-        private void handleDeviceConnection(Device dev, boolean sendUniEvent) {
-            post(new AccessDeviceEvent(
-                    AccessDeviceEvent.Type.DEVICE_CONNECTED, dev.id(),
-                    null, null, null));
-            programmedDevices.add(dev.id());
-            checkAndCreateDeviceFlows(dev);
-            if (sendUniEvent) {
-                sendUniEvent(dev, AccessDeviceEvent.Type.UNI_ADDED);
+        protected void handleOltPort(DeviceEvent.Type type, Device device, Port port) {
+            log.info("OltDeviceListener receives event {} for port {} with status {} on device {}", type,
+                    portWithName(port), port.isEnabled() ? "ENABLED" : "DISABLED", device.id());
+            if (port.isEnabled()) {
+                if (oltDeviceService.isNniPort(device, port.number())) {
+                    // NOTE in the NNI case we receive a PORT_REMOVED event with status ENABLED, thus we need to
+                    // pass the floeAction to the handleNniFlows method
+                    OltFlowService.FlowOperation action = OltFlowService.FlowOperation.ADD;
+                    if (type == DeviceEvent.Type.PORT_REMOVED) {
+                        action = OltFlowService.FlowOperation.REMOVE;
+                    }
+                    oltFlowService.handleNniFlows(device, port, action);
+                } else {
+                    post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_ADDED, device.id(), port));
+                    // NOTE if the subscriber was previously provisioned,
+                    // then add it back to the queue to be re-provisioned
+                    boolean provisionSubscriber = oltFlowService.
+                            isSubscriberServiceProvisioned(new AccessDevicePort(port));
+                    SubscriberAndDeviceInformation si = subsService.get(getPortName(port));
+                    if (si == null) {
+                        //NOTE this should not happen given that the subscriber was provisioned before
+                        log.error("Subscriber information not found in sadis for port {}",
+                                portWithName(port));
+                        return;
+                    }
+
+                    DiscoveredSubscriber.Status status = DiscoveredSubscriber.Status.ADDED;
+                    if (type == DeviceEvent.Type.PORT_REMOVED) {
+                        status = DiscoveredSubscriber.Status.REMOVED;
+                    }
+
+                    DiscoveredSubscriber sub =
+                            new DiscoveredSubscriber(device, port,
+                                    status, provisionSubscriber, si);
+                    addSubscriberToQueue(sub);
+                }
+            } else {
+                if (oltDeviceService.isNniPort(device, port.number())) {
+                    // NOTE this may need to be handled on DEVICE_REMOVE as we don't disable the NNI
+                    oltFlowService.handleNniFlows(device, port, OltFlowService.FlowOperation.REMOVE);
+                } else {
+                    post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_REMOVED, device.id(), port));
+                    // NOTE we are assuming that if a subscriber has default eapol
+                    // it does not have subscriber flows
+                    if (oltFlowService.hasDefaultEapol(port)) {
+                        SubscriberAndDeviceInformation si = subsService.get(getPortName(port));
+                        if (si == null) {
+                            //NOTE this should not happen given that the subscriber was provisioned before
+                            log.error("Subscriber information not found in sadis for port {}",
+                                    portWithName(port));
+                            return;
+                        }
+                        DiscoveredSubscriber sub =
+                                new DiscoveredSubscriber(device, port,
+                                        DiscoveredSubscriber.Status.REMOVED, false, si);
+
+                        addSubscriberToQueue(sub);
+
+                    } else if (oltFlowService.isSubscriberServiceProvisioned(new AccessDevicePort(port))) {
+                        SubscriberAndDeviceInformation si = subsService.get(getPortName(port));
+                        if (si == null) {
+                            //NOTE this should not happen given that the subscriber was provisioned before
+                            log.error("Subscriber information not found in sadis for port {}",
+                                    portWithName(port));
+                            return;
+                        }
+                        DiscoveredSubscriber sub =
+                                new DiscoveredSubscriber(device, port,
+                                        DiscoveredSubscriber.Status.REMOVED, true, si);
+                        addSubscriberToQueue(sub);
+                    }
+                }
             }
         }
 
-        private void removeAllSubscribers(DeviceId deviceId) {
-            List<Map.Entry<ConnectPoint, UniTagInformation>> subs = programmedSubs.stream()
-                    .filter(e -> e.getKey().deviceId().equals(deviceId))
-                    .collect(toList());
-
-            subs.forEach(e -> programmedSubs.remove(e.getKey(), e.getValue()));
-        }
-
-        private void removeWaitingMacSubs(DeviceId deviceId) {
-            List<ConnectPoint> waitingMacKeys = waitingMacSubscribers.stream()
-                    .filter(cp -> cp.getKey().deviceId().equals(deviceId))
-                    .map(Map.Entry::getKey)
-                    .collect(toList());
-            waitingMacKeys.forEach(cp -> waitingMacSubscribers.removeAll(cp));
-        }
-
-    }
-
-    private class InternalClusterListener implements ClusterEventListener {
-
-        @Override
-        public void event(ClusterEvent event) {
-            if (event.type() == ClusterEvent.Type.INSTANCE_READY) {
-                hasher.addServer(event.subject().id());
-            }
-            if (event.type() == ClusterEvent.Type.INSTANCE_DEACTIVATED) {
-                hasher.removeServer(event.subject().id());
+        /**
+         * This method is invoked on app activation in order to deal
+         * with devices and ports that are already existing in the system
+         * and thus won't trigger an event.
+         * It is also needed on instance reboot and device reconnect
+         */
+        protected void handleExistingPorts() {
+            Iterable<DeviceId> devices = getConnectedOlts();
+            for (DeviceId deviceId : devices) {
+                log.info("Handling existing OLT Ports for device {}", deviceId);
+                if (oltDeviceService.isLocalLeader(deviceId)) {
+                    List<Port> ports = deviceService.getPorts(deviceId);
+                    for (Port p : ports) {
+                        if (PortNumber.LOCAL.equals(p.number()) || !p.isEnabled()) {
+                            continue;
+                        }
+                        Device device = deviceService.getDevice(deviceId);
+                        deviceListener.handleOltPort(DeviceEvent.Type.PORT_UPDATED, device, p);
+                    }
+                }
             }
         }
     }
-
 }
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltDeviceService.java b/impl/src/main/java/org/opencord/olt/impl/OltDeviceService.java
new file mode 100644
index 0000000..b336c28
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/OltDeviceService.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * The implementation of the OltDeviceService.
+ */
+@Component(immediate = true)
+public class OltDeviceService implements OltDeviceServiceInterface {
+
+    protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL,
+            bind = "bindSadisService",
+            unbind = "unbindSadisService",
+            policy = ReferencePolicy.DYNAMIC)
+    protected volatile SadisService sadisService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected LeadershipService leadershipService;
+
+    @Activate
+    public void activate() {
+        log.info("Activated");
+    }
+
+    /**
+     * Returns true if the device is an OLT.
+     *
+     * @param device the Device to be checked
+     * @return boolean
+     */
+    public boolean isOlt(Device device) {
+        return getOltInfo(device) != null;
+    }
+
+    private SubscriberAndDeviceInformation getOltInfo(Device dev) {
+        if (subsService == null) {
+            return null;
+        }
+        String devSerialNo = dev.serialNumber();
+        return subsService.get(devSerialNo);
+    }
+
+
+    /**
+     * Returns true if the port is an NNI Port on the OLT.
+     * NOTE: We can check if a port is a NNI based on the SADIS config, specifically the uplinkPort section
+     *
+     * @param dev  the Device this port belongs to
+     * @param portNumber the PortNumber to be checked
+     * @return boolean
+     */
+    @Override
+    public boolean isNniPort(Device dev, PortNumber portNumber) {
+        SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
+        return deviceInfo != null && portNumber.toLong() == deviceInfo.uplinkPort();
+    }
+
+    @Override
+    public Optional<Port> getNniPort(Device device) {
+        SubscriberAndDeviceInformation deviceInfo = getOltInfo(device);
+        if (deviceInfo == null) {
+            return Optional.empty();
+        }
+        List<Port> ports = deviceService.getPorts(device.id());
+        if (log.isTraceEnabled()) {
+            log.trace("Get NNI Port looks for NNI in: {}", ports);
+        }
+        return ports.stream()
+                .filter(p -> p.number().toLong() == deviceInfo.uplinkPort())
+                .findFirst();
+    }
+
+    protected void bindSadisService(SadisService service) {
+        this.subsService = service.getSubscriberInfoService();
+        log.info("Sadis service is loaded");
+    }
+
+    protected void unbindSadisService(SadisService service) {
+        this.subsService = null;
+        log.info("Sadis service is unloaded");
+    }
+
+    /**
+     * Checks for mastership or falls back to leadership on deviceId.
+     * If the device is available use mastership,
+     * otherwise fallback on leadership.
+     * Leadership on the device topic is needed because the master can be NONE
+     * in case the device went away, we still need to handle events
+     * consistently
+     *
+     * @param deviceId The device ID to check.
+     * @return boolean (true if the current instance is managing the device)
+     */
+    @Override
+    public boolean isLocalLeader(DeviceId deviceId) {
+        if (deviceService.isAvailable(deviceId)) {
+            return mastershipService.isLocalMaster(deviceId);
+        } else {
+            // Fallback with Leadership service - device id is used as topic
+            NodeId leader = leadershipService.runForLeadership(
+                    deviceId.toString()).leaderNodeId();
+            // Verify if this node is the leader
+            return clusterService.getLocalNode().id().equals(leader);
+        }
+    }
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltDeviceServiceInterface.java b/impl/src/main/java/org/opencord/olt/impl/OltDeviceServiceInterface.java
new file mode 100644
index 0000000..e8fcccb
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/OltDeviceServiceInterface.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+
+import java.util.Optional;
+
+/**
+ * Service for olt device handling.
+ */
+public interface OltDeviceServiceInterface {
+    /**
+     * Returns true if the device is a known OLT to sadis/config.
+     * @param device the device
+     * @return true if a configured olt
+     */
+    boolean isOlt(Device device);
+
+    /**
+     * Returns true if the port is an NNI port of the OLT device.
+     * @param device the device
+     * @param port the port
+     * @return true if an NNI port of that OLT
+     */
+    boolean isNniPort(Device device, PortNumber port);
+
+    /**
+     * Returns the NNi port fo the OLT device if present.
+     * @param device the device
+     * @return the nni Port, if present
+     */
+    Optional<Port> getNniPort(Device device);
+
+    /**
+     * Returns true if the instance is leader for the OLT device.
+     * @param deviceId the device
+     * @return true if master, false otherwise.
+     */
+    boolean isLocalLeader(DeviceId deviceId);
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java b/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java
index 1868421..ee184a5 100644
--- a/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java
+++ b/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,8 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.opencord.olt.impl;
 
+import com.google.common.collect.ImmutableMap;
 import org.onlab.packet.EthType;
 import org.onlab.packet.IPv4;
 import org.onlab.packet.IPv6;
@@ -26,18 +28,31 @@
 import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
-import org.onosproject.mastership.MastershipService;
 import org.onosproject.net.Annotations;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleListener;
+import org.onosproject.net.flow.FlowRuleService;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.UdpPortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
 import org.onosproject.net.flowobjective.DefaultFilteringObjective;
 import org.onosproject.net.flowobjective.DefaultForwardingObjective;
 import org.onosproject.net.flowobjective.FilteringObjective;
@@ -46,13 +61,11 @@
 import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.flowobjective.ObjectiveContext;
 import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.host.HostService;
 import org.onosproject.net.meter.MeterId;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.Serializer;
 import org.onosproject.store.service.StorageService;
-import org.opencord.olt.AccessDevicePort;
-import org.opencord.olt.internalapi.AccessDeviceFlowService;
-import org.opencord.olt.internalapi.AccessDeviceMeterService;
 import org.opencord.sadis.BandwidthProfileInformation;
 import org.opencord.sadis.BaseInformationService;
 import org.opencord.sadis.SadisService;
@@ -67,26 +80,46 @@
 import org.osgi.service.component.annotations.ReferenceCardinality;
 import org.osgi.service.component.annotations.ReferencePolicy;
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import java.util.Arrays;
 import java.util.Dictionary;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.Properties;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
 import static org.onlab.util.Tools.get;
-import static org.opencord.olt.impl.OsgiPropertyConstants.*;
-import static org.slf4j.LoggerFactory.getLogger;
+import static org.onosproject.net.flow.instructions.Instruction.Type.L2MODIFICATION;
+import static org.opencord.olt.impl.OltUtils.completeFlowOpToString;
+import static org.opencord.olt.impl.OltUtils.flowOpToString;
+import static org.opencord.olt.impl.OltUtils.getPortName;
+import static org.opencord.olt.impl.OltUtils.portWithName;
+import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_TP_ID;
+import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_TP_ID_DEFAULT;
+import static org.opencord.olt.impl.OsgiPropertyConstants.DOWNSTREAM_OLT;
+import static org.opencord.olt.impl.OsgiPropertyConstants.DOWNSTREAM_ONU;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_ON_NNI;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_ON_NNI_DEFAULT;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_V4;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_V4_DEFAULT;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_V6;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_V6_DEFAULT;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_EAPOL;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_EAPOL_DEFAULT;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_IGMP_ON_NNI;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_IGMP_ON_NNI_DEFAULT;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_PPPOE;
+import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_PPPOE_DEFAULT;
+import static org.opencord.olt.impl.OsgiPropertyConstants.UPSTREAM_OLT;
+import static org.opencord.olt.impl.OsgiPropertyConstants.UPSTREAM_ONU;
+import static org.opencord.olt.impl.OsgiPropertyConstants.WAIT_FOR_REMOVAL;
+import static org.opencord.olt.impl.OsgiPropertyConstants.WAIT_FOR_REMOVAL_DEFAULT;
 
-/**
- * Provisions flow rules on access devices.
- */
 @Component(immediate = true, property = {
         ENABLE_DHCP_ON_NNI + ":Boolean=" + ENABLE_DHCP_ON_NNI_DEFAULT,
         ENABLE_DHCP_V4 + ":Boolean=" + ENABLE_DHCP_V4_DEFAULT,
@@ -94,32 +127,20 @@
         ENABLE_IGMP_ON_NNI + ":Boolean=" + ENABLE_IGMP_ON_NNI_DEFAULT,
         ENABLE_EAPOL + ":Boolean=" + ENABLE_EAPOL_DEFAULT,
         ENABLE_PPPOE + ":Boolean=" + ENABLE_PPPOE_DEFAULT,
-        DEFAULT_TP_ID + ":Integer=" + DEFAULT_TP_ID_DEFAULT
+        DEFAULT_TP_ID + ":Integer=" + DEFAULT_TP_ID_DEFAULT,
+        // FIXME remove this option as potentially dangerous in production
+        WAIT_FOR_REMOVAL + ":Boolean=" + WAIT_FOR_REMOVAL_DEFAULT
 })
-public class OltFlowService implements AccessDeviceFlowService {
-    private static final String SADIS_NOT_RUNNING = "Sadis is not running.";
-    private static final String APP_NAME = "org.opencord.olt";
-    private static final int NONE_TP_ID = -1;
-    private static final int NO_PCP = -1;
-    private static final Integer MAX_PRIORITY = 10000;
-    private static final Integer MIN_PRIORITY = 1000;
-    private static final String INSTALLED = "installed";
-    private static final String REMOVED = "removed";
-    private static final String INSTALLATION = "installation";
-    private static final String REMOVAL = "removal";
-    private static final String V4 = "V4";
-    private static final String V6 = "V6";
-
-    private final Logger log = getLogger(getClass());
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected FlowObjectiveService flowObjectiveService;
+public class OltFlowService implements OltFlowServiceInterface {
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected CoreService coreService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected MastershipService mastershipService;
+    protected ComponentConfigService cfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected FlowObjectiveService flowObjectiveService;
 
     @Reference(cardinality = ReferenceCardinality.OPTIONAL,
             bind = "bindSadisService",
@@ -128,17 +149,65 @@
     protected volatile SadisService sadisService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected OltMeterServiceInterface oltMeterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected OltDeviceServiceInterface oltDeviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected DeviceService deviceService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected AccessDeviceMeterService oltMeterService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected ComponentConfigService componentConfigService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected StorageService storageService;
 
+    protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
+    protected BaseInformationService<BandwidthProfileInformation> bpService;
+
+    private static final String APP_NAME = "org.opencord.olt";
+    protected ApplicationId appId;
+    private static final Integer MAX_PRIORITY = 10000;
+    private static final Integer MIN_PRIORITY = 1000;
+    private static final short EAPOL_DEFAULT_VLAN = 4091;
+    private static final int NONE_TP_ID = -1;
+    private static final String V4 = "V4";
+    private static final String V6 = "V6";
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    protected UniTagInformation defaultEapolUniTag = new UniTagInformation.Builder()
+            .setServiceName("defaultEapol").build();
+    protected UniTagInformation nniUniTag = new UniTagInformation.Builder()
+            .setServiceName("nni")
+            .setTechnologyProfileId(NONE_TP_ID)
+            .setPonCTag(VlanId.NONE)
+            .setUniTagMatch(VlanId.ANY)
+            .setUsPonCTagPriority(-1)
+            .build();
+
+    /**
+     * Connect Point status map.
+     * Used to keep track of which cp has flows that needs to be removed when the status changes.
+     */
+    protected Map<ServiceKey, OltPortStatus> cpStatus;
+    private final ReentrantReadWriteLock cpStatusLock = new ReentrantReadWriteLock();
+    private final Lock cpStatusWriteLock = cpStatusLock.writeLock();
+    private final Lock cpStatusReadLock = cpStatusLock.readLock();
+
+    /**
+     * This map contains the subscriber that have been provisioned by the operator.
+     * They may or may not have flows, depending on the port status.
+     * The map is used to define whether flows need to be provisioned when a port comes up.
+     */
+    protected Map<ServiceKey, Boolean> provisionedSubscribers;
+    private final ReentrantReadWriteLock provisionedSubscribersLock = new ReentrantReadWriteLock();
+    private final Lock provisionedSubscribersWriteLock = provisionedSubscribersLock.writeLock();
+    private final Lock provisionedSubscribersReadLock = provisionedSubscribersLock.readLock();
+
     /**
      * Create DHCP trap flow on NNI port(s).
      */
@@ -174,42 +243,76 @@
      **/
     protected int defaultTechProfileId = DEFAULT_TP_ID_DEFAULT;
 
-    protected ApplicationId appId;
-    protected BaseInformationService<BandwidthProfileInformation> bpService;
-    protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
-    protected Map<DeviceId, BlockingQueue<SubscriberFlowInfo>> pendingEapolForDevice;
+    protected boolean waitForRemoval = WAIT_FOR_REMOVAL_DEFAULT;
+
+    public enum FlowOperation {
+        ADD,
+        REMOVE;
+
+
+        @Override
+        public String toString() {
+            return super.toString().toLowerCase();
+        }
+    }
+
+    public enum FlowDirection {
+        UPSTREAM,
+        DOWNSTREAM,
+    }
+
+    public enum OltFlowsStatus {
+        NONE,
+        PENDING_ADD,
+        ADDED,
+        PENDING_REMOVE,
+        REMOVED,
+        ERROR
+    }
+
+    protected InternalFlowListener internalFlowListener;
 
     @Activate
     public void activate(ComponentContext context) {
-        if (sadisService != null) {
-            bpService = sadisService.getBandwidthProfileService();
-            subsService = sadisService.getSubscriberInfoService();
-        } else {
-            log.warn(SADIS_NOT_RUNNING);
-        }
-        componentConfigService.registerProperties(getClass());
-        appId = coreService.getAppId(APP_NAME);
+        cfgService.registerProperties(getClass());
+        appId = coreService.registerApplication(APP_NAME);
+        internalFlowListener = new InternalFlowListener();
+
+        modified(context);
+
         KryoNamespace serializer = KryoNamespace.newBuilder()
                 .register(KryoNamespaces.API)
-                .register(UniTagInformation.class)
-                .register(SubscriberFlowInfo.class)
+                .register(OltFlowsStatus.class)
+                .register(FlowDirection.class)
+                .register(OltPortStatus.class)
+                .register(OltFlowsStatus.class)
                 .register(AccessDevicePort.class)
-                .register(AccessDevicePort.Type.class)
-                .register(LinkedBlockingQueue.class)
+                .register(new ServiceKeySerializer(), ServiceKey.class)
+                .register(UniTagInformation.class)
                 .build();
-        pendingEapolForDevice = storageService.<DeviceId, BlockingQueue<SubscriberFlowInfo>>consistentMapBuilder()
-                .withName("volt-pending-eapol")
-                .withSerializer(Serializer.using(serializer))
-                .withApplicationId(appId)
-                .build().asJavaMap();
-        log.info("started");
-    }
 
+        cpStatus = storageService.<ServiceKey, OltPortStatus>consistentMapBuilder()
+                .withName("volt-cp-status")
+                .withApplicationId(appId)
+                .withSerializer(Serializer.using(serializer))
+                .build().asJavaMap();
+
+        provisionedSubscribers = storageService.<ServiceKey, Boolean>consistentMapBuilder()
+                .withName("volt-provisioned-subscriber")
+                .withApplicationId(appId)
+                .withSerializer(Serializer.using(serializer))
+                .build().asJavaMap();
+
+        flowRuleService.addListener(internalFlowListener);
+
+        log.info("Started");
+    }
 
     @Deactivate
     public void deactivate(ComponentContext context) {
-        componentConfigService.unregisterProperties(getClass(), false);
-        log.info("stopped");
+        cfgService.unregisterProperties(getClass(), false);
+        flowRuleService.removeListener(internalFlowListener);
+        log.info("Stopped");
     }
 
     @Modified
@@ -247,106 +350,712 @@
             enablePppoe = pppoe;
         }
 
+        Boolean wait = Tools.isPropertyEnabled(properties, WAIT_FOR_REMOVAL);
+        if (wait != null) {
+            waitForRemoval = wait;
+        }
+
         String tpId = get(properties, DEFAULT_TP_ID);
         defaultTechProfileId = isNullOrEmpty(tpId) ? DEFAULT_TP_ID_DEFAULT : Integer.parseInt(tpId.trim());
 
-        log.info("modified. Values = enableDhcpOnNni: {}, enableDhcpV4: {}, " +
-                         "enableDhcpV6:{}, enableIgmpOnNni:{}, " +
-                         "enableEapol:{}, enablePppoe:{}, defaultTechProfileId:{}",
-                 enableDhcpOnNni, enableDhcpV4, enableDhcpV6,
-                 enableIgmpOnNni, enableEapol,  enablePppoe,
-                 defaultTechProfileId);
+        log.info("Modified. Values = enableDhcpOnNni: {}, enableDhcpV4: {}, " +
+                        "enableDhcpV6:{}, enableIgmpOnNni:{}, " +
+                        "enableEapol:{}, enablePppoe:{}, defaultTechProfileId:{}," +
+                        "waitForRemoval:{}",
+                enableDhcpOnNni, enableDhcpV4, enableDhcpV6,
+                enableIgmpOnNni, enableEapol, enablePppoe,
+                defaultTechProfileId, waitForRemoval);
 
     }
 
-    protected void bindSadisService(SadisService service) {
-        sadisService = service;
-        bpService = sadisService.getBandwidthProfileService();
-        subsService = sadisService.getSubscriberInfoService();
-        log.info("Sadis-service binds to onos.");
-    }
-
-    protected void unbindSadisService(SadisService service) {
-        sadisService = null;
-        bpService = null;
-        subsService = null;
-        log.info("Sadis-service unbinds from onos.");
-    }
-
     @Override
-    public void processDhcpFilteringObjectives(AccessDevicePort port,
-                                               MeterId upstreamMeterId,
-                                               MeterId upstreamOltMeterId,
-                                               UniTagInformation tagInformation,
-                                               boolean install,
-                                               boolean upstream,
-                                               Optional<CompletableFuture<ObjectiveError>> dhcpFuture) {
-        if (upstream) {
-            // for UNI ports
-            if (tagInformation != null && !tagInformation.getIsDhcpRequired()) {
-                log.debug("Dhcp provisioning is disabled for UNI port {} for service {}",
-                        port, tagInformation.getServiceName());
-                dhcpFuture.ifPresent(f -> f.complete(null));
-                return;
-            }
-        } else {
-            // for NNI ports
-            if (!enableDhcpOnNni) {
-                log.debug("Dhcp provisioning is disabled for NNI port {}", port);
-                dhcpFuture.ifPresent(f -> f.complete(null));
-                return;
-            }
-        }
-        int techProfileId = tagInformation != null ? tagInformation.getTechnologyProfileId() : NONE_TP_ID;
-        VlanId cTag = tagInformation != null ? tagInformation.getPonCTag() : VlanId.NONE;
-        VlanId unitagMatch = tagInformation != null ? tagInformation.getUniTagMatch() : VlanId.ANY;
-        Byte vlanPcp = tagInformation != null && tagInformation.getUsPonCTagPriority() != NO_PCP
-                ? (byte) tagInformation.getUsPonCTagPriority() : null;
-
-
-        if (enableDhcpV4) {
-            int udpSrc = (upstream) ? 68 : 67;
-            int udpDst = (upstream) ? 67 : 68;
-
-            EthType ethType = EthType.EtherType.IPV4.ethType();
-            byte protocol = IPv4.PROTOCOL_UDP;
-
-            addDhcpFilteringObjectives(port, udpSrc, udpDst, ethType,
-                    upstreamMeterId, upstreamOltMeterId, techProfileId, protocol, cTag, unitagMatch,
-                    vlanPcp, upstream, install, dhcpFuture);
-        }
-
-        if (enableDhcpV6) {
-            int udpSrc = (upstream) ? 547 : 546;
-            int udpDst = (upstream) ? 546 : 547;
-
-            EthType ethType = EthType.EtherType.IPV6.ethType();
-            byte protocol = IPv6.PROTOCOL_UDP;
-
-            addDhcpFilteringObjectives(port, udpSrc, udpDst, ethType,
-                    upstreamMeterId, upstreamOltMeterId, techProfileId, protocol, cTag, unitagMatch,
-                    vlanPcp, upstream, install, dhcpFuture);
+    public ImmutableMap<ServiceKey, OltPortStatus> getConnectPointStatus() {
+        try {
+            cpStatusReadLock.lock();
+            return ImmutableMap.copyOf(cpStatus);
+        } finally {
+            cpStatusReadLock.unlock();
         }
     }
 
-    private void addDhcpFilteringObjectives(AccessDevicePort port, int udpSrc, int udpDst,
-                                            EthType ethType, MeterId upstreamMeterId, MeterId upstreamOltMeterId,
-                                            int techProfileId, byte protocol, VlanId cTag, VlanId unitagMatch,
-                                            Byte vlanPcp, boolean upstream,
-                                            boolean install, Optional<CompletableFuture<ObjectiveError>> dhcpFuture) {
+    @Override
+    public ImmutableMap<ServiceKey, UniTagInformation> getProgrammedSubscribers() {
+        // NOTE we might want to remove this conversion and directly use cpStatus as it contains
+        // all the required information about suscribers
+        Map<ServiceKey, UniTagInformation> subscribers =
+                new HashMap<>();
+        try {
+            cpStatusReadLock.lock();
+
+            cpStatus.forEach((sk, status) -> {
+                if (
+                    // not NNI Port
+                        !oltDeviceService.isNniPort(deviceService.getDevice(sk.getPort().connectPoint().deviceId()),
+                                sk.getPort().connectPoint().port()) &&
+                                // not EAPOL flow
+                                !sk.getService().equals(defaultEapolUniTag)
+                ) {
+                    subscribers.put(sk, sk.getService());
+                }
+            });
+
+            return ImmutableMap.copyOf(subscribers);
+        } finally {
+            cpStatusReadLock.unlock();
+        }
+    }
+
+    @Override
+    public Map<ServiceKey, Boolean> getRequestedSubscribers() {
+        try {
+            provisionedSubscribersReadLock.lock();
+            return ImmutableMap.copyOf(provisionedSubscribers);
+        } finally {
+            provisionedSubscribersReadLock.unlock();
+        }
+    }
+
+    @Override
+    public void handleNniFlows(Device device, Port port, FlowOperation action) {
+
+        // always handle the LLDP flow
+        processLldpFilteringObjective(device.id(), port, action);
+
+        if (enableDhcpOnNni) {
+            if (enableDhcpV4) {
+                log.debug("Installing DHCPv4 trap flow on NNI {} for device {}", portWithName(port), device.id());
+                processDhcpFilteringObjectives(device.id(), port, action, FlowDirection.DOWNSTREAM,
+                        67, 68, EthType.EtherType.IPV4.ethType(), IPv4.PROTOCOL_UDP,
+                        null, null, nniUniTag);
+            }
+            if (enableDhcpV6) {
+                log.debug("Installing DHCPv6 trap flow on NNI {} for device {}", portWithName(port), device.id());
+                processDhcpFilteringObjectives(device.id(), port, action, FlowDirection.DOWNSTREAM,
+                        546, 547, EthType.EtherType.IPV6.ethType(), IPv6.PROTOCOL_UDP,
+                        null, null, nniUniTag);
+            }
+        } else {
+            log.info("DHCP is not required on NNI {} for device {}", portWithName(port), device.id());
+        }
+
+        if (enableIgmpOnNni) {
+            log.debug("Installing IGMP flow on NNI {} for device {}", portWithName(port), device.id());
+            processIgmpFilteringObjectives(device.id(), port, action, FlowDirection.DOWNSTREAM,
+                    null, null, NONE_TP_ID, VlanId.NONE, VlanId.ANY, -1);
+        }
+
+        if (enablePppoe) {
+            log.debug("Installing PPPoE flow on NNI {} for device {}", port.number(), device.id());
+            processPPPoEDFilteringObjectives(device.id(), port, action, FlowDirection.DOWNSTREAM,
+                    null, null, NONE_TP_ID, VlanId.NONE, VlanId.ANY, null);
+        }
+    }
+
+    @Override
+    public boolean handleBasicPortFlows(DiscoveredSubscriber sub, String bandwidthProfileId,
+                                        String oltBandwidthProfileId) {
+
+        // we only need to something if EAPOL is enabled
+        if (!enableEapol) {
+            return true;
+        }
+
+        if (sub.status == DiscoveredSubscriber.Status.ADDED) {
+            return addDefaultFlows(sub, bandwidthProfileId, oltBandwidthProfileId);
+        } else if (sub.status == DiscoveredSubscriber.Status.REMOVED) {
+            return removeDefaultFlows(sub, bandwidthProfileId, oltBandwidthProfileId);
+        } else {
+            log.error("Unknown Status {} on DiscoveredSubscriber {}", sub.status, sub);
+            return false;
+        }
+
+    }
+
+    private boolean addDefaultFlows(DiscoveredSubscriber sub, String bandwidthProfileId, String oltBandwidthProfileId) {
+
+        if (!oltMeterService.createMeter(sub.device.id(), bandwidthProfileId)) {
+            if (log.isTraceEnabled()) {
+                log.trace("waiting on meter for bp {} and sub {}", bandwidthProfileId, sub);
+            }
+            return false;
+        }
+        if (hasDefaultEapol(sub.port)) {
+            return true;
+        }
+        return handleEapolFlow(sub, bandwidthProfileId,
+                oltBandwidthProfileId, FlowOperation.ADD, VlanId.vlanId(EAPOL_DEFAULT_VLAN));
+
+    }
+
+    private boolean removeDefaultFlows(DiscoveredSubscriber sub, String bandwidthProfile, String oltBandwidthProfile) {
+        // NOTE that we are not checking for meters as they must have been created to install the flow in first place
+        return handleEapolFlow(sub, bandwidthProfile, oltBandwidthProfile,
+                FlowOperation.REMOVE, VlanId.vlanId(EAPOL_DEFAULT_VLAN));
+    }
+
+    @Override
+    public boolean handleSubscriberFlows(DiscoveredSubscriber sub, String defaultBandwidthProfile,
+                                         String multicastServiceName) {
+        // NOTE that we are taking defaultBandwithProfile as a parameter as that can be configured in the Olt component
+        if (sub.status == DiscoveredSubscriber.Status.ADDED) {
+            return addSubscriberFlows(sub, defaultBandwidthProfile, multicastServiceName);
+        } else if (sub.status == DiscoveredSubscriber.Status.REMOVED) {
+            return removeSubscriberFlows(sub, defaultBandwidthProfile, multicastServiceName);
+        } else {
+            log.error("don't know how to handle {}", sub);
+            return false;
+        }
+    }
+
+    private boolean addSubscriberFlows(DiscoveredSubscriber sub, String defaultBandwithProfile,
+                                       String multicastServiceName) {
+        if (log.isTraceEnabled()) {
+            log.trace("Provisioning of subscriber on {} started", portWithName(sub.port));
+        }
+        if (enableEapol) {
+            if (hasDefaultEapol(sub.port)) {
+                // remove EAPOL flow and throw exception so that we'll retry later
+                if (!isDefaultEapolPendingRemoval(sub.port)) {
+                    removeDefaultFlows(sub, defaultBandwithProfile, defaultBandwithProfile);
+                }
+
+                if (waitForRemoval) {
+                    // NOTE wait for removal is a flag only needed to make sure VOLTHA
+                    // does not explode with the flows remove/add in the same batch
+                    log.debug("Awaiting for default flows removal for {}", portWithName(sub.port));
+                    return false;
+                } else {
+                    log.warn("continuing provisioning on {}", portWithName(sub.port));
+                }
+            }
+
+        }
+
+        // NOTE createMeters will return if the meters are not installed
+        if (!oltMeterService.createMeters(sub.device.id(),
+                sub.subscriberAndDeviceInformation)) {
+            return false;
+        }
+
+        // NOTE we need to add the DHCP flow regardless so that the host can be discovered and the MacAddress added
+        handleSubscriberDhcpFlows(sub.device.id(), sub.port, FlowOperation.ADD,
+                sub.subscriberAndDeviceInformation);
+
+        if (isMacLearningEnabled(sub.subscriberAndDeviceInformation)
+                && !isMacAddressAvailable(sub.device.id(), sub.port,
+                sub.subscriberAndDeviceInformation)) {
+            log.debug("Awaiting for macAddress on {}", portWithName(sub.port));
+            return false;
+        }
+
+        handleSubscriberDataFlows(sub.device, sub.port, FlowOperation.ADD,
+                sub.subscriberAndDeviceInformation, multicastServiceName);
+
+        handleSubscriberEapolFlows(sub, FlowOperation.ADD, sub.subscriberAndDeviceInformation);
+
+        handleSubscriberIgmpFlows(sub, FlowOperation.ADD);
+
+        log.info("Provisioning of subscriber on {} completed", portWithName(sub.port));
+        return true;
+    }
+
+    private boolean removeSubscriberFlows(DiscoveredSubscriber sub, String defaultBandwithProfile,
+                                          String multicastServiceName) {
+
+        if (log.isTraceEnabled()) {
+            log.trace("Removal of subscriber on {} started",
+                    portWithName(sub.port));
+        }
+        SubscriberAndDeviceInformation si = subsService.get(sub.portName());
+        if (si == null) {
+            log.error("Subscriber information not found in sadis for port {} during subscriber removal",
+                    portWithName(sub.port));
+            // NOTE that we are returning true so that the subscriber is removed from the queue
+            // and we can move on provisioning others
+            return true;
+        }
+
+        handleSubscriberDhcpFlows(sub.device.id(), sub.port, FlowOperation.REMOVE, si);
+
+        if (enableEapol) {
+            // remove the tagged eapol
+            handleSubscriberEapolFlows(sub, FlowOperation.REMOVE, si);
+
+            // and add the default one back
+            if (sub.port.isEnabled()) {
+                // NOTE we remove the subscriber when the port goes down
+                // but in that case we don't need to add default eapol
+                handleEapolFlow(sub, defaultBandwithProfile, defaultBandwithProfile,
+                        FlowOperation.ADD, VlanId.vlanId(EAPOL_DEFAULT_VLAN));
+            }
+        }
+        handleSubscriberDataFlows(sub.device, sub.port, FlowOperation.REMOVE, si, multicastServiceName);
+
+        handleSubscriberIgmpFlows(sub, FlowOperation.REMOVE);
+
+        // FIXME check the return status of the flow and return accordingly
+        log.info("Removal of subscriber on {} completed", portWithName(sub.port));
+        return true;
+    }
+
+    @Override
+    public boolean hasDefaultEapol(Port port) {
+        OltPortStatus status = getOltPortStatus(port, defaultEapolUniTag);
+        // NOTE we consider ERROR as a present EAPOL flow as ONOS
+        // will keep trying to add it
+        return status != null && (status.defaultEapolStatus == OltFlowsStatus.ADDED ||
+                status.defaultEapolStatus == OltFlowsStatus.PENDING_ADD ||
+                status.defaultEapolStatus == OltFlowsStatus.ERROR);
+    }
+
+    private OltPortStatus getOltPortStatus(Port port, UniTagInformation uniTagInformation) {
+        try {
+            cpStatusReadLock.lock();
+            ServiceKey sk = new ServiceKey(new AccessDevicePort(port), uniTagInformation);
+            OltPortStatus status = cpStatus.get(sk);
+            return status;
+        } finally {
+            cpStatusReadLock.unlock();
+        }
+    }
+
+    public boolean isDefaultEapolPendingRemoval(Port port) {
+        OltPortStatus status = getOltPortStatus(port, defaultEapolUniTag);
+        if (log.isTraceEnabled()) {
+            log.trace("Status during EAPOL flow check {} for port {} and UniTagInformation {}",
+                    status, portWithName(port), defaultEapolUniTag);
+        }
+        return status != null && status.defaultEapolStatus == OltFlowsStatus.PENDING_REMOVE;
+    }
+
+    @Override
+    public boolean hasDhcpFlows(Port port, UniTagInformation uti) {
+        OltPortStatus status = getOltPortStatus(port, uti);
+        if (log.isTraceEnabled()) {
+            log.trace("Status during DHCP flow check {} for port {} and service {}",
+                    status, portWithName(port), uti.getServiceName());
+        }
+        return status != null &&
+                (status.dhcpStatus == OltFlowsStatus.ADDED ||
+                        status.dhcpStatus == OltFlowsStatus.PENDING_ADD);
+    }
+
+    @Override
+    public boolean hasSubscriberFlows(Port port, UniTagInformation uti) {
+
+        OltPortStatus status = getOltPortStatus(port, uti);
+        if (log.isTraceEnabled()) {
+            log.trace("Status during subscriber flow check {} for port {} and service {}",
+                    status, portWithName(port), uti.getServiceName());
+        }
+        return status != null && (status.subscriberFlowsStatus == OltFlowsStatus.ADDED ||
+                status.subscriberFlowsStatus == OltFlowsStatus.PENDING_ADD);
+    }
+
+    @Override
+    public void purgeDeviceFlows(DeviceId deviceId) {
+        log.debug("Purging flows on device {}", deviceId);
+        flowRuleService.purgeFlowRules(deviceId);
+
+        // removing the status from the cpStatus map
+        try {
+            cpStatusWriteLock.lock();
+            Iterator<Map.Entry<ServiceKey, OltPortStatus>> iter = cpStatus.entrySet().iterator();
+            while (iter.hasNext()) {
+                Map.Entry<ServiceKey, OltPortStatus> entry = iter.next();
+                if (entry.getKey().getPort().connectPoint().deviceId().equals(deviceId)) {
+                    cpStatus.remove(entry.getKey());
+                }
+            }
+        } finally {
+            cpStatusWriteLock.unlock();
+        }
+
+        // removing subscribers from the provisioned map
+        try {
+            provisionedSubscribersWriteLock.lock();
+            Iterator<Map.Entry<ServiceKey, Boolean>> iter = provisionedSubscribers.entrySet().iterator();
+            while (iter.hasNext()) {
+                Map.Entry<ServiceKey, Boolean> entry = iter.next();
+                if (entry.getKey().getPort().connectPoint().deviceId().equals(deviceId)) {
+                    provisionedSubscribers.remove(entry.getKey());
+                }
+            }
+        } finally {
+            provisionedSubscribersWriteLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean isSubscriberServiceProvisioned(AccessDevicePort cp) {
+        // if any service is programmed on this port, returns true
+        AtomicBoolean provisioned = new AtomicBoolean(false);
+        try {
+            provisionedSubscribersReadLock.lock();
+            for (Map.Entry<ServiceKey, Boolean> entry : provisionedSubscribers.entrySet()) {
+                if (entry.getKey().getPort().equals(cp) && entry.getValue()) {
+                    provisioned.set(true);
+                    break;
+                }
+            }
+        } finally {
+            provisionedSubscribersReadLock.unlock();
+        }
+        return provisioned.get();
+    }
+
+    @Override
+    public boolean isSubscriberServiceProvisioned(ServiceKey sk) {
+        try {
+            provisionedSubscribersReadLock.lock();
+            Boolean provisioned = provisionedSubscribers.get(sk);
+            if (provisioned == null || !provisioned) {
+                return false;
+            }
+        } finally {
+            provisionedSubscribersReadLock.unlock();
+        }
+        return true;
+    }
+
+    @Override
+    public void updateProvisionedSubscriberStatus(ServiceKey sk, Boolean status) {
+        try {
+            provisionedSubscribersWriteLock.lock();
+            provisionedSubscribers.put(sk, status);
+        } finally {
+            provisionedSubscribersWriteLock.unlock();
+        }
+    }
+
+    private boolean handleEapolFlow(DiscoveredSubscriber sub, String bandwidthProfile,
+                                    String oltBandwidthProfile, FlowOperation action, VlanId vlanId) {
+
+        // create a subscriberKey for the EAPOL flow
+        ServiceKey sk = new ServiceKey(new AccessDevicePort(sub.port), defaultEapolUniTag);
+
+        // NOTE we only need to keep track of the default EAPOL flow in the
+        // connectpoint status map
+        if (vlanId.id().equals(EAPOL_DEFAULT_VLAN)) {
+            OltFlowsStatus status = action == FlowOperation.ADD ?
+                    OltFlowsStatus.PENDING_ADD : OltFlowsStatus.PENDING_REMOVE;
+            updateConnectPointStatus(sk, status, OltFlowsStatus.NONE, OltFlowsStatus.NONE);
+
+        }
+
+        DefaultFilteringObjective.Builder filterBuilder = DefaultFilteringObjective.builder();
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+
+        int techProfileId = getDefaultTechProfileId(sub.port);
+        MeterId meterId = oltMeterService.getMeterIdForBandwidthProfile(sub.device.id(), bandwidthProfile);
+
+        // in the delete case the meter should still be there as we remove
+        // the meters only if no flows are pointing to them
+        if (meterId == null) {
+            log.debug("MeterId is null for BandwidthProfile {} on device {}",
+                    bandwidthProfile, sub.device.id());
+            return false;
+        }
+
+        MeterId oltMeterId = oltMeterService.getMeterIdForBandwidthProfile(sub.device.id(), oltBandwidthProfile);
+        if (oltMeterId == null) {
+            log.debug("MeterId is null for OltBandwidthProfile {} on device {}",
+                    oltBandwidthProfile, sub.device.id());
+            return false;
+        }
+
+        log.info("{} EAPOL flow for {} with vlanId {} and BandwidthProfile {} (meterId {})",
+                flowOpToString(action), portWithName(sub.port), vlanId, bandwidthProfile, meterId);
+
+        FilteringObjective.Builder eapolAction;
+
+        if (action == FlowOperation.ADD) {
+            eapolAction = filterBuilder.permit();
+        } else if (action == FlowOperation.REMOVE) {
+            eapolAction = filterBuilder.deny();
+        } else {
+            log.error("Operation {} not supported", action);
+            return false;
+        }
+
+        FilteringObjective.Builder baseEapol = eapolAction
+                .withKey(Criteria.matchInPort(sub.port.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()));
+
+        // NOTE we only need to add the treatment to install the flow,
+        // we can remove it based in the match
+        FilteringObjective.Builder eapol;
+
+        TrafficTreatment treatment = treatmentBuilder
+                .meter(meterId)
+                .writeMetadata(createTechProfValueForWriteMetadata(
+                        vlanId,
+                        techProfileId, oltMeterId), 0)
+                .setOutput(PortNumber.CONTROLLER)
+                .pushVlan()
+                .setVlanId(vlanId)
+                .build();
+        eapol = baseEapol
+                .withMeta(treatment);
+
+        FilteringObjective eapolObjective = eapol
+                .fromApp(appId)
+                .withPriority(MAX_PRIORITY)
+                .add(new ObjectiveContext() {
+                    @Override
+                    public void onSuccess(Objective objective) {
+                        log.info("EAPOL flow objective {} for {}",
+                                completeFlowOpToString(action), portWithName(sub.port));
+                        if (log.isTraceEnabled()) {
+                            log.trace("EAPOL flow details for port {}: {}", portWithName(sub.port), objective);
+                        }
+                    }
+
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.error("Cannot {} eapol flow for {} : {}", action,
+                                portWithName(sub.port), error);
+
+                        if (vlanId.id().equals(EAPOL_DEFAULT_VLAN)) {
+                            updateConnectPointStatus(sk,
+                                    OltFlowsStatus.ERROR, null, null);
+                        }
+                    }
+                });
+
+        flowObjectiveService.filter(sub.device.id(), eapolObjective);
+
+        log.info("{} EAPOL filter for {}", completeFlowOpToString(action), portWithName(sub.port));
+        return true;
+    }
+
+    // FIXME it's confusing that si is not necessarily inside the DiscoveredSubscriber
+    private boolean handleSubscriberEapolFlows(DiscoveredSubscriber sub, FlowOperation action,
+                                               SubscriberAndDeviceInformation si) {
+        if (!enableEapol) {
+            return true;
+        }
+        // TODO verify we need an EAPOL flow for EACH service
+        AtomicBoolean success = new AtomicBoolean(true);
+        si.uniTagList().forEach(u -> {
+            // we assume that if subscriber flows are installed, tagged EAPOL is installed as well
+            boolean hasFlows = hasSubscriberFlows(sub.port, u);
+
+            // if the subscriber flows are present the EAPOL flow is present thus we don't need to install it,
+            // if the subscriber does not have flows the EAPOL flow is not present thus we don't need to remove it
+            if (action == FlowOperation.ADD && hasFlows ||
+                    action == FlowOperation.REMOVE && !hasFlows) {
+                log.debug("Not {} EAPOL on {}({}) as subscriber flow status is {}", flowOpToString(action),
+                        portWithName(sub.port), u.getServiceName(), hasFlows);
+                return;
+            }
+            log.info("{} EAPOL flows for subscriber {} on {} and service {}",
+                    flowOpToString(action), si.id(), portWithName(sub.port), u.getServiceName());
+            if (!handleEapolFlow(sub, u.getUpstreamBandwidthProfile(),
+                    u.getUpstreamOltBandwidthProfile(),
+                    action, u.getPonCTag())) {
+                //
+                log.error("Failed to {} EAPOL with suscriber tags", action);
+                //TODO this sets it for all services, maybe some services succeeded.
+                success.set(false);
+            }
+        });
+        return success.get();
+    }
+
+    private void handleSubscriberIgmpFlows(DiscoveredSubscriber sub, FlowOperation action) {
+        sub.subscriberAndDeviceInformation.uniTagList().forEach(uti -> {
+            if (uti.getIsIgmpRequired()) {
+                DeviceId deviceId = sub.device.id();
+                // if we reached here a meter already exists
+                MeterId meterId = oltMeterService
+                        .getMeterIdForBandwidthProfile(deviceId, uti.getUpstreamBandwidthProfile());
+                MeterId oltMeterId = oltMeterService
+                        .getMeterIdForBandwidthProfile(deviceId, uti.getUpstreamOltBandwidthProfile());
+
+                processIgmpFilteringObjectives(deviceId, sub.port,
+                        action, FlowDirection.UPSTREAM, meterId, oltMeterId, uti.getTechnologyProfileId(),
+                        uti.getPonCTag(), uti.getUniTagMatch(), uti.getUsPonCTagPriority());
+            }
+        });
+    }
+
+    private boolean checkSadisRunning() {
+        if (bpService == null) {
+            log.warn("Sadis is not running");
+            return false;
+        }
+        return true;
+    }
+
+    private int getDefaultTechProfileId(Port port) {
+        if (!checkSadisRunning()) {
+            return defaultTechProfileId;
+        }
+        if (port != null) {
+            SubscriberAndDeviceInformation info = subsService.get(getPortName(port));
+            if (info != null && info.uniTagList().size() == 1) {
+                return info.uniTagList().get(0).getTechnologyProfileId();
+            }
+        }
+        return defaultTechProfileId;
+    }
+
+    protected Long createTechProfValueForWriteMetadata(VlanId cVlan, int techProfileId, MeterId upstreamOltMeterId) {
+        Long writeMetadata;
+
+        if (cVlan == null || VlanId.NONE.equals(cVlan)) {
+            writeMetadata = (long) techProfileId << 32;
+        } else {
+            writeMetadata = ((long) (cVlan.id()) << 48 | (long) techProfileId << 32);
+        }
+        if (upstreamOltMeterId == null) {
+            return writeMetadata;
+        } else {
+            return writeMetadata | upstreamOltMeterId.id();
+        }
+    }
+
+    private void processLldpFilteringObjective(DeviceId deviceId, Port port, FlowOperation action) {
+        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
+
+        FilteringObjective lldp = (action == FlowOperation.ADD ? builder.permit() : builder.deny())
+                .withKey(Criteria.matchInPort(port.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.LLDP.ethType()))
+                .withMeta(DefaultTrafficTreatment.builder()
+                        .setOutput(PortNumber.CONTROLLER).build())
+                .fromApp(appId)
+                .withPriority(MAX_PRIORITY)
+                .add(new ObjectiveContext() {
+                    @Override
+                    public void onSuccess(Objective objective) {
+                        log.info("{} LLDP filter for {}.", completeFlowOpToString(action), portWithName(port));
+                    }
+
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.error("Falied to {} LLDP filter on {} because {}", action, portWithName(port),
+                                error);
+                    }
+                });
+
+        flowObjectiveService.filter(deviceId, lldp);
+    }
+
+    protected void handleSubscriberDhcpFlows(DeviceId deviceId, Port port,
+                                             FlowOperation action,
+                                             SubscriberAndDeviceInformation si) {
+        si.uniTagList().forEach(uti -> {
+
+            if (!uti.getIsDhcpRequired()) {
+                return;
+            }
+
+            // if it's an ADD skip if flows are there,
+            // if it's a DELETE skip if flows are not there
+            boolean hasFlows = hasDhcpFlows(port, uti);
+            if (action == FlowOperation.ADD && hasFlows ||
+                    action == FlowOperation.REMOVE && !hasFlows) {
+                log.debug("Not dealing with DHCP {} on {} as DHCP flow status is {}", action,
+                        uti.getServiceName(), hasFlows);
+                return;
+            }
+
+            log.info("{} DHCP flows for subscriber on {} and service {}",
+                    flowOpToString(action), portWithName(port), uti.getServiceName());
+
+            // if we reached here a meter already exists
+            MeterId meterId = oltMeterService
+                    .getMeterIdForBandwidthProfile(deviceId, uti.getUpstreamBandwidthProfile());
+            MeterId oltMeterId = oltMeterService
+                    .getMeterIdForBandwidthProfile(deviceId, uti.getUpstreamOltBandwidthProfile());
+
+            if (enableDhcpV4) {
+                processDhcpFilteringObjectives(deviceId, port, action, FlowDirection.UPSTREAM, 68, 67,
+                        EthType.EtherType.IPV4.ethType(), IPv4.PROTOCOL_UDP, meterId, oltMeterId,
+                        uti);
+            }
+            if (enableDhcpV6) {
+                log.error("DHCP V6 not supported for subscribers");
+            }
+        });
+    }
+
+    // FIXME return boolean, if this fails we need to retry
+    protected void handleSubscriberDataFlows(Device device, Port port,
+                                             FlowOperation action,
+                                             SubscriberAndDeviceInformation si, String multicastServiceName) {
+
+        Optional<Port> nniPort = oltDeviceService.getNniPort(device);
+        if (nniPort.isEmpty()) {
+            log.error("Cannot configure DP flows as upstream port is not configured for subscriber {} on {}",
+                    si.id(), portWithName(port));
+            return;
+        }
+        si.uniTagList().forEach(uti -> {
+
+            boolean hasFlows = hasSubscriberFlows(port, uti);
+            if (action == FlowOperation.ADD && hasFlows ||
+                    action == FlowOperation.REMOVE && !hasFlows) {
+                log.debug("Not dealing with DP flows {} on {} as subscriber flow status is {}", action,
+                        uti.getServiceName(), hasFlows);
+                return;
+            }
+
+            if (multicastServiceName.equals(uti.getServiceName())) {
+                log.debug("This is the multicast service ({}) for subscriber {} on {}, " +
+                                "dataplane flows are not needed",
+                        uti.getServiceName(), si.id(), portWithName(port));
+                return;
+            }
+
+            log.info("{} Data plane flows for subscriber {} on {} and service {}",
+                    flowOpToString(action), si.id(), portWithName(port), uti.getServiceName());
+
+            // upstream flows
+            MeterId usMeterId = oltMeterService
+                    .getMeterIdForBandwidthProfile(device.id(), uti.getUpstreamBandwidthProfile());
+            MeterId oltUsMeterId = oltMeterService
+                    .getMeterIdForBandwidthProfile(device.id(), uti.getUpstreamOltBandwidthProfile());
+            processUpstreamDataFilteringObjects(device.id(), port, nniPort.get(), action, usMeterId,
+                    oltUsMeterId, uti);
+
+            // downstream flows
+            MeterId dsMeterId = oltMeterService
+                    .getMeterIdForBandwidthProfile(device.id(), uti.getDownstreamBandwidthProfile());
+            MeterId oltDsMeterId = oltMeterService
+                    .getMeterIdForBandwidthProfile(device.id(), uti.getDownstreamOltBandwidthProfile());
+            processDownstreamDataFilteringObjects(device.id(), port, nniPort.get(), action, dsMeterId,
+                    oltDsMeterId, uti, getMacAddress(device.id(), port, uti));
+        });
+    }
+
+    private void processDhcpFilteringObjectives(DeviceId deviceId, Port port,
+                                                FlowOperation action, FlowDirection direction,
+                                                int udpSrc, int udpDst, EthType ethType, byte protocol,
+                                                MeterId meterId, MeterId oltMeterId, UniTagInformation uti) {
+        ServiceKey sk = new ServiceKey(new AccessDevicePort(port), uti);
+        log.debug("{} DHCP filtering objectives on {}", flowOpToString(action), sk);
+
+
+        OltFlowsStatus status = action.equals(FlowOperation.ADD) ?
+                OltFlowsStatus.PENDING_ADD : OltFlowsStatus.PENDING_REMOVE;
+        updateConnectPointStatus(sk, null, null, status);
 
         DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
         TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
 
-        if (upstreamMeterId != null) {
-            treatmentBuilder.meter(upstreamMeterId);
+        if (meterId != null) {
+            treatmentBuilder.meter(meterId);
         }
 
-        if (techProfileId != NONE_TP_ID) {
-            treatmentBuilder.writeMetadata(createTechProfValueForWm(unitagMatch, techProfileId, upstreamOltMeterId), 0);
+        if (uti.getTechnologyProfileId() != NONE_TP_ID) {
+            treatmentBuilder.writeMetadata(
+                    createTechProfValueForWriteMetadata(uti.getUniTagMatch(),
+                            uti.getTechnologyProfileId(), oltMeterId), 0);
         }
 
-        FilteringObjective.Builder dhcpUpstreamBuilder = (install ? builder.permit() : builder.deny())
+        FilteringObjective.Builder dhcpBuilder = (action == FlowOperation.ADD ? builder.permit() : builder.deny())
                 .withKey(Criteria.matchInPort(port.number()))
                 .addCondition(Criteria.matchEthType(ethType))
                 .addCondition(Criteria.matchIPProtocol(protocol))
@@ -356,87 +1065,124 @@
                 .withPriority(MAX_PRIORITY);
 
         //VLAN changes and PCP matching need to happen only in the upstream directions
-        if (upstream) {
-            treatmentBuilder.setVlanId(cTag);
-            if (!VlanId.vlanId(VlanId.NO_VID).equals(unitagMatch)) {
-                dhcpUpstreamBuilder.addCondition(Criteria.matchVlanId(unitagMatch));
+        if (direction == FlowDirection.UPSTREAM) {
+            treatmentBuilder.setVlanId(uti.getPonCTag());
+            if (!VlanId.vlanId(VlanId.NO_VID).equals(uti.getUniTagMatch())) {
+                dhcpBuilder.addCondition(Criteria.matchVlanId(uti.getUniTagMatch()));
             }
-            if (vlanPcp != null) {
-                treatmentBuilder.setVlanPcp(vlanPcp);
+            if (uti.getUsPonCTagPriority() != -1) {
+                treatmentBuilder.setVlanPcp((byte) uti.getUsPonCTagPriority());
             }
         }
 
-        dhcpUpstreamBuilder.withMeta(treatmentBuilder
-                                  .setOutput(PortNumber.CONTROLLER).build());
+        dhcpBuilder.withMeta(treatmentBuilder
+                .setOutput(PortNumber.CONTROLLER).build());
 
 
-        FilteringObjective dhcpUpstream = dhcpUpstreamBuilder.add(new ObjectiveContext() {
+        FilteringObjective dhcpUpstream = dhcpBuilder.add(new ObjectiveContext() {
             @Override
             public void onSuccess(Objective objective) {
-                log.info("DHCP {} filter for {} {}.",
-                        (ethType.equals(EthType.EtherType.IPV4.ethType())) ? V4 : V6, port,
-                        (install) ? INSTALLED : REMOVED);
-                dhcpFuture.ifPresent(f -> f.complete(null));
+                log.info("{} DHCP {} filter for {}.",
+                        completeFlowOpToString(action), (ethType.equals(EthType.EtherType.IPV4.ethType())) ? V4 : V6,
+                        portWithName(port));
             }
 
             @Override
             public void onError(Objective objective, ObjectiveError error) {
                 log.error("DHCP {} filter for {} failed {} because {}",
-                        (ethType.equals(EthType.EtherType.IPV4.ethType())) ? V4 : V6, port,
-                        (install) ? INSTALLATION : REMOVAL,
+                        (ethType.equals(EthType.EtherType.IPV4.ethType())) ? V4 : V6,
+                        portWithName(port),
+                        action,
                         error);
-                dhcpFuture.ifPresent(f -> f.complete(error));
+                updateConnectPointStatus(sk, null, null, OltFlowsStatus.ERROR);
             }
         });
-        flowObjectiveService.filter(port.deviceId(), dhcpUpstream);
+        flowObjectiveService.filter(deviceId, dhcpUpstream);
+    }
+
+    private void processIgmpFilteringObjectives(DeviceId deviceId, Port port,
+                                                FlowOperation action, FlowDirection direction,
+                                                MeterId meterId, MeterId oltMeterId, int techProfileId,
+                                                VlanId cTag, VlanId unitagMatch, int vlanPcp) {
+
+        DefaultFilteringObjective.Builder filterBuilder = DefaultFilteringObjective.builder();
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+        if (direction == FlowDirection.UPSTREAM) {
+
+            if (techProfileId != NONE_TP_ID) {
+                treatmentBuilder.writeMetadata(createTechProfValueForWriteMetadata(null,
+                        techProfileId, oltMeterId), 0);
+            }
+
+
+            if (meterId != null) {
+                treatmentBuilder.meter(meterId);
+            }
+
+            if (!VlanId.vlanId(VlanId.NO_VID).equals(unitagMatch)) {
+                filterBuilder.addCondition(Criteria.matchVlanId(unitagMatch));
+            }
+
+            if (!VlanId.vlanId(VlanId.NO_VID).equals(cTag)) {
+                treatmentBuilder.setVlanId(cTag);
+            }
+
+            if (vlanPcp != -1) {
+                treatmentBuilder.setVlanPcp((byte) vlanPcp);
+            }
+        }
+
+        filterBuilder = (action == FlowOperation.ADD) ? filterBuilder.permit() : filterBuilder.deny();
+
+        FilteringObjective igmp = filterBuilder
+                .withKey(Criteria.matchInPort(port.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
+                .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_IGMP))
+                .withMeta(treatmentBuilder
+                        .setOutput(PortNumber.CONTROLLER).build())
+                .fromApp(appId)
+                .withPriority(MAX_PRIORITY)
+                .add(new ObjectiveContext() {
+                    @Override
+                    public void onSuccess(Objective objective) {
+                        log.info("Igmp filter for {} {}.", portWithName(port), action);
+                    }
+
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.error("Igmp filter for {} failed {} because {}.", portWithName(port), action,
+                                error);
+                    }
+                });
+
+        flowObjectiveService.filter(deviceId, igmp);
 
     }
 
-    @Override
-    public void processPPPoEDFilteringObjectives(AccessDevicePort port,
-                                                 MeterId upstreamMeterId,
-                                                 MeterId upstreamOltMeterId,
-                                                 UniTagInformation tagInformation,
-                                                 boolean install,
-                                                 boolean upstream) {
-        if (!enablePppoe) {
-            log.debug("PPPoED filtering is disabled. Ignoring request.");
-            return;
-        }
-
-        int techProfileId = NONE_TP_ID;
-        VlanId cTag = VlanId.NONE;
-        VlanId unitagMatch = VlanId.ANY;
-        Byte vlanPcp = null;
-
-        if (tagInformation != null) {
-            techProfileId = tagInformation.getTechnologyProfileId();
-            cTag = tagInformation.getPonCTag();
-            unitagMatch = tagInformation.getUniTagMatch();
-            if (tagInformation.getUsPonCTagPriority() != NO_PCP) {
-                vlanPcp = (byte) tagInformation.getUsPonCTagPriority();
-            }
-        }
+    private void processPPPoEDFilteringObjectives(DeviceId deviceId, Port port,
+                                                  FlowOperation action, FlowDirection direction,
+                                                  MeterId meterId, MeterId oltMeterId, int techProfileId,
+                                                  VlanId cTag, VlanId unitagMatch, Byte vlanPcp) {
 
         DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
         TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-        CompletableFuture<Object> meterFuture = new CompletableFuture<>();
 
-        if (upstreamMeterId != null) {
-            treatmentBuilder.meter(upstreamMeterId);
+        if (meterId != null) {
+            treatmentBuilder.meter(meterId);
         }
 
         if (techProfileId != NONE_TP_ID) {
-            treatmentBuilder.writeMetadata(createTechProfValueForWm(cTag, techProfileId, upstreamOltMeterId), 0);
+            treatmentBuilder.writeMetadata(createTechProfValueForWriteMetadata(cTag, techProfileId, oltMeterId), 0);
         }
 
-        DefaultFilteringObjective.Builder pppoedBuilder = (install ? builder.permit() : builder.deny())
+        DefaultFilteringObjective.Builder pppoedBuilder = ((action == FlowOperation.ADD)
+                ? builder.permit() : builder.deny())
                 .withKey(Criteria.matchInPort(port.number()))
                 .addCondition(Criteria.matchEthType(EthType.EtherType.PPPoED.ethType()))
                 .fromApp(appId)
                 .withPriority(10000);
 
-        if (upstream) {
+        if (direction == FlowDirection.UPSTREAM) {
             treatmentBuilder.setVlanId(cTag);
             if (!VlanId.vlanId(VlanId.NO_VID).equals(unitagMatch)) {
                 pppoedBuilder.addCondition(Criteria.matchVlanId(unitagMatch));
@@ -451,398 +1197,50 @@
                 .add(new ObjectiveContext() {
                     @Override
                     public void onSuccess(Objective objective) {
-                        log.info("PPPoED filter for {} {}.", port, (install) ? INSTALLED : REMOVED);
+                        log.info("PPPoED filter for {} {}.", portWithName(port), action);
                     }
 
                     @Override
                     public void onError(Objective objective, ObjectiveError error) {
-                        log.info("PPPoED filter for {} failed {} because {}", port,
-                                (install) ? INSTALLATION : REMOVAL, error);
+                        log.info("PPPoED filter for {} failed {} because {}", portWithName(port),
+                                action, error);
                     }
                 });
-        flowObjectiveService.filter(port.deviceId(), pppoed);
+        flowObjectiveService.filter(deviceId, pppoed);
     }
 
-    @Override
-    public void processIgmpFilteringObjectives(AccessDevicePort port,
-                                               MeterId upstreamMeterId,
-                                               MeterId upstreamOltMeterId,
-                                               UniTagInformation tagInformation,
-                                               boolean install,
-                                               boolean upstream) {
-        if (upstream) {
-            // for UNI ports
-            if (tagInformation != null && !tagInformation.getIsIgmpRequired()) {
-                log.debug("Igmp provisioning is disabled for UNI port {} for service {}",
-                        port, tagInformation.getServiceName());
-                return;
-            }
-        } else {
-            // for NNI ports
-            if (!enableIgmpOnNni) {
-                log.debug("Igmp provisioning is disabled for NNI port {}", port);
-                return;
-            }
-        }
-
-        log.debug("{} IGMP flows on {}", (install) ? "Installing" : "Removing", port);
-        DefaultFilteringObjective.Builder filterBuilder = DefaultFilteringObjective.builder();
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-        if (upstream) {
-
-            if (tagInformation.getTechnologyProfileId() != NONE_TP_ID) {
-                treatmentBuilder.writeMetadata(createTechProfValueForWm(null,
-                        tagInformation.getTechnologyProfileId(), upstreamOltMeterId), 0);
-            }
-
-
-            if (upstreamMeterId != null) {
-                treatmentBuilder.meter(upstreamMeterId);
-            }
-
-            if (!VlanId.vlanId(VlanId.NO_VID).equals(tagInformation.getUniTagMatch())) {
-                filterBuilder.addCondition(Criteria.matchVlanId(tagInformation.getUniTagMatch()));
-            }
-
-            if (!VlanId.vlanId(VlanId.NO_VID).equals(tagInformation.getPonCTag())) {
-                treatmentBuilder.setVlanId(tagInformation.getPonCTag());
-            }
-
-            if (tagInformation.getUsPonCTagPriority() != NO_PCP) {
-                treatmentBuilder.setVlanPcp((byte) tagInformation.getUsPonCTagPriority());
-            }
-        }
-
-        filterBuilder = install ? filterBuilder.permit() : filterBuilder.deny();
-
-        FilteringObjective igmp = filterBuilder
-                .withKey(Criteria.matchInPort(port.number()))
-                .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
-                .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_IGMP))
-                .withMeta(treatmentBuilder
-                        .setOutput(PortNumber.CONTROLLER).build())
-                .fromApp(appId)
-                .withPriority(MAX_PRIORITY)
-                .add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        log.info("Igmp filter for {} {}.", port, (install) ? INSTALLED : REMOVED);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        log.error("Igmp filter for {} failed {} because {}.", port, (install) ? INSTALLATION : REMOVAL,
-                                error);
-                    }
-                });
-
-        flowObjectiveService.filter(port.deviceId(), igmp);
-    }
-
-    @Override
-    public void processEapolFilteringObjectives(AccessDevicePort port, String bpId, Optional<String> oltBpId,
-                                                CompletableFuture<ObjectiveError> filterFuture,
-                                                VlanId vlanId, boolean install) {
-
-        if (!enableEapol) {
-            log.debug("Eapol filtering is disabled. Completing filteringFuture immediately for the device {}",
-                    port.deviceId());
-            if (filterFuture != null) {
-                filterFuture.complete(null);
-            }
-            return;
-        }
-        log.info("Processing EAPOL with Bandwidth profile {} on {}", bpId, port);
-        BandwidthProfileInformation bpInfo = getBandwidthProfileInformation(bpId);
-        BandwidthProfileInformation oltBpInfo;
-        if (oltBpId.isPresent()) {
-            oltBpInfo = getBandwidthProfileInformation(oltBpId.get());
-        } else {
-            oltBpInfo = bpInfo;
-        }
-        if (bpInfo == null) {
-            log.warn("Bandwidth profile {} is not found. Authentication flow"
-                    + " will not be installed on {}", bpId, port);
-            if (filterFuture != null) {
-                filterFuture.complete(ObjectiveError.BADPARAMS);
-            }
-            return;
-        }
-
-        ConnectPoint cp = new ConnectPoint(port.deviceId(), port.number());
-        DefaultFilteringObjective.Builder filterBuilder = DefaultFilteringObjective.builder();
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-        // check if meter exists and create it only for an install
-        final MeterId meterId = oltMeterService.getMeterIdFromBpMapping(port.deviceId(), bpInfo.id());
-        MeterId oltMeterId = null;
-        if (oltBpId.isPresent()) {
-            oltMeterId = oltBpId.map(id -> oltMeterService.getMeterIdFromBpMapping(port.deviceId(), id)).orElse(null);
-        }
-        log.info("Meter id {} for Bandwidth profile {} and OLT meter id {} for OLT Bandwidth profile {} " +
-                        "associated to EAPOL on {}", meterId, bpInfo.id(), oltMeterId, oltBpId, port.deviceId());
-        if (meterId == null || (oltBpId.isPresent() && oltMeterId == null)) {
-            if (install) {
-                log.debug("Need to install meter for EAPOL with bwp {} on {}", bpInfo.id(), port);
-                SubscriberFlowInfo fi = new SubscriberFlowInfo(null, port,
-                                                            new UniTagInformation.Builder()
-                                                                    .setPonCTag(vlanId).build(),
-                                                        null, meterId, null, oltMeterId,
-                                                    null, bpInfo.id(), null, oltBpInfo.id());
-                pendingEapolForDevice.compute(port.deviceId(), (id, queue) -> {
-                    if (queue == null) {
-                        queue = new LinkedBlockingQueue<>();
-                    }
-                    queue.add(fi);
-                    return queue;
-                });
-
-                //If false the meter is already being installed, skipping installation
-                if (!oltMeterService.checkAndAddPendingMeter(port.deviceId(), bpInfo) &&
-                        !oltMeterService.checkAndAddPendingMeter(port.deviceId(), oltBpInfo)) {
-                    return;
-                }
-                List<BandwidthProfileInformation> bwpList = Arrays.asList(bpInfo, oltBpInfo);
-                bwpList.stream().distinct().filter(Objects::nonNull)
-                        .forEach(bwp -> createMeterAndProceedEapol(port, bwp, filterFuture, install,
-                        cp, filterBuilder, treatmentBuilder));
-            } else {
-                // this case should not happen as the request to remove an eapol
-                // flow should mean that the flow points to a meter that exists.
-                // Nevertheless we can still delete the flow as we only need the
-                // correct 'match' to do so.
-                log.warn("Unknown meter id for bp {}, still proceeding with "
-                        + "delete of eapol flow on {}", bpInfo.id(), port);
-                SubscriberFlowInfo fi = new SubscriberFlowInfo(null, port,
-                        new UniTagInformation.Builder().setPonCTag(vlanId).build(),
-                        null, meterId, null, oltMeterId, null,
-                        bpInfo.id(), null, oltBpInfo.id());
-                handleEapol(filterFuture, install, cp, filterBuilder, treatmentBuilder, fi, meterId, oltMeterId);
-            }
-        } else {
-            log.debug("Meter {} was previously created for bp {} on {}", meterId, bpInfo.id(), port);
-            SubscriberFlowInfo fi = new SubscriberFlowInfo(null, port,
-                    new UniTagInformation.Builder().setPonCTag(vlanId).build(),
-                    null, meterId, null, oltMeterId, null,
-                    bpInfo.id(), null, oltBpInfo.id());
-            handleEapol(filterFuture, install, cp, filterBuilder, treatmentBuilder, fi, meterId, oltMeterId);
-            //No need for the future, meter is present.
-            return;
-        }
-    }
-
-    private void createMeterAndProceedEapol(AccessDevicePort port, BandwidthProfileInformation bwpInfo,
-                                            CompletableFuture<ObjectiveError> filterFuture,
-                                            boolean install, ConnectPoint cp,
-                                            DefaultFilteringObjective.Builder filterBuilder,
-                                            TrafficTreatment.Builder treatmentBuilder) {
-        CompletableFuture<Object> meterFuture = new CompletableFuture<>();
-        MeterId meterId = oltMeterService.createMeter(port.deviceId(), bwpInfo, meterFuture);
-        DeviceId deviceId = port.deviceId();
-        meterFuture.thenAccept(result -> {
-            //for each pending eapol flow we check if the meter is there.
-            pendingEapolForDevice.compute(deviceId, (id, queue) -> {
-                if (queue != null && !queue.isEmpty()) {
-                    while (true) {
-                        //TODO this might return the reference and not the actual object
-                        // so it can be actually swapped underneath us.
-                        SubscriberFlowInfo fi = queue.peek();
-                        if (fi == null) {
-                            log.debug("No more subscribers eapol flows on {}", deviceId);
-                            queue = new LinkedBlockingQueue<>();
-                            break;
-                        }
-                        log.debug("handing pending eapol on {} for {}", fi.getUniPort(), fi);
-                        if (result == null) {
-                            MeterId mId = oltMeterService
-                                    .getMeterIdFromBpMapping(port.deviceId(), fi.getUpBpInfo());
-                            MeterId oltMeterId = oltMeterService
-                                    .getMeterIdFromBpMapping(port.deviceId(), fi.getUpOltBpInfo());
-                            if (mId != null && oltMeterId != null) {
-                                log.debug("Meter installation completed for subscriber on {}, " +
-                                                  "handling EAPOL trap flow", port);
-                                fi.setUpMeterId(mId);
-                                fi.setUpOltMeterId(oltMeterId);
-                                handleEapol(filterFuture, install, cp, filterBuilder, treatmentBuilder, fi,
-                                            mId, oltMeterId);
-                                queue.remove(fi);
-                            } else {
-                                log.debug("Not all meters for {} are yet installed for EAPOL meterID {}, " +
-                                                  "oltMeterId {}", fi, meterId, oltMeterId);
-                            }
-                        } else {
-                            log.warn("Meter installation error while sending EAPOL trap flow to {}. " +
-                                             "Result {} and MeterId {}", port, result, meterId);
-                            queue.remove(fi);
-                        }
-                        oltMeterService.removeFromPendingMeters(port.deviceId(), bwpInfo);
-                    }
-                } else {
-                    log.info("No pending EAPOLs on {}", port.deviceId());
-                    queue = new LinkedBlockingQueue<>();
-                }
-                return queue;
-            });
-        });
-    }
-
-    private void handleEapol(CompletableFuture<ObjectiveError> filterFuture,
-                             boolean install, ConnectPoint cp,
-                             DefaultFilteringObjective.Builder filterBuilder,
-                             TrafficTreatment.Builder treatmentBuilder,
-                             SubscriberFlowInfo fi, MeterId mId, MeterId oltMeterId) {
-        log.info("Meter {} for {} on {} exists. {} EAPOL trap flow",
-                 mId, fi.getUpBpInfo(), fi.getUniPort(),
-                 (install) ? "Installing" : "Removing");
-        int techProfileId = getDefaultTechProfileId(fi.getUniPort());
-        // can happen in case of removal
-        if (mId != null) {
-            treatmentBuilder.meter(mId);
-        }
-        //Authentication trap flow uses only tech profile id as write metadata value
-        FilteringObjective eapol = (install ? filterBuilder.permit() : filterBuilder.deny())
-                .withKey(Criteria.matchInPort(fi.getUniPort().number()))
-                .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
-                .withMeta(treatmentBuilder
-                                  .writeMetadata(createTechProfValueForWm(
-                                          fi.getTagInfo().getPonCTag(),
-                                          techProfileId, oltMeterId), 0)
-                                  .setOutput(PortNumber.CONTROLLER)
-                                  .pushVlan()
-                                  .setVlanId(fi.getTagInfo().getPonCTag())
-                                  .build())
-                .fromApp(appId)
-                .withPriority(MAX_PRIORITY)
-                .add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        log.info("Eapol filter {} for {} on {} with meter {}.",
-                                 objective.id(), (install) ? INSTALLED : REMOVED, fi.getUniPort(), mId);
-                        if (filterFuture != null) {
-                            filterFuture.complete(null);
-                        }
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        log.error("Eapol filter {} for {} with meter {} " +
-                                         "failed {} because {}", objective.id(), fi.getUniPort(), mId,
-                                 (install) ? INSTALLATION : REMOVAL,
-                                 error);
-                        if (filterFuture != null) {
-                            filterFuture.complete(error);
-                        }
-                    }
-                });
-        flowObjectiveService.filter(fi.getDevId(), eapol);
-    }
-
-    /**
-     * Installs trap filtering objectives for particular traffic types on an
-     * NNI port.
-     *
-     * @param nniPort    NNI port
-     * @param install true to install, false to remove
-     */
-    @Override
-    public void processNniFilteringObjectives(AccessDevicePort nniPort, boolean install) {
-        log.info("{} flows for NNI port {}",
-                 install ? "Adding" : "Removing", nniPort);
-        processLldpFilteringObjective(nniPort, install);
-        processDhcpFilteringObjectives(nniPort, null, null, null, install, false, Optional.empty());
-        processIgmpFilteringObjectives(nniPort, null, null, null, install, false);
-        processPPPoEDFilteringObjectives(nniPort, null, null, null, install, false);
-    }
-
-
-    @Override
-    public void processLldpFilteringObjective(AccessDevicePort port, boolean install) {
-        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
-
-        FilteringObjective lldp = (install ? builder.permit() : builder.deny())
-                .withKey(Criteria.matchInPort(port.number()))
-                .addCondition(Criteria.matchEthType(EthType.EtherType.LLDP.ethType()))
-                .withMeta(DefaultTrafficTreatment.builder()
-                        .setOutput(PortNumber.CONTROLLER).build())
-                .fromApp(appId)
-                .withPriority(MAX_PRIORITY)
-                .add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        log.info("LLDP filter for {} {}.", port, (install) ? INSTALLED : REMOVED);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        log.error("LLDP filter for {} failed {} because {}", port, (install) ? INSTALLATION : REMOVAL,
-                                error);
-                    }
-                });
-
-        flowObjectiveService.filter(port.deviceId(), lldp);
-    }
-
-    @Override
-    public ForwardingObjective.Builder createTransparentBuilder(AccessDevicePort uplinkPort,
-                                                                AccessDevicePort subscriberPort,
-                                                                MeterId meterId,
-                                                                UniTagInformation tagInfo,
-                                                                boolean upstream) {
-
+    private void processUpstreamDataFilteringObjects(DeviceId deviceId, Port port, Port nniPort,
+                                                     FlowOperation action,
+                                                     MeterId upstreamMeterId,
+                                                     MeterId upstreamOltMeterId,
+                                                     UniTagInformation uti) {
+        ServiceKey sk = new ServiceKey(new AccessDevicePort(port), uti);
         TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchVlanId(tagInfo.getPonSTag())
-                .matchInPort(upstream ? subscriberPort.number() : uplinkPort.number())
-                .matchInnerVlanId(tagInfo.getPonCTag())
-                .build();
-
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-        if (meterId != null) {
-            tBuilder.meter(meterId);
-        }
-
-        TrafficTreatment treatment = tBuilder
-                .setOutput(upstream ? uplinkPort.number() : subscriberPort.number())
-                .writeMetadata(createMetadata(upstream ? tagInfo.getPonSTag() : tagInfo.getPonCTag(),
-                        tagInfo.getTechnologyProfileId(),
-                        upstream ? uplinkPort.number() : subscriberPort.number()), 0)
-                .build();
-
-        return createForwardingObjectiveBuilder(selector, treatment, MIN_PRIORITY,
-                DefaultAnnotations.builder().build());
-    }
-
-    @Override
-    public ForwardingObjective.Builder createUpBuilder(AccessDevicePort uplinkPort,
-                                                       AccessDevicePort subscriberPort,
-                                                       MeterId upstreamMeterId,
-                                                       MeterId upstreamOltMeterId,
-                                                       UniTagInformation uniTagInformation) {
-
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchInPort(subscriberPort.number())
-                .matchVlanId(uniTagInformation.getUniTagMatch())
+                .matchInPort(port.number())
+                .matchVlanId(uti.getUniTagMatch())
                 .build();
 
         TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
         //if the subscriberVlan (cTag) is different than ANY it needs to set.
-        if (uniTagInformation.getPonCTag().toShort() != VlanId.ANY_VALUE) {
+        if (uti.getPonCTag().toShort() != VlanId.ANY_VALUE) {
             treatmentBuilder.pushVlan()
-                    .setVlanId(uniTagInformation.getPonCTag());
+                    .setVlanId(uti.getPonCTag());
         }
 
-        if (uniTagInformation.getUsPonCTagPriority() != NO_PCP) {
-            treatmentBuilder.setVlanPcp((byte) uniTagInformation.getUsPonCTagPriority());
+        if (uti.getUsPonCTagPriority() != -1) {
+            treatmentBuilder.setVlanPcp((byte) uti.getUsPonCTagPriority());
         }
 
         treatmentBuilder.pushVlan()
-                .setVlanId(uniTagInformation.getPonSTag());
+                .setVlanId(uti.getPonSTag());
 
-        if (uniTagInformation.getUsPonSTagPriority() != NO_PCP) {
-            treatmentBuilder.setVlanPcp((byte) uniTagInformation.getUsPonSTagPriority());
+        if (uti.getUsPonSTagPriority() != -1) {
+            treatmentBuilder.setVlanPcp((byte) uti.getUsPonSTagPriority());
         }
 
-        treatmentBuilder.setOutput(uplinkPort.number())
-                .writeMetadata(createMetadata(uniTagInformation.getPonCTag(),
-                        uniTagInformation.getTechnologyProfileId(), uplinkPort.number()), 0L);
+        treatmentBuilder.setOutput(nniPort.number())
+                .writeMetadata(createMetadata(uti.getPonCTag(),
+                        uti.getTechnologyProfileId(), nniPort.number()), 0L);
 
         DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
 
@@ -855,55 +1253,84 @@
             annotationBuilder.set(UPSTREAM_OLT, upstreamOltMeterId.toString());
         }
 
-        return createForwardingObjectiveBuilder(selector, treatmentBuilder.build(), MIN_PRIORITY,
+        DefaultForwardingObjective.Builder flowBuilder = createForwardingObjectiveBuilder(selector,
+                treatmentBuilder.build(), MIN_PRIORITY,
                 annotationBuilder.build());
+
+        ObjectiveContext context = new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.info("{} Upstream Data plane filter for {}.",
+                        completeFlowOpToString(action), sk);
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.error("Upstream Data plane filter for {} failed {} because {}.",
+                        sk, action, error);
+                updateConnectPointStatus(sk, null, OltFlowsStatus.ERROR, null);
+            }
+        };
+
+        ForwardingObjective flow = null;
+        if (action == FlowOperation.ADD) {
+            flow = flowBuilder.add(context);
+        } else if (action == FlowOperation.REMOVE) {
+            flow = flowBuilder.remove(context);
+        } else {
+            log.error("Flow action not supported: {}", action);
+        }
+
+        if (flow != null) {
+            flowObjectiveService.forward(deviceId, flow);
+        }
     }
 
-    @Override
-    public ForwardingObjective.Builder createDownBuilder(AccessDevicePort uplinkPort,
-                                                         AccessDevicePort subscriberPort,
-                                                         MeterId downstreamMeterId,
-                                                         MeterId downstreamOltMeterId,
-                                                         UniTagInformation tagInformation,
-                                                         Optional<MacAddress> macAddress) {
-
+    private void processDownstreamDataFilteringObjects(DeviceId deviceId, Port port, Port nniPort,
+                                                       FlowOperation action,
+                                                       MeterId downstreamMeterId,
+                                                       MeterId downstreamOltMeterId,
+                                                       UniTagInformation uti,
+                                                       MacAddress macAddress) {
+        ServiceKey sk = new ServiceKey(new AccessDevicePort(port), uti);
         //subscriberVlan can be any valid Vlan here including ANY to make sure the packet is tagged
         TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder()
-                .matchVlanId(tagInformation.getPonSTag())
-                .matchInPort(uplinkPort.number())
-                .matchInnerVlanId(tagInformation.getPonCTag());
+                .matchVlanId(uti.getPonSTag())
+                .matchInPort(nniPort.number())
+                .matchInnerVlanId(uti.getPonCTag());
 
-
-        if (tagInformation.getPonCTag().toShort() != VlanId.ANY_VALUE) {
-            selectorBuilder.matchMetadata(tagInformation.getPonCTag().toShort());
+        if (uti.getPonCTag().toShort() != VlanId.ANY_VALUE) {
+            selectorBuilder.matchMetadata(uti.getPonCTag().toShort());
         }
 
-        if (tagInformation.getDsPonSTagPriority() != NO_PCP) {
-            selectorBuilder.matchVlanPcp((byte) tagInformation.getDsPonSTagPriority());
+        if (uti.getDsPonCTagPriority() != -1) {
+            selectorBuilder.matchVlanPcp((byte) uti.getDsPonCTagPriority());
         }
 
-        macAddress.ifPresent(selectorBuilder::matchEthDst);
+        if (macAddress != null) {
+            selectorBuilder.matchEthDst(macAddress);
+        }
 
         TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder()
                 .popVlan()
-                .setOutput(subscriberPort.number());
+                .setOutput(port.number());
 
-        treatmentBuilder.writeMetadata(createMetadata(tagInformation.getPonCTag(),
-                                                      tagInformation.getTechnologyProfileId(),
-                                                      subscriberPort.number()), 0);
+        treatmentBuilder.writeMetadata(createMetadata(uti.getPonCTag(),
+                uti.getTechnologyProfileId(),
+                port.number()), 0);
 
         // Upstream pbit is used to remark inner vlan pbit.
         // Upstream is used to avoid trusting the BNG to send the packet with correct pbit.
         // this is done because ds mode 0 is used because ds mode 3 or 6 that allow for
         // all pbit acceptance are not widely supported by vendors even though present in
         // the OMCI spec.
-        if (tagInformation.getUsPonCTagPriority() != NO_PCP) {
-            treatmentBuilder.setVlanPcp((byte) tagInformation.getUsPonCTagPriority());
+        if (uti.getUsPonCTagPriority() != -1) {
+            treatmentBuilder.setVlanPcp((byte) uti.getUsPonCTagPriority());
         }
 
-        if (!VlanId.NONE.equals(tagInformation.getUniTagMatch()) &&
-                tagInformation.getPonCTag().toShort() != VlanId.ANY_VALUE) {
-            treatmentBuilder.setVlanId(tagInformation.getUniTagMatch());
+        if (!VlanId.NONE.equals(uti.getUniTagMatch()) &&
+                uti.getPonCTag().toShort() != VlanId.ANY_VALUE) {
+            treatmentBuilder.setVlanId(uti.getUniTagMatch());
         }
 
         DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
@@ -918,13 +1345,39 @@
             annotationBuilder.set(DOWNSTREAM_OLT, downstreamOltMeterId.toString());
         }
 
-        return createForwardingObjectiveBuilder(selectorBuilder.build(), treatmentBuilder.build(), MIN_PRIORITY,
-                annotationBuilder.build());
-    }
+        DefaultForwardingObjective.Builder flowBuilder = createForwardingObjectiveBuilder(selectorBuilder.build(),
+                treatmentBuilder.build(), MIN_PRIORITY, annotationBuilder.build());
 
-    @Override
-    public void clearDeviceState(DeviceId deviceId) {
-        pendingEapolForDevice.remove(deviceId);
+        ObjectiveContext context = new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.info("{} Downstream Data plane filter for {}.",
+                        completeFlowOpToString(action), sk);
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.info("Downstream Data plane filter for {} failed {} because {}.",
+                        sk, action, error);
+                updateConnectPointStatus(sk, null, OltFlowsStatus.ERROR, null);
+            }
+        };
+
+        ForwardingObjective flow = null;
+        if (action == FlowOperation.ADD) {
+            flow = flowBuilder.add(context);
+        } else if (action == FlowOperation.REMOVE) {
+            flow = flowBuilder.remove(context);
+        } else {
+            log.error("Flow action not supported: {}", action);
+        }
+
+        if (flow != null) {
+            if (log.isTraceEnabled()) {
+                log.trace("Forwarding rule {}", flow);
+            }
+            flowObjectiveService.forward(deviceId, flow);
+        }
     }
 
     private DefaultForwardingObjective.Builder createForwardingObjectiveBuilder(TrafficSelector selector,
@@ -941,70 +1394,6 @@
                 .withTreatment(treatment);
     }
 
-    /**
-     * Returns the write metadata value including tech profile reference and innerVlan.
-     * For param cVlan, null can be sent
-     *
-     * @param cVlan                 c (customer) tag of one subscriber
-     * @param techProfileId         tech profile id of one subscriber
-     * @param upstreamOltMeterId    upstream meter id for OLT device.
-     * @return the write metadata value including tech profile reference and innerVlan
-     */
-    private Long createTechProfValueForWm(VlanId cVlan, int techProfileId, MeterId upstreamOltMeterId) {
-        Long writeMetadata;
-
-        if (cVlan == null || VlanId.NONE.equals(cVlan)) {
-            writeMetadata = (long) techProfileId << 32;
-        } else {
-            writeMetadata = ((long) (cVlan.id()) << 48 | (long) techProfileId << 32);
-        }
-        if (upstreamOltMeterId == null) {
-            return writeMetadata;
-        } else {
-            return writeMetadata | upstreamOltMeterId.id();
-        }
-    }
-
-    private BandwidthProfileInformation getBandwidthProfileInformation(String bandwidthProfile) {
-        if (bpService == null) {
-            log.warn(SADIS_NOT_RUNNING);
-            return null;
-        }
-        if (bandwidthProfile == null) {
-            return null;
-        }
-        return bpService.get(bandwidthProfile);
-    }
-
-    /**
-     * It will be used to support AT&T use case (for EAPOL flows).
-     * If multiple services are found in uniServiceList, returns default tech profile id
-     * If one service is found, returns the found one
-     *
-     * @param port uni port
-     * @return the default technology profile id
-     */
-    private int getDefaultTechProfileId(AccessDevicePort port) {
-        if (subsService == null) {
-            log.warn(SADIS_NOT_RUNNING);
-            return defaultTechProfileId;
-        }
-        if (port != null) {
-            SubscriberAndDeviceInformation info = subsService.get(port.name());
-            if (info != null && info.uniTagList().size() == 1) {
-                return info.uniTagList().get(0).getTechnologyProfileId();
-            }
-        }
-        return defaultTechProfileId;
-    }
-
-    /**
-     * Write metadata instruction value (metadata) is 8 bytes.
-     * <p>
-     * MS 2 bytes: C Tag
-     * Next 2 bytes: Technology Profile Id
-     * Next 4 bytes: Port number (uni or nni)
-     */
     private Long createMetadata(VlanId innerVlan, int techProfileId, PortNumber egressPort) {
         if (techProfileId == NONE_TP_ID) {
             techProfileId = DEFAULT_TP_ID_DEFAULT;
@@ -1013,5 +1402,318 @@
         return ((long) (innerVlan.id()) << 48 | (long) techProfileId << 32) | egressPort.toLong();
     }
 
+    private boolean isMacLearningEnabled(SubscriberAndDeviceInformation si) {
+        AtomicBoolean requiresMacLearning = new AtomicBoolean();
+        requiresMacLearning.set(false);
 
+        si.uniTagList().forEach(uniTagInfo -> {
+            if (uniTagInfo.getEnableMacLearning()) {
+                requiresMacLearning.set(true);
+            }
+        });
+
+        return requiresMacLearning.get();
+    }
+
+    /**
+     * Checks whether the subscriber has the MacAddress configured or discovered.
+     *
+     * @param deviceId DeviceId for this subscriber
+     * @param port     Port for this subscriber
+     * @param si       SubscriberAndDeviceInformation
+     * @return boolean
+     */
+    protected boolean isMacAddressAvailable(DeviceId deviceId, Port port, SubscriberAndDeviceInformation si) {
+        AtomicBoolean isConfigured = new AtomicBoolean();
+        isConfigured.set(true);
+
+        si.uniTagList().forEach(uniTagInfo -> {
+            boolean isMacLearningEnabled = uniTagInfo.getEnableMacLearning();
+            boolean configureMac = isMacAddressValid(uniTagInfo);
+            boolean discoveredMac = false;
+            Optional<Host> optHost = hostService.getConnectedHosts(new ConnectPoint(deviceId, port.number()))
+                    .stream().filter(host -> host.vlan().equals(uniTagInfo.getPonCTag())).findFirst();
+            if (optHost.isPresent() && optHost.get().mac() != null) {
+                discoveredMac = true;
+            }
+            if (isMacLearningEnabled && !configureMac && !discoveredMac) {
+                log.debug("Awaiting for macAddress on {} for service {}",
+                        portWithName(port), uniTagInfo.getServiceName());
+                isConfigured.set(false);
+            }
+        });
+
+        return isConfigured.get();
+    }
+
+    protected MacAddress getMacAddress(DeviceId deviceId, Port port, UniTagInformation uniTagInfo) {
+        boolean configuredMac = isMacAddressValid(uniTagInfo);
+        if (configuredMac) {
+            return MacAddress.valueOf(uniTagInfo.getConfiguredMacAddress());
+        } else if (uniTagInfo.getEnableMacLearning()) {
+            Optional<Host> optHost = hostService.getConnectedHosts(new ConnectPoint(deviceId, port.number()))
+                    .stream().filter(host -> host.vlan().equals(uniTagInfo.getPonCTag())).findFirst();
+            if (optHost.isPresent() && optHost.get().mac() != null) {
+                return optHost.get().mac();
+            }
+        }
+        return null;
+    }
+
+    private boolean isMacAddressValid(UniTagInformation tagInformation) {
+        return tagInformation.getConfiguredMacAddress() != null &&
+                !tagInformation.getConfiguredMacAddress().trim().equals("") &&
+                !MacAddress.NONE.equals(MacAddress.valueOf(tagInformation.getConfiguredMacAddress()));
+    }
+
+    protected void updateConnectPointStatus(ServiceKey key, OltFlowsStatus eapolStatus,
+                                            OltFlowsStatus subscriberFlowsStatus, OltFlowsStatus dhcpStatus) {
+        try {
+            cpStatusWriteLock.lock();
+            OltPortStatus status = cpStatus.get(key);
+
+            if (status == null) {
+                status = new OltPortStatus(
+                        eapolStatus != null ? eapolStatus : OltFlowsStatus.NONE,
+                        subscriberFlowsStatus != null ? subscriberFlowsStatus : OltFlowsStatus.NONE,
+                        dhcpStatus != null ? dhcpStatus : OltFlowsStatus.NONE
+                );
+            } else {
+                if (eapolStatus != null) {
+                    status.defaultEapolStatus = eapolStatus;
+                }
+                if (subscriberFlowsStatus != null) {
+                    status.subscriberFlowsStatus = subscriberFlowsStatus;
+                }
+                if (dhcpStatus != null) {
+                    status.dhcpStatus = dhcpStatus;
+                }
+            }
+
+            cpStatus.put(key, status);
+        } finally {
+            cpStatusWriteLock.unlock();
+        }
+    }
+
+    protected class InternalFlowListener implements FlowRuleListener {
+        @Override
+        public void event(FlowRuleEvent event) {
+            if (appId.id() != (event.subject().appId())) {
+                return;
+            }
+
+            if (!oltDeviceService.isLocalLeader(event.subject().deviceId())) {
+                if (log.isTraceEnabled()) {
+                    log.trace("ignoring flow event {} " +
+                            "as not leader for {}", event, event.subject().deviceId());
+                }
+                return;
+            }
+
+            switch (event.type()) {
+                case RULE_ADDED:
+                case RULE_REMOVED:
+                    Port port = getCpFromFlowRule(event.subject());
+                    if (port == null) {
+                        log.error("Can't find port in flow {}", event.subject());
+                        return;
+                    }
+                    if (log.isTraceEnabled()) {
+                        log.trace("flow event {} on cp {}: {}", event.type(),
+                                portWithName(port), event.subject());
+                    }
+                    updateCpStatus(event.type(), port, event.subject());
+                    return;
+                case RULE_ADD_REQUESTED:
+                case RULE_REMOVE_REQUESTED:
+                    // NOTE that PENDING_ADD/REMOVE is set when we create the flowObjective
+                    return;
+                default:
+                    return;
+            }
+        }
+
+        protected void updateCpStatus(FlowRuleEvent.Type type, Port port, FlowRule flowRule) {
+            OltFlowsStatus status = flowRuleStatusToOltFlowStatus(type);
+            if (isDefaultEapolFlow(flowRule)) {
+                ServiceKey sk = new ServiceKey(new AccessDevicePort(port),
+                        defaultEapolUniTag);
+                if (log.isTraceEnabled()) {
+                    log.trace("update defaultEapolStatus {} on {}", status, sk);
+                }
+                updateConnectPointStatus(sk, status, null, null);
+            } else if (isDhcpFlow(flowRule)) {
+                ServiceKey sk = getSubscriberKeyFromFlowRule(flowRule);
+                if (sk == null) {
+                    return;
+                }
+                if (log.isTraceEnabled()) {
+                    log.trace("update dhcpStatus {} on {}", status, sk);
+                }
+                updateConnectPointStatus(sk, null, null, status);
+            } else if (isDataFlow(flowRule)) {
+
+                if (oltDeviceService.isNniPort(deviceService.getDevice(flowRule.deviceId()),
+                        getCpFromFlowRule(flowRule).number())) {
+                    // the NNI has data-plane for every subscriber, doesn't make sense to track them
+                    return;
+                }
+
+                ServiceKey sk = getSubscriberKeyFromFlowRule(flowRule);
+                if (sk == null) {
+                    return;
+                }
+                if (log.isTraceEnabled()) {
+                    log.trace("update dataplaneStatus {} on {}", status, sk);
+                }
+                updateConnectPointStatus(sk, null, status, null);
+            }
+        }
+
+        private boolean isDefaultEapolFlow(FlowRule flowRule) {
+            EthTypeCriterion c = (EthTypeCriterion) flowRule.selector().getCriterion(Criterion.Type.ETH_TYPE);
+            if (c == null) {
+                return false;
+            }
+            if (c.ethType().equals(EthType.EtherType.EAPOL.ethType())) {
+                AtomicBoolean isDefault = new AtomicBoolean(false);
+                flowRule.treatment().allInstructions().forEach(instruction -> {
+                    if (instruction.type() == L2MODIFICATION) {
+                        L2ModificationInstruction modificationInstruction = (L2ModificationInstruction) instruction;
+                        if (modificationInstruction.subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
+                            L2ModificationInstruction.ModVlanIdInstruction vlanInstruction =
+                                    (L2ModificationInstruction.ModVlanIdInstruction) modificationInstruction;
+                            if (vlanInstruction.vlanId().id().equals(EAPOL_DEFAULT_VLAN)) {
+                                isDefault.set(true);
+                                return;
+                            }
+                        }
+                    }
+                });
+                return isDefault.get();
+            }
+            return false;
+        }
+
+        /**
+         * Returns true if the flow is a DHCP flow.
+         * Matches both upstream and downstream flows.
+         *
+         * @param flowRule The FlowRule to evaluate
+         * @return boolean
+         */
+        private boolean isDhcpFlow(FlowRule flowRule) {
+            IPProtocolCriterion ipCriterion = (IPProtocolCriterion) flowRule.selector()
+                    .getCriterion(Criterion.Type.IP_PROTO);
+            if (ipCriterion == null) {
+                return false;
+            }
+
+            UdpPortCriterion src = (UdpPortCriterion) flowRule.selector().getCriterion(Criterion.Type.UDP_SRC);
+
+            if (src == null) {
+                return false;
+            }
+            return ipCriterion.protocol() == IPv4.PROTOCOL_UDP &&
+                    (src.udpPort().toInt() == 68 || src.udpPort().toInt() == 67);
+        }
+
+        private boolean isDataFlow(FlowRule flowRule) {
+            // we consider subscriber flows the one that matches on VLAN_VID
+            // method is valid only because it's the last check after EAPOL and DHCP.
+            // this matches mcast flows as well, if we want to avoid that we can
+            // filter out the elements that have groups in the treatment or
+            // mcastIp in the selector
+            // IPV4_DST:224.0.0.22/32
+            // treatment=[immediate=[GROUP:0x1]]
+
+            return flowRule.selector().getCriterion(Criterion.Type.VLAN_VID) != null;
+        }
+
+        private Port getCpFromFlowRule(FlowRule flowRule) {
+            DeviceId deviceId = flowRule.deviceId();
+            PortCriterion inPort = (PortCriterion) flowRule.selector().getCriterion(Criterion.Type.IN_PORT);
+            if (inPort != null) {
+                PortNumber port = inPort.port();
+                return deviceService.getPort(deviceId, port);
+            }
+            return null;
+        }
+
+        private ServiceKey getSubscriberKeyFromFlowRule(FlowRule flowRule) {
+            Port flowPort = getCpFromFlowRule(flowRule);
+            SubscriberAndDeviceInformation si = subsService.get(getPortName(flowPort));
+
+            Boolean isNni = oltDeviceService.isNniPort(deviceService.getDevice(flowRule.deviceId()), flowPort.number());
+            if (si == null && !isNni) {
+                log.error("Subscriber information not found in sadis for port {}", portWithName(flowPort));
+                return null;
+            }
+
+            if (isNni) {
+                return new ServiceKey(new AccessDevicePort(flowPort), nniUniTag);
+            }
+
+            Optional<UniTagInformation> found = Optional.empty();
+            VlanId flowVlan = null;
+            if (isDhcpFlow(flowRule)) {
+                // we need to make a special case for DHCP as in the ATT workflow DHCP flows don't match on tags
+                L2ModificationInstruction.ModVlanIdInstruction instruction =
+                        (L2ModificationInstruction.ModVlanIdInstruction) flowRule.treatment().immediate().get(1);
+                flowVlan = instruction.vlanId();
+            } else {
+                // for now we assume that if it's not DHCP it's dataplane (or at least tagged)
+                VlanIdCriterion vlanIdCriterion =
+                        (VlanIdCriterion) flowRule.selector().getCriterion(Criterion.Type.VLAN_VID);
+                if (vlanIdCriterion == null) {
+                    log.warn("cannot match the flow to a subscriber service as it does not carry vlans");
+                    return null;
+                }
+                flowVlan = vlanIdCriterion.vlanId();
+            }
+
+            VlanId finalFlowVlan = flowVlan;
+            found = si.uniTagList().stream().filter(uti ->
+                    uti.getPonCTag().equals(finalFlowVlan) ||
+                            uti.getPonSTag().equals(finalFlowVlan) ||
+                            uti.getUniTagMatch().equals(finalFlowVlan)
+            ).findFirst();
+
+
+            if (found.isEmpty()) {
+                log.warn("Cannot map flow rule {} to Service in {}", flowRule, si);
+            }
+
+            return found.isPresent() ? new ServiceKey(new AccessDevicePort(flowPort), found.get()) : null;
+
+        }
+
+        private OltFlowsStatus flowRuleStatusToOltFlowStatus(FlowRuleEvent.Type type) {
+            switch (type) {
+                case RULE_ADD_REQUESTED:
+                    return OltFlowsStatus.PENDING_ADD;
+                case RULE_ADDED:
+                    return OltFlowsStatus.ADDED;
+                case RULE_REMOVE_REQUESTED:
+                    return OltFlowsStatus.PENDING_REMOVE;
+                case RULE_REMOVED:
+                    return OltFlowsStatus.REMOVED;
+                default:
+                    return OltFlowsStatus.NONE;
+            }
+        }
+    }
+
+    protected void bindSadisService(SadisService service) {
+        this.subsService = service.getSubscriberInfoService();
+        this.bpService = service.getBandwidthProfileService();
+        log.info("Sadis service is loaded");
+    }
+
+    protected void unbindSadisService(SadisService service) {
+        this.subsService = null;
+        this.bpService = null;
+        log.info("Sadis service is unloaded");
+    }
 }
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltFlowServiceInterface.java b/impl/src/main/java/org/opencord/olt/impl/OltFlowServiceInterface.java
new file mode 100644
index 0000000..e55c789
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/OltFlowServiceInterface.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.opencord.sadis.UniTagInformation;
+
+import java.util.Map;
+
+/**
+ * Interface for flow installation/removal methods for different types of traffic.
+ */
+public interface OltFlowServiceInterface {
+    /**
+     * Installs or removes default flows for the port to trap to controller.
+     * @param sub the information about the port
+     * @param defaultBpId the default bandwidth profile
+     * @param oltBandwidthProfile the olt bandwidth profile.
+     * @return true if successful
+     */
+    boolean handleBasicPortFlows(
+            DiscoveredSubscriber sub, String defaultBpId, String oltBandwidthProfile);
+
+    /**
+     * Installs or removes subscriber specific flows.
+     * @param sub the information about the subscriber
+     * @param defaultBpId the default bandwidth profile
+     * @param multicastServiceName the multicast service name.
+     * @return true if successful
+     */
+    boolean handleSubscriberFlows(DiscoveredSubscriber sub, String defaultBpId, String multicastServiceName);
+
+    /**
+     * Installs or removes flows on the NNI port.
+     * @param device the OLT
+     * @param port the NNI port
+     * @param action the operatio, ADD or REMOVE.
+     */
+    void handleNniFlows(Device device, Port port, OltFlowService.FlowOperation action);
+
+    /**
+     * Checks if the default eapol flow is already installed.
+     * @param port the port
+     * @return true if installed, false otherwise.
+     */
+    boolean hasDefaultEapol(Port port);
+
+    /**
+     * Checks if the dhcp flows are installed.
+     * @param port the port
+     * @param uti the UniTagInformation to check for
+     * @return true if installed, false otherwise.
+     */
+    boolean hasDhcpFlows(Port port, UniTagInformation uti);
+
+    /**
+     * Checks if the subscriber flows are installed.
+     * @param port the port
+     * @param uti the UniTagInformation to check for
+     * @return true if installed, false otherwise.
+     */
+    boolean hasSubscriberFlows(Port port, UniTagInformation uti);
+
+    /**
+     * Removes all device flows.
+     * @param deviceId the olt.
+     */
+    void purgeDeviceFlows(DeviceId deviceId);
+
+    /**
+     * Return the status of installation on the connect points.
+     * @return the status map
+     */
+    Map<ServiceKey, OltPortStatus> getConnectPointStatus();
+
+    /**
+     * Returns all the programmed subscribers.
+     * @return the subscribers
+     */
+    Map<ServiceKey, UniTagInformation> getProgrammedSubscribers();
+
+    /**
+     * Returns the list of requested subscribers to be installed with status.
+     * @return the list
+     */
+    Map<ServiceKey, Boolean> getRequestedSubscribers();
+
+    /**
+     * Returns if a subscriber on a port is provisioned or not.
+     * @param cp the port
+     * @return true if any service on that port is provisioned, false otherwise
+     */
+    boolean isSubscriberServiceProvisioned(AccessDevicePort cp);
+
+    /**
+     * Returns if a subscriber on a port is provisioned or not.
+     * @param sk the SubscriberKey
+     * @return true if provisioned, false otherwise
+     */
+    boolean isSubscriberServiceProvisioned(ServiceKey sk);
+
+    /**
+     * Updates the subscriber provisioning status.
+     * @param sk the SubscriberKey
+     * @param status the next status
+     */
+    void updateProvisionedSubscriberStatus(ServiceKey sk, Boolean status);
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltMeterService.java b/impl/src/main/java/org/opencord/olt/impl/OltMeterService.java
index 4b88344..be04449 100644
--- a/impl/src/main/java/org/opencord/olt/impl/OltMeterService.java
+++ b/impl/src/main/java/org/opencord/olt/impl/OltMeterService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,47 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.opencord.olt.impl;
 
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static java.util.stream.Collectors.collectingAndThen;
-import static java.util.stream.Collectors.groupingBy;
-import static java.util.stream.Collectors.mapping;
-import static java.util.stream.Collectors.toSet;
-import static org.onlab.util.Tools.get;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.opencord.olt.impl.OsgiPropertyConstants.*;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.stream.Collectors;
-
+import com.google.common.collect.ImmutableMap;
 import org.onlab.util.KryoNamespace;
 import org.onlab.util.Tools;
 import org.onosproject.cfg.ComponentConfigService;
-import org.onosproject.cluster.ClusterService;
-import org.onosproject.cluster.LeadershipService;
-import org.onosproject.cluster.NodeId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
-import org.onosproject.mastership.MastershipService;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.meter.Band;
 import org.onosproject.net.meter.DefaultBand;
 import org.onosproject.net.meter.DefaultMeterRequest;
@@ -66,12 +35,14 @@
 import org.onosproject.net.meter.MeterListener;
 import org.onosproject.net.meter.MeterRequest;
 import org.onosproject.net.meter.MeterService;
+import org.onosproject.net.meter.MeterState;
 import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.ConsistentMultimap;
 import org.onosproject.store.service.Serializer;
 import org.onosproject.store.service.StorageService;
-import org.opencord.olt.internalapi.AccessDeviceMeterService;
 import org.opencord.sadis.BandwidthProfileInformation;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -79,219 +50,386 @@
 import org.osgi.service.component.annotations.Modified;
 import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
 import org.slf4j.Logger;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
-/**
- * Provisions Meters on access devices.
- */
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.onlab.util.Tools.get;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.opencord.olt.impl.OsgiPropertyConstants.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
 @Component(immediate = true, property = {
         DELETE_METERS + ":Boolean=" + DELETE_METERS_DEFAULT,
         ZERO_REFERENCE_METER_COUNT + ":Integer=" + ZERO_REFERENCE_METER_COUNT_DEFAULT,
-        })
-public class OltMeterService implements AccessDeviceMeterService {
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected MeterService meterService;
+})
+public class OltMeterService implements OltMeterServiceInterface {
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected CoreService coreService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected ComponentConfigService componentConfigService;
+    protected ComponentConfigService cfgService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected StorageService storageService;
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected DeviceService deviceService;
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL,
+            bind = "bindSadisService",
+            unbind = "unbindSadisService",
+            policy = ReferencePolicy.DYNAMIC)
+    protected volatile SadisService sadisService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected ClusterService clusterService;
+    protected MeterService meterService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected MastershipService mastershipService;
+    protected OltDeviceServiceInterface oltDeviceService;
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected LeadershipService leadershipService;
+    private final Logger log = getLogger(getClass());
+    protected BaseInformationService<BandwidthProfileInformation> bpService;
+    private ApplicationId appId;
+    private static final String APP_NAME = "org.opencord.olt";
+    private final ReentrantReadWriteLock programmedMeterLock = new ReentrantReadWriteLock();
+    private final Lock programmedMeterWriteLock = programmedMeterLock.writeLock();
+    private final Lock programmedMeterReadLock = programmedMeterLock.readLock();
+
+    /**
+     * Programmed Meters status map.
+     * Keeps track of which meter is programmed on which device for which BandwidthProfile.
+     * The String key is the BandwidthProfile
+     */
+    protected Map<DeviceId, Map<String, MeterData>> programmedMeters;
+
+    private final MeterListener meterListener = new InternalMeterListener();
+    protected ExecutorService pendingRemovalMetersExecutor =
+            Executors.newFixedThreadPool(5, groupedThreads("onos/olt",
+                                                           "pending-removal-meters-%d", log));
+
+    /**
+     * Map that contains a list of meters that needs to be removed.
+     * We wait to get 3 METER_REFERENCE_COUNT_ZERO events before removing the meter
+     * so that we're sure no flow is referencing it.
+     */
+    protected Map<DeviceId, Map<MeterKey, AtomicInteger>> pendingRemoveMeters;
+
+    /**
+     * Number of consecutive meter events with empty reference count
+     * after which a meter gets removed from the device.
+     */
+    protected int zeroReferenceMeterCount = 3;
 
     /**
      * Delete meters when reference count drops to zero.
      */
     protected boolean deleteMeters = DELETE_METERS_DEFAULT;
 
-    /**
-     * Number of Zero References received before deleting the meter.
-     */
-    protected int zeroReferenceMeterCount = ZERO_REFERENCE_METER_COUNT_DEFAULT;
-
-    private ApplicationId appId;
-    private static final String APP_NAME = "org.opencord.olt";
-
-    private final MeterListener meterListener = new InternalMeterListener();
-
-    private final Logger log = getLogger(getClass());
-
-    protected ExecutorService eventExecutor;
-
-    protected Map<DeviceId, Set<BandwidthProfileInformation>> pendingMeters;
-    protected Map<DeviceId, Map<MeterKey, AtomicInteger>> pendingRemoveMeters;
-    protected ConsistentMultimap<String, MeterKey> bpInfoToMeter;
-
     @Activate
     public void activate(ComponentContext context) {
-        eventExecutor = Executors.newFixedThreadPool(5, groupedThreads("onos/olt",
-                "events-%d", log));
         appId = coreService.registerApplication(APP_NAME);
         modified(context);
-
         KryoNamespace serializer = KryoNamespace.newBuilder()
                 .register(KryoNamespaces.API)
+                .register(List.class)
+                .register(MeterData.class)
+                .register(MeterState.class)
                 .register(MeterKey.class)
-                .register(BandwidthProfileInformation.class)
                 .build();
 
-        bpInfoToMeter = storageService.<String, MeterKey>consistentMultimapBuilder()
-                .withName("volt-bp-info-to-meter")
-                .withSerializer(Serializer.using(serializer))
-                .withApplicationId(appId)
-                .build();
-
-        meterService.addListener(meterListener);
-        componentConfigService.registerProperties(getClass());
-        pendingMeters = storageService.<DeviceId, Set<BandwidthProfileInformation>>consistentMapBuilder()
-                .withName("volt-pending-meters")
+        programmedMeters = storageService.<DeviceId, Map<String, MeterData>>consistentMapBuilder()
+                .withName("volt-programmed-meters")
                 .withSerializer(Serializer.using(serializer))
                 .withApplicationId(appId)
                 .build().asJavaMap();
+
         pendingRemoveMeters = storageService.<DeviceId, Map<MeterKey, AtomicInteger>>consistentMapBuilder()
                 .withName("volt-pending-remove-meters")
                 .withSerializer(Serializer.using(serializer))
                 .withApplicationId(appId)
                 .build().asJavaMap();
-        log.info("Olt Meter service started");
-    }
 
-    @Deactivate
-    public void deactivate() {
-        meterService.removeListener(meterListener);
-    }
+        cfgService.registerProperties(getClass());
 
+        meterService.addListener(meterListener);
+
+        log.info("Started");
+    }
 
     @Modified
     public void modified(ComponentContext context) {
         Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
 
-        Boolean d = Tools.isPropertyEnabled(properties, "deleteMeters");
+        Boolean d = Tools.isPropertyEnabled(properties, DELETE_METERS);
         if (d != null) {
             deleteMeters = d;
         }
 
-        String zeroReferenceMeterCountNew = get(properties, ZERO_REFERENCE_METER_COUNT);
-        zeroReferenceMeterCount = isNullOrEmpty(zeroReferenceMeterCountNew) ? ZERO_REFERENCE_METER_COUNT_DEFAULT :
-                Integer.parseInt(zeroReferenceMeterCountNew.trim());
+        String zeroCount = get(properties, ZERO_REFERENCE_METER_COUNT);
+        int oldSubscriberProcessingThreads = zeroReferenceMeterCount;
+        zeroReferenceMeterCount = isNullOrEmpty(zeroCount) ?
+                oldSubscriberProcessingThreads : Integer.parseInt(zeroCount.trim());
 
+        log.info("Modified. Values = deleteMeters: {}, zeroReferenceMeterCount: {}",
+                 deleteMeters, zeroReferenceMeterCount);
+    }
+
+    @Deactivate
+    public void deactivate(ComponentContext context) {
+        cfgService.unregisterProperties(getClass(), false);
+        meterService.removeListener(meterListener);
+        log.info("Stopped");
     }
 
     @Override
-    public ImmutableMap<String, Collection<MeterKey>> getBpMeterMappings() {
-        return bpInfoToMeter.stream()
-                .collect(collectingAndThen(
-                        groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toSet())),
-                        ImmutableMap::copyOf));
+    public Map<DeviceId, Map<String, MeterData>> getProgrammedMeters() {
+        try {
+            programmedMeterReadLock.lock();
+            return ImmutableMap.copyOf(programmedMeters);
+        } finally {
+            programmedMeterReadLock.unlock();
+        }
     }
 
-    boolean addMeterIdToBpMapping(DeviceId deviceId, MeterId meterId, String bandwidthProfile) {
-        log.debug("adding bp {} to meter {} mapping for device {}",
-                 bandwidthProfile, meterId, deviceId);
-        return bpInfoToMeter.put(bandwidthProfile, MeterKey.key(deviceId, meterId));
+    /**
+     * Will create a meter if needed and return true once available.
+     *
+     * @param deviceId         DeviceId
+     * @param bandwidthProfile Bandwidth Profile Id
+     * @return true
+     */
+    @Override
+    public synchronized boolean createMeter(DeviceId deviceId, String bandwidthProfile) {
+
+        // NOTE it is possible that hasMeterByBandwidthProfile returns false has the meter is in PENDING_ADD
+        // then a different thread changes the meter to ADDED
+        // and thus hasPendingMeterByBandwidthProfile return false as well and we install the meter a second time
+        // this causes an inconsistency between the existing meter and meterId stored in the map
+
+        if (!hasMeterByBandwidthProfile(deviceId, bandwidthProfile)) {
+            // NOTE this is at trace level as it's constantly called by the queue processor
+            if (log.isTraceEnabled()) {
+                log.trace("Missing meter for BandwidthProfile {} on device {}", bandwidthProfile, deviceId);
+            }
+
+            if (!hasPendingMeterByBandwidthProfile(deviceId, bandwidthProfile)) {
+                createMeterForBp(deviceId, bandwidthProfile);
+            }
+            if (log.isTraceEnabled()) {
+                log.trace("Meter is not yet available for {} on device {}",
+                          bandwidthProfile, deviceId);
+            }
+            return false;
+        }
+        log.debug("Meter found for BandwidthProfile {} on device {}", bandwidthProfile, deviceId);
+        return true;
     }
 
     @Override
-    public MeterId getMeterIdFromBpMapping(DeviceId deviceId, String bandwidthProfile) {
-        if (bandwidthProfile == null) {
-            log.warn("Bandwidth Profile requested is null");
-            return null;
+    public boolean createMeters(DeviceId deviceId, SubscriberAndDeviceInformation si) {
+        // Each UniTagInformation has up to 4 meters,
+        // check and/or create all of them
+        AtomicBoolean waitingOnMeter = new AtomicBoolean();
+        waitingOnMeter.set(false);
+        Map<String, List<String>> pendingMeters = new HashMap<>();
+        si.uniTagList().forEach(uniTagInfo -> {
+            String serviceName = uniTagInfo.getServiceName();
+            pendingMeters.put(serviceName, new LinkedList<>());
+            String usBp = uniTagInfo.getUpstreamBandwidthProfile();
+            String dsBp = uniTagInfo.getDownstreamBandwidthProfile();
+            String oltUBp = uniTagInfo.getDownstreamOltBandwidthProfile();
+            String oltDsBp = uniTagInfo.getUpstreamOltBandwidthProfile();
+            if (!createMeter(deviceId, usBp)) {
+                pendingMeters.get(serviceName).add(usBp);
+                waitingOnMeter.set(true);
+            }
+            if (!createMeter(deviceId, dsBp)) {
+                pendingMeters.get(serviceName).add(usBp);
+                waitingOnMeter.set(true);
+            }
+            if (!createMeter(deviceId, oltUBp)) {
+                pendingMeters.get(serviceName).add(usBp);
+                waitingOnMeter.set(true);
+            }
+            if (!createMeter(deviceId, oltDsBp)) {
+                pendingMeters.get(serviceName).add(usBp);
+                waitingOnMeter.set(true);
+            }
+        });
+        if (waitingOnMeter.get()) {
+            if (log.isTraceEnabled()) {
+                log.trace("Meters {} on device {} are not " +
+                                  "installed yet (requested by subscriber {})",
+                          pendingMeters, deviceId, si.id());
+            }
+            return false;
         }
-        if (bpInfoToMeter.get(bandwidthProfile) == null) {
-            log.warn("Bandwidth Profile '{}' is not present in the map",
-                     bandwidthProfile);
-            return null;
-        }
-        if (bpInfoToMeter.get(bandwidthProfile).value().isEmpty()) {
-            log.warn("Bandwidth Profile '{}' is not currently mapped to a meter",
-                    bandwidthProfile);
-            return null;
-        }
+        return true;
+    }
 
-        Optional<? extends MeterKey> meterKeyForDevice = bpInfoToMeter.get(bandwidthProfile).value()
-                .stream()
-                .filter(meterKey -> meterKey.deviceId().equals(deviceId))
-                .findFirst();
-        if (meterKeyForDevice.isPresent()) {
-            log.debug("Found meter {} for bandwidth profile {} on {}",
-                    meterKeyForDevice.get().meterId(), bandwidthProfile, deviceId);
-            return meterKeyForDevice.get().meterId();
-        } else {
-            log.warn("Bandwidth Profile '{}' is not currently mapped to a meter on {} , {}",
-                     bandwidthProfile, deviceId, bpInfoToMeter.get(bandwidthProfile).value());
-            return null;
+    /**
+     * Returns true if a meter is present in the programmed meters map, only if status is ADDED.
+     *
+     * @param deviceId         the DeviceId on which to look for the meter
+     * @param bandwidthProfile the Bandwidth profile associated with this meter
+     * @return true if the meter is found
+     */
+    public boolean hasMeterByBandwidthProfile(DeviceId deviceId, String bandwidthProfile) {
+        try {
+            programmedMeterReadLock.lock();
+            Map<String, MeterData> metersOnDevice = programmedMeters.get(deviceId);
+            if (metersOnDevice == null || metersOnDevice.isEmpty()) {
+                return false;
+            }
+            if (log.isTraceEnabled()) {
+                log.trace("added metersOnDevice {}: {}", deviceId, metersOnDevice);
+            }
+            return metersOnDevice.get(bandwidthProfile) != null &&
+                    metersOnDevice.get(bandwidthProfile).getMeterStatus().equals(MeterState.ADDED);
+        } finally {
+            programmedMeterReadLock.unlock();
+        }
+    }
+
+    public boolean hasPendingMeterByBandwidthProfile(DeviceId deviceId, String bandwidthProfile) {
+        try {
+            programmedMeterReadLock.lock();
+            Map<String, MeterData> metersOnDevice = programmedMeters.get(deviceId);
+            if (metersOnDevice == null || metersOnDevice.isEmpty()) {
+                return false;
+            }
+            if (log.isTraceEnabled()) {
+                log.trace("pending metersOnDevice {}: {}", deviceId, metersOnDevice);
+            }
+            // NOTE that we check in order if the meter was ADDED and if it wasn't we check for PENDING_ADD
+            // it is possible that a different thread move the meter state from PENDING_ADD
+            // to ADDED between these two checks
+            // to avoid creating the meter twice we return true event if the meter is already added
+            return metersOnDevice.get(bandwidthProfile) != null && (
+                    metersOnDevice.get(bandwidthProfile).getMeterStatus().equals(MeterState.ADDED) ||
+                            metersOnDevice.get(bandwidthProfile).getMeterStatus().equals(MeterState.PENDING_ADD)
+            );
+
+        } finally {
+            programmedMeterReadLock.unlock();
+        }
+    }
+
+    public MeterId getMeterIdForBandwidthProfile(DeviceId deviceId, String bandwidthProfile) {
+        try {
+            programmedMeterReadLock.lock();
+            Map<String, MeterData> metersOnDevice = programmedMeters.get(deviceId);
+            if (metersOnDevice == null || metersOnDevice.isEmpty()) {
+                return null;
+            }
+            MeterData meterData = metersOnDevice.get(bandwidthProfile);
+            if (meterData == null || meterData.getMeterStatus() != MeterState.ADDED) {
+                return null;
+            }
+            if (log.isTraceEnabled()) {
+                log.debug("Found meter {} on device {} for bandwidth profile {}",
+                        meterData.getMeterId(), deviceId, bandwidthProfile);
+            }
+            return meterData.getMeterId();
+        } finally {
+            programmedMeterReadLock.unlock();
         }
     }
 
     @Override
-    public ImmutableSet<MeterKey> getProgMeters() {
-        return bpInfoToMeter.stream()
-                .map(Map.Entry::getValue)
-                .collect(ImmutableSet.toImmutableSet());
+    public void purgeDeviceMeters(DeviceId deviceId) {
+        log.debug("Purging meters on device {}", deviceId);
+        meterService.purgeMeters(deviceId);
+
+        // after we purge the meters we also need to clear the map
+        try {
+            programmedMeterWriteLock.lock();
+            programmedMeters.remove(deviceId);
+        } finally {
+            programmedMeterWriteLock.unlock();
+        }
+
+        // and clear the event count
+        // NOTE do we need a lock?
+        pendingRemoveMeters.remove(deviceId);
     }
 
-    @Override
-    public MeterId createMeter(DeviceId deviceId, BandwidthProfileInformation bpInfo,
-                               CompletableFuture<Object> meterFuture) {
-        log.debug("Creating meter on {} for {}", deviceId, bpInfo);
+    /**
+     * Creates of a meter for a given Bandwidth Profile on a given device.
+     *
+     * @param deviceId         the DeviceId
+     * @param bandwidthProfile the BandwidthProfile ID
+     */
+    public void createMeterForBp(DeviceId deviceId, String bandwidthProfile) {
+        // adding meter in pending state to the programmedMeter map
+        try {
+            programmedMeterWriteLock.lock();
+            programmedMeters.compute(deviceId, (d, deviceMeters) -> {
+
+                if (deviceMeters == null) {
+                    deviceMeters = new HashMap<>();
+                }
+                // NOTE that this method is only called after verifying a
+                // meter for this BP does not already exist
+                MeterData meterData = new MeterData(
+                        null,
+                        MeterState.PENDING_ADD,
+                        bandwidthProfile
+                );
+                deviceMeters.put(bandwidthProfile, meterData);
+
+                return deviceMeters;
+            });
+        } finally {
+            programmedMeterWriteLock.unlock();
+        }
+
+        BandwidthProfileInformation bpInfo = getBandwidthProfileInformation(bandwidthProfile);
         if (bpInfo == null) {
-            log.warn("Requested bandwidth profile on {} information is NULL", deviceId);
-            meterFuture.complete(ObjectiveError.BADPARAMS);
-            return null;
+            log.error("BandwidthProfile {} information not found in sadis", bandwidthProfile);
+            return;
         }
 
-        MeterId meterId = getMeterIdFromBpMapping(deviceId, bpInfo.id());
-        if (meterId != null) {
-            log.debug("Meter {} was previously created for bp {}", meterId, bpInfo.id());
-            meterFuture.complete(null);
-            return meterId;
+        log.info("Creating meter for BandwidthProfile {} on device {}", bpInfo.id(), deviceId);
+
+        if (log.isTraceEnabled()) {
+            log.trace("BandwidthProfile: {}", bpInfo);
         }
 
         List<Band> meterBands = createMeterBands(bpInfo);
 
-        final AtomicReference<MeterId> meterIdRef = new AtomicReference<>();
+        CompletableFuture<Object> meterFuture = new CompletableFuture<>();
+
         MeterRequest meterRequest = DefaultMeterRequest.builder()
                 .withBands(meterBands)
                 .withUnit(Meter.Unit.KB_PER_SEC)
                 .withContext(new MeterContext() {
                     @Override
                     public void onSuccess(MeterRequest op) {
-                        log.debug("Meter {} for {} is installed on the device {}",
-                                  meterIdRef.get(), bpInfo.id(), deviceId);
-                        boolean added = addMeterIdToBpMapping(deviceId, meterIdRef.get(), bpInfo.id());
-                        if (added) {
-                            meterFuture.complete(null);
-                        } else {
-                            log.error("Failed to add Meter {} for {} on {} to the meter-bandwidth mapping",
-                                      meterIdRef.get(), bpInfo.id(), deviceId);
-                            meterFuture.complete(ObjectiveError.UNKNOWN);
-                        }
+                        log.info("Meter for BandwidthProfile {} is installed on the device {}",
+                                 bandwidthProfile, deviceId);
+                        meterFuture.complete(null);
                     }
 
                     @Override
                     public void onError(MeterRequest op, MeterFailReason reason) {
-                        log.error("Failed installing meter {} on {} for {}",
-                                  meterIdRef.get(), deviceId, bpInfo.id());
-                        bpInfoToMeter.remove(bpInfo.id(),
-                                             MeterKey.key(deviceId, meterIdRef.get()));
+                        log.error("Failed installing meter on {} for {}",
+                                  deviceId, bandwidthProfile);
                         meterFuture.complete(reason);
                     }
                 })
@@ -300,63 +438,34 @@
                 .burst()
                 .add();
 
+        // creating the meter
         Meter meter = meterService.submit(meterRequest);
-        meterIdRef.set(meter.id());
-        log.info("Meter {} created and sent for installation on {} for {}",
-                 meter.id(), deviceId, bpInfo);
-        return meter.id();
-    }
 
-    @Override
-    public void removeFromPendingMeters(DeviceId deviceId, BandwidthProfileInformation bwpInfo) {
-        if (deviceId == null) {
-            return;
-        }
-        pendingMeters.computeIfPresent(deviceId, (id, bwps) -> {
-            bwps.remove(bwpInfo);
-            return bwps;
-        });
-    }
-
-    @Override
-    public synchronized boolean checkAndAddPendingMeter(DeviceId deviceId, BandwidthProfileInformation bwpInfo) {
-        if (bwpInfo == null) {
-            log.debug("Bandwidth profile is null for device: {}", deviceId);
-            return false;
-        }
-        if (pendingMeters.containsKey(deviceId)
-                && pendingMeters.get(deviceId).contains(bwpInfo)) {
-            log.debug("Meter is already pending on {} with bp {}",
-                      deviceId, bwpInfo);
-            return false;
-        }
-        log.debug("Adding bandwidth profile {} to pending on {}",
-                  bwpInfo, deviceId);
-        pendingMeters.compute(deviceId, (id, bwps) -> {
-            if (bwps == null) {
-                bwps = new HashSet<>();
+        // wait for the meter to be completed
+        meterFuture.thenAccept(error -> {
+            if (error != null) {
+                log.error("Cannot create meter, TODO address me");
             }
-            bwps.add(bwpInfo);
-            return bwps;
+
+            // then update the map with the MeterId
+            try {
+                programmedMeterWriteLock.lock();
+                programmedMeters.compute(deviceId, (d, entry) -> {
+                    if (entry != null) {
+                        entry.compute(bandwidthProfile, (bp, meterData) -> {
+                            if (meterData != null) {
+                                meterData.setMeterCellId(meter.meterCellId());
+                                meterData.setMeterStatus(MeterState.ADDED);
+                            }
+                            return meterData;
+                        });
+                    }
+                    return entry;
+                });
+            } finally {
+                programmedMeterWriteLock.unlock();
+            }
         });
-
-        return true;
-    }
-
-    @Override
-    public void clearMeters(DeviceId deviceId) {
-        log.debug("Removing all meters for device {}", deviceId);
-        clearDeviceState(deviceId);
-        meterService.purgeMeters(deviceId);
-    }
-
-    @Override
-    public void clearDeviceState(DeviceId deviceId) {
-        log.info("Clearing local device state for {}", deviceId);
-        pendingRemoveMeters.remove(deviceId);
-        removeMetersFromBpMapping(deviceId);
-        //Following call handles cornercase of OLT delete during meter provisioning
-        pendingMeters.remove(deviceId);
     }
 
     private List<Band> createMeterBands(BandwidthProfileInformation bpInfo) {
@@ -408,119 +517,137 @@
                 .build();
     }
 
-    private void removeMeterFromBpMapping(MeterKey meterKey) {
-        List<Map.Entry<String, MeterKey>> meters = bpInfoToMeter.stream()
-                .filter(e -> e.getValue().equals(meterKey))
-                .collect(Collectors.toList());
-
-        meters.forEach(e -> bpInfoToMeter.remove(e.getKey(), e.getValue()));
-    }
-
-    private void removeMetersFromBpMapping(DeviceId deviceId) {
-        List<Map.Entry<String, MeterKey>> meters = bpInfoToMeter.stream()
-                .filter(e -> e.getValue().deviceId().equals(deviceId))
-                .collect(Collectors.toList());
-
-        meters.forEach(e -> bpInfoToMeter.remove(e.getKey(), e.getValue()));
-    }
-
-    /**
-     * Checks for mastership or falls back to leadership on deviceId.
-     * If the device is available use mastership,
-     * otherwise fallback on leadership.
-     * Leadership on the device topic is needed because the master can be NONE
-     * in case the device went away, we still need to handle events
-     * consistently
-     */
-    private boolean isLocalLeader(DeviceId deviceId) {
-        if (deviceService.isAvailable(deviceId)) {
-            return mastershipService.isLocalMaster(deviceId);
-        } else {
-            // Fallback with Leadership service - device id is used as topic
-            NodeId leader = leadershipService.runForLeadership(
-                    deviceId.toString()).leaderNodeId();
-            // Verify if this node is the leader
-            return clusterService.getLocalNode().id().equals(leader);
+    private BandwidthProfileInformation getBandwidthProfileInformation(String bandwidthProfile) {
+        if (!checkSadisRunning()) {
+            return null;
         }
+        if (bandwidthProfile == null) {
+            return null;
+        }
+        return bpService.get(bandwidthProfile);
+    }
+
+    private boolean checkSadisRunning() {
+        if (bpService == null) {
+            log.warn("Sadis is not running");
+            return false;
+        }
+        return true;
     }
 
     private class InternalMeterListener implements MeterListener {
-
         @Override
         public void event(MeterEvent meterEvent) {
-            eventExecutor.execute(() -> {
+            pendingRemovalMetersExecutor.execute(() -> {
+
                 Meter meter = meterEvent.subject();
-                if (meter == null) {
-                    log.error("Meter in event {} is null", meterEvent);
+                if (!appId.equals(meter.appId())) {
                     return;
                 }
-                if (isLocalLeader(meter.deviceId())) {
-                    MeterKey key = MeterKey.key(meter.deviceId(), meter.id());
-                    if (deleteMeters &&
-                            MeterEvent.Type.METER_REFERENCE_COUNT_ZERO.equals(meterEvent.type())) {
-                        log.info("Zero Count Meter Event is received. Meter is {} on {}",
-                                 meter.id(), meter.deviceId());
-                        incrementMeterCount(meter.deviceId(), key);
 
-                        if (appId.equals(meter.appId()) && pendingRemoveMeters.get(meter.deviceId())
-                                .get(key).get() == zeroReferenceMeterCount) {
-                            log.info("Deleting unreferenced, no longer programmed Meter {} on {}",
-                                     meter.id(), meter.deviceId());
+                if (log.isTraceEnabled()) {
+                    log.trace("Received meter event {}", meterEvent);
+                }
+                MeterKey key = MeterKey.key(meter.deviceId(), meter.id());
+                if (meterEvent.type().equals(MeterEvent.Type.METER_REFERENCE_COUNT_ZERO)) {
+                    if (!oltDeviceService.isLocalLeader(meter.deviceId())) {
+                        if (log.isTraceEnabled()) {
+                            log.trace("ignoring meter event {} " +
+                                    "as not leader for {}", meterEvent, meter.deviceId());
+                        }
+                        return;
+                    }
+                    log.info("Zero Count Reference event is received for meter {} on {}, " +
+                                     "incrementing counter",
+                             meter.id(), meter.deviceId());
+                    incrementMeterCount(meter.deviceId(), key);
+                    if (pendingRemoveMeters.get(meter.deviceId())
+                            .get(key).get() == zeroReferenceMeterCount) {
+                        // only delete the meters if the app is configured to do so
+                        if (deleteMeters) {
+                            log.info("Meter {} on device {} is unused, removing it", meter.id(), meter.deviceId());
                             deleteMeter(meter.deviceId(), meter.id());
                         }
                     }
-                    if (MeterEvent.Type.METER_REMOVED.equals(meterEvent.type())) {
-                        log.info("Meter Removed Event is received for {} on {}",
-                                 meter.id(), meter.deviceId());
-                        pendingRemoveMeters.computeIfPresent(meter.deviceId(),
-                                                             (id, meters) -> {
-                                                                 if (meters.get(key) == null) {
-                                                                     log.info("Meters is not pending " +
-                                                                                      "{} on {}", key, id);
-                                                                     return meters;
-                                                                 }
-                                                                 meters.remove(key);
-                                                                 return meters;
-                                                             });
-                        removeMeterFromBpMapping(key);
-                    }
-                } else {
-                    log.trace("Ignoring meter event, not leader of {}, {}", meter.deviceId(), meterEvent);
+                }
+
+                if (meterEvent.type().equals(MeterEvent.Type.METER_REMOVED)) {
+                    removeMeterCount(meter, key);
                 }
             });
         }
 
+        private void removeMeterCount(Meter meter, MeterKey key) {
+            pendingRemoveMeters.computeIfPresent(meter.deviceId(),
+                                                 (id, meters) -> {
+                                                     if (meters.get(key) == null) {
+                                                         log.info("Meters is not pending " +
+                                                                          "{} on {}", key, id);
+                                                         return meters;
+                                                     }
+                                                     meters.remove(key);
+                                                     return meters;
+                                                 });
+        }
+
         private void incrementMeterCount(DeviceId deviceId, MeterKey key) {
             if (key == null) {
                 return;
             }
             pendingRemoveMeters.compute(deviceId,
-                    (id, meters) -> {
-                        if (meters == null) {
-                            meters = new HashMap<>();
+                                        (id, meters) -> {
+                                            if (meters == null) {
+                                                meters = new HashMap<>();
 
-                        }
-                        if (meters.get(key) == null) {
-                            meters.put(key, new AtomicInteger(1));
-                        }
-                        meters.get(key).addAndGet(1);
-                        return meters;
-                    });
+                                            }
+                                            if (meters.get(key) == null) {
+                                                meters.put(key, new AtomicInteger(1));
+                                            }
+                                            meters.get(key).addAndGet(1);
+                                            return meters;
+                                        });
+        }
+    }
+
+    private void deleteMeter(DeviceId deviceId, MeterId meterId) {
+        Meter meter = meterService.getMeter(deviceId, meterId);
+        if (meter != null) {
+            MeterRequest meterRequest = DefaultMeterRequest.builder()
+                    .withBands(meter.bands())
+                    .withUnit(meter.unit())
+                    .forDevice(deviceId)
+                    .fromApp(appId)
+                    .burst()
+                    .remove();
+
+            meterService.withdraw(meterRequest, meterId);
         }
 
-        private void deleteMeter(DeviceId deviceId, MeterId meterId) {
-            Meter meter = meterService.getMeter(deviceId, meterId);
-            if (meter != null) {
-                MeterRequest meterRequest = DefaultMeterRequest.builder()
-                        .withBands(meter.bands())
-                        .withUnit(meter.unit())
-                        .forDevice(deviceId)
-                        .fromApp(appId)
-                        .burst()
-                        .remove();
-
-                meterService.withdraw(meterRequest, meterId);
-            }
+        // remove the meter from local caching
+        try {
+            programmedMeterWriteLock.lock();
+            programmedMeters.computeIfPresent(deviceId, (d, deviceMeters) -> {
+                Iterator<Map.Entry<String, MeterData>> iter = deviceMeters.entrySet().iterator();
+                while (iter.hasNext()) {
+                    Map.Entry<String, MeterData> entry = iter.next();
+                    if (entry.getValue().getMeterId().equals(meterId)) {
+                        deviceMeters.remove(entry.getKey());
+                    }
+                }
+                return deviceMeters;
+            });
+        } finally {
+            programmedMeterWriteLock.unlock();
         }
     }
+
+    protected void bindSadisService(SadisService service) {
+        this.bpService = service.getBandwidthProfileService();
+        log.info("Sadis service is loaded");
+    }
+
+    protected void unbindSadisService(SadisService service) {
+        this.bpService = null;
+        log.info("Sadis service is unloaded");
+    }
 }
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltMeterServiceInterface.java b/impl/src/main/java/org/opencord/olt/impl/OltMeterServiceInterface.java
new file mode 100644
index 0000000..a10455b
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/OltMeterServiceInterface.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.MeterId;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+
+import java.util.Map;
+
+/**
+ * Interface for meter installation/removal methods
+ * for different types of bandwidth profiles.
+ */
+public interface OltMeterServiceInterface {
+    /**
+     * Checks for a meter, if not present it will create it and return false.
+     * @param deviceId DeviceId
+     * @param bandwidthProfile Bandwidth Profile Id
+     * @return boolean
+     */
+    boolean createMeter(DeviceId deviceId, String bandwidthProfile);
+
+    /**
+     * Checks for all the meters specified in the sadis uniTagList,
+     * if not present it will create them and return false.
+     * @param deviceId DeviceId
+     * @param si SubscriberAndDeviceInformation
+     * @return boolean
+     */
+    boolean createMeters(DeviceId deviceId, SubscriberAndDeviceInformation si);
+
+    /**
+     * Checks if a meter for the specified bandwidthProfile exists
+     * and is in ADDED state.
+     * @param deviceId DeviceId
+     * @param bandwidthProfileId bandwidth profile id
+     * @return true if present and in ADDED state
+     */
+    boolean hasMeterByBandwidthProfile(DeviceId deviceId, String bandwidthProfileId);
+
+    /**
+     * Checks if a meter for the specified bandwidthProfile exists
+     * and is in PENDING_ADD state.
+     * @param deviceId DeviceId
+     * @param bandwidthProfileId bandwidth profile id
+     * @return true if present and in PENDING_ADD state
+     */
+    boolean hasPendingMeterByBandwidthProfile(DeviceId deviceId, String bandwidthProfileId);
+
+    /**
+     * Creates a meter on a device for the given BandwidthProfile Id.
+     * @param deviceId the device id
+     * @param bandwidthProfileId the bandwidth profile Id
+     */
+    void createMeterForBp(DeviceId deviceId, String bandwidthProfileId);
+
+    /**
+     * Returns the meter Id for a given bandwidth profile Id.
+     * @param deviceId the device id
+     * @param bandwidthProfileId the bandwidth profile Id
+     * @return the meter Id
+     */
+    MeterId getMeterIdForBandwidthProfile(DeviceId deviceId, String bandwidthProfileId);
+
+    /**
+     * Purges all the meters on a device.
+     * @param deviceId the device
+     */
+    void purgeDeviceMeters(DeviceId deviceId);
+
+    /**
+     * Return all programmed meters for all OLTs controlled by this ONOS cluster.
+     * @return a map, with the device keys, and entry of map with bp Id and corresponding meter
+     */
+    Map<DeviceId, Map<String, MeterData>> getProgrammedMeters();
+
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltPortStatus.java b/impl/src/main/java/org/opencord/olt/impl/OltPortStatus.java
new file mode 100644
index 0000000..655a0ac
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/OltPortStatus.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import java.util.Objects;
+
+/**
+ * OltPortStatus is used to keep track of the flow status for a subscriber service.
+ */
+public class OltPortStatus {
+    // TODO consider adding a lastUpdated field, it may help with debugging
+    public OltFlowService.OltFlowsStatus defaultEapolStatus;
+    public OltFlowService.OltFlowsStatus subscriberFlowsStatus;
+    // NOTE we need to keep track of the DHCP status as that is installed before the other flows
+    // if macLearning is enabled (DHCP is needed to learn the MacAddress from the host)
+    public OltFlowService.OltFlowsStatus dhcpStatus;
+
+    public OltPortStatus(OltFlowService.OltFlowsStatus defaultEapolStatus,
+                         OltFlowService.OltFlowsStatus subscriberFlowsStatus,
+                         OltFlowService.OltFlowsStatus dhcpStatus) {
+        this.defaultEapolStatus = defaultEapolStatus;
+        this.subscriberFlowsStatus = subscriberFlowsStatus;
+        this.dhcpStatus = dhcpStatus;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        OltPortStatus that = (OltPortStatus) o;
+        return defaultEapolStatus == that.defaultEapolStatus
+                && subscriberFlowsStatus == that.subscriberFlowsStatus
+                && dhcpStatus == that.dhcpStatus;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(defaultEapolStatus, subscriberFlowsStatus, dhcpStatus);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("OltPortStatus{");
+        sb.append("defaultEapolStatus=").append(defaultEapolStatus);
+        sb.append(", subscriberFlowsStatus=").append(subscriberFlowsStatus);
+        sb.append(", dhcpStatus=").append(dhcpStatus);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltUtils.java b/impl/src/main/java/org/opencord/olt/impl/OltUtils.java
new file mode 100644
index 0000000..6300ff9
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/OltUtils.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Port;
+
+import static org.opencord.olt.impl.OltFlowService.FlowOperation.ADD;
+
+/**
+ * Utility class for OLT app.
+ */
+final class OltUtils {
+
+    private OltUtils() {
+    }
+
+    /**
+     * Returns the port name if present in the annotations.
+     * @param port the port
+     * @return the annotated port name
+     */
+    static String getPortName(Port port) {
+        String name = port.annotations().value(AnnotationKeys.PORT_NAME);
+        return name == null ? "" : name;
+    }
+
+    /**
+     * Returns a port printed as a connect point and with the name appended.
+     * @param port the port
+     * @return the formatted string
+     */
+    static String portWithName(Port port) {
+        return port.element().id().toString() + '/' +
+                port.number() + '[' +
+                getPortName(port) + ']';
+    }
+
+    static String flowOpToString(OltFlowService.FlowOperation op) {
+        return op == ADD ? "Adding" : "Removing";
+    }
+
+    static String completeFlowOpToString(OltFlowService.FlowOperation op) {
+        return op == ADD ? "Added" : "Removed";
+    }
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/OsgiPropertyConstants.java b/impl/src/main/java/org/opencord/olt/impl/OsgiPropertyConstants.java
index 3657436..a73a42b 100644
--- a/impl/src/main/java/org/opencord/olt/impl/OsgiPropertyConstants.java
+++ b/impl/src/main/java/org/opencord/olt/impl/OsgiPropertyConstants.java
@@ -58,15 +58,21 @@
     public static final String ENABLE_PPPOE = "enablePppoe";
     public static final boolean ENABLE_PPPOE_DEFAULT = false;
 
-    public static final String EAPOL_DELETE_RETRY_MAX_ATTEMPS = "eapolDeleteRetryMaxAttempts";
-    public static final int EAPOL_DELETE_RETRY_MAX_ATTEMPS_DEFAULT = 3;
-
-    public static final String PROVISION_DELAY = "provisionDelay";
-    public static final int PROVISION_DELAY_DEFAULT = 100;
+    public static final String WAIT_FOR_REMOVAL = "waitForRemoval";
+    public static final boolean WAIT_FOR_REMOVAL_DEFAULT = true;
 
     public static final String REQUIRED_DRIVERS_PROPERTY_DELAY = "requiredDriversPropertyDelay";
     public static final int REQUIRED_DRIVERS_PROPERTY_DELAY_DEFAULT = 5;
 
+    public static final String FLOW_PROCESSING_THREADS = "flowProcessingThreads";
+    public static final int FLOW_PROCESSING_THREADS_DEFAULT = 8;
+
+    public static final String SUBSCRIBER_PROCESSING_THREADS = "subscriberProcessingThreads";
+    public static final int SUBSCRIBER_PROCESSING_THREADS_DEFAULT = 8;
+
+    public static final String REQUEUE_DELAY = "requeueDelay";
+    public static final int REQUEUE_DELAY_DEFAULT = 500;
+
     public static final String UPSTREAM_ONU = "upstreamOnu";
     public static final String UPSTREAM_OLT = "upstreamOlt";
     public static final String DOWNSTREAM_ONU = "downstreamOnu";
diff --git a/impl/src/main/java/org/opencord/olt/impl/ServiceKey.java b/impl/src/main/java/org/opencord/olt/impl/ServiceKey.java
new file mode 100644
index 0000000..c878062
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/ServiceKey.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.opencord.sadis.UniTagInformation;
+
+import java.util.Objects;
+
+/**
+ * SubscriberKey is used to identify the combination of a subscriber and a service.
+ */
+public class ServiceKey {
+    private AccessDevicePort port;
+    private UniTagInformation service;
+
+    public ServiceKey(AccessDevicePort port, UniTagInformation service) {
+        this.port = port;
+        this.service = service;
+    }
+
+    public AccessDevicePort getPort() {
+        return port;
+    }
+
+    public void setPort(AccessDevicePort port) {
+        this.port = port;
+    }
+
+    public UniTagInformation getService() {
+        return service;
+    }
+
+    public void setService(UniTagInformation service) {
+        this.service = service;
+    }
+
+    @Override
+    public String toString() {
+        return this.port.toString() + " - " + this.service.getServiceName();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        ServiceKey that = (ServiceKey) o;
+        boolean isPortEqual = Objects.equals(port, that.port);
+        boolean isServiceEqual = Objects.equals(service, that.service);
+
+        return isPortEqual && isServiceEqual;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(port, service);
+    }
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/ServiceKeySerializer.java b/impl/src/main/java/org/opencord/olt/impl/ServiceKeySerializer.java
new file mode 100644
index 0000000..4035bdd
--- /dev/null
+++ b/impl/src/main/java/org/opencord/olt/impl/ServiceKeySerializer.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+import com.esotericsoftware.kryo.Serializer;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.opencord.sadis.UniTagInformation;
+
+/**
+ * ServiceKeySerializer is a custom serializer to store a ServiceKey in an Atomix ditributed map.
+ */
+class ServiceKeySerializer extends Serializer<ServiceKey> {
+
+    ServiceKeySerializer() {
+        // non-null, immutable
+        super(false, true);
+    }
+
+    @Override
+    public void write(Kryo kryo, Output output, ServiceKey object) {
+        kryo.writeClassAndObject(output, object.getPort().connectPoint().port());
+        output.writeString(object.getPort().name());
+        output.writeString(object.getPort().connectPoint().deviceId().toString());
+        kryo.writeClassAndObject(output, object.getService());
+    }
+
+    @Override
+    public ServiceKey read(Kryo kryo, Input input, Class<ServiceKey> type) {
+        PortNumber port = (PortNumber) kryo.readClassAndObject(input);
+        final String portName = input.readString();
+        final String devId = input.readString();
+
+        UniTagInformation uti = (UniTagInformation) kryo.readClassAndObject(input);
+        ConnectPoint cp = new ConnectPoint(DeviceId.deviceId(devId), port);
+        AccessDevicePort adp = new AccessDevicePort(cp, portName);
+
+        return new ServiceKey(adp, uti);
+    }
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/SubscriberFlowInfo.java b/impl/src/main/java/org/opencord/olt/impl/SubscriberFlowInfo.java
deleted file mode 100644
index 225e48f..0000000
--- a/impl/src/main/java/org/opencord/olt/impl/SubscriberFlowInfo.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright 2020-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.opencord.olt.impl;
-
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.meter.MeterId;
-import org.opencord.olt.AccessDevicePort;
-import org.opencord.sadis.UniTagInformation;
-
-import java.util.Objects;
-
-/**
- * Contains the mapping of a given port to flow information, including bandwidth profile.
- */
-class SubscriberFlowInfo {
-    private final DeviceId devId;
-    private final AccessDevicePort nniPort;
-    private final AccessDevicePort uniPort;
-    private final UniTagInformation tagInfo;
-    private MeterId downId;
-    private MeterId upId;
-    private MeterId downOltId;
-    private MeterId upOltId;
-    private final String downBpInfo;
-    private final String upBpInfo;
-    private final String downOltBpInfo;
-    private final String upOltBpInfo;
-
-    /**
-     * Builds the mapper of information.
-     * @param nniPort       the nni port
-     * @param uniPort       the uni port
-     * @param tagInfo       the tag info
-     * @param downId        the downstream meter id
-     * @param upId          the upstream meter id
-     * @param downOltId     the downstream meter id of OLT device
-     * @param upOltId       the upstream meter id of OLT device
-     * @param downBpInfo    the downstream bandwidth profile
-     * @param upBpInfo      the upstream bandwidth profile
-     * @param downOltBpInfo the downstream bandwidth profile of OLT device
-     * @param upOltBpInfo   the upstream bandwidth profile of OLT device
-     */
-    SubscriberFlowInfo(AccessDevicePort nniPort, AccessDevicePort uniPort,
-                       UniTagInformation tagInfo, MeterId downId, MeterId upId,
-                       MeterId downOltId, MeterId upOltId,
-                       String downBpInfo, String upBpInfo,
-                       String downOltBpInfo, String upOltBpInfo) {
-        this.devId = uniPort.deviceId();
-        this.nniPort = nniPort;
-        this.uniPort = uniPort;
-        this.tagInfo = tagInfo;
-        this.downId = downId;
-        this.upId = upId;
-        this.downOltId = downOltId;
-        this.upOltId = upOltId;
-        this.downBpInfo = downBpInfo;
-        this.upBpInfo = upBpInfo;
-        this.downOltBpInfo = downOltBpInfo;
-        this.upOltBpInfo = upOltBpInfo;
-    }
-
-    /**
-     * Gets the device id of this subscriber and flow information.
-     *
-     * @return device id
-     */
-    DeviceId getDevId() {
-        return devId;
-    }
-
-    /**
-     * Gets the nni of this subscriber and flow information.
-     *
-     * @return nni port
-     */
-    AccessDevicePort getNniPort() {
-        return nniPort;
-    }
-
-    /**
-     * Gets the uni port of this subscriber and flow information.
-     *
-     * @return uni port
-     */
-    AccessDevicePort getUniPort() {
-        return uniPort;
-    }
-
-    /**
-     * Gets the tag of this subscriber and flow information.
-     *
-     * @return tag of the subscriber
-     */
-    UniTagInformation getTagInfo() {
-        return tagInfo;
-    }
-
-    /**
-     * Gets the downstream meter id of this subscriber and flow information.
-     *
-     * @return downstream meter id
-     */
-    MeterId getDownId() {
-        return downId;
-    }
-
-    /**
-     * Gets the upstream meter id of this subscriber and flow information.
-     *
-     * @return upstream meter id
-     */
-    MeterId getUpId() {
-        return upId;
-    }
-
-    /**
-     * Gets the downstream meter id of this subscriber and flow information of OLT device.
-     *
-     * @return downstream olt meter id
-     */
-    MeterId getDownOltId() {
-        return downOltId;
-    }
-
-    /**
-     * Gets the upstream meter id of this subscriber and flow information of OLT device.
-     *
-     * @return upstream olt meter id
-     */
-    MeterId getUpOltId() {
-        return upOltId;
-    }
-
-    /**
-     * Gets the downstream bandwidth profile of this subscriber and flow information.
-     *
-     * @return downstream bandwidth profile
-     */
-    String getDownBpInfo() {
-        return downBpInfo;
-    }
-
-    /**
-     * Gets the upstream bandwidth profile of this subscriber and flow information.
-     *
-     * @return upstream bandwidth profile.
-     */
-    String getUpBpInfo() {
-        return upBpInfo;
-    }
-
-    /**
-     * Gets the downstream bandwidth profile of this subscriber and flow information of OLT device.
-     *
-     * @return downstream OLT bandwidth profile
-     */
-    String getDownOltBpInfo() {
-        return downOltBpInfo;
-    }
-
-    /**
-     * Gets the upstream bandwidth profile of this subscriber and flow information of OLT device.
-     *
-     * @return upstream OLT bandwidth profile.
-     */
-    String getUpOltBpInfo() {
-        return upOltBpInfo;
-    }
-
-    /**
-     * Sets the upstream meter id.
-     *
-     * @param upMeterId the upstream meter id
-     */
-    void setUpMeterId(MeterId upMeterId) {
-        this.upId = upMeterId;
-    }
-
-    /**
-     * Sets the downstream meter id.
-     *
-     * @param downMeterId the downstream meter id
-     */
-    void setDownMeterId(MeterId downMeterId) {
-        this.downId = downMeterId;
-    }
-
-    /**
-     * Sets the upstream meter id of OLT.
-     *
-     * @param upOltMeterId the upstream meter id of OLT
-     */
-    void setUpOltMeterId(MeterId upOltMeterId) {
-        this.upOltId = upOltMeterId;
-    }
-
-    /**
-     * Sets the downstream meter id of OLT.
-     *
-     * @param downOltMeterId the downstream meter id of OLT
-     */
-    void setDownOltMeterId(MeterId downOltMeterId) {
-        this.downOltId = downOltMeterId;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        SubscriberFlowInfo flowInfo = (SubscriberFlowInfo) o;
-        return devId.equals(flowInfo.devId) &&
-                nniPort.equals(flowInfo.nniPort) &&
-                uniPort.equals(flowInfo.uniPort) &&
-                tagInfo.equals(flowInfo.tagInfo) &&
-                downBpInfo.equals(flowInfo.downBpInfo) &&
-                upBpInfo.equals(flowInfo.upBpInfo) &&
-                Objects.equals(downOltBpInfo, flowInfo.downOltBpInfo) &&
-                Objects.equals(upOltBpInfo, flowInfo.upOltBpInfo);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(devId, nniPort, uniPort, tagInfo, downBpInfo, upBpInfo, downOltBpInfo, upOltBpInfo);
-    }
-
-    @Override
-    public String toString() {
-        return com.google.common.base.MoreObjects.toStringHelper(this)
-                .add("devId", devId)
-                .add("nniPort", nniPort)
-                .add("uniPort", uniPort)
-                .add("tagInfo", tagInfo)
-                .add("downId", downId)
-                .add("upId", upId)
-                .add("downOltId", downOltId)
-                .add("upOltId", upOltId)
-                .add("downBpInfo", downBpInfo)
-                .add("upBpInfo", upBpInfo)
-                .add("downOltBpInfo", downOltBpInfo)
-                .add("upOltBpInfo", upOltBpInfo)
-                .toString();
-    }
-}
diff --git a/impl/src/main/java/org/opencord/olt/impl/package-info.java b/impl/src/main/java/org/opencord/olt/impl/package-info.java
index b5ba320..ccdfda7 100644
--- a/impl/src/main/java/org/opencord/olt/impl/package-info.java
+++ b/impl/src/main/java/org/opencord/olt/impl/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,6 +15,6 @@
  */
 
 /**
- * OLT application handling PMC OLT hardware.
+ * ONOS application archetype.
  */
-package org.opencord.olt.impl;
+package org.opencord.olt.impl;
\ No newline at end of file
diff --git a/impl/src/main/java/org/opencord/olt/internalapi/AccessDeviceFlowService.java b/impl/src/main/java/org/opencord/olt/internalapi/AccessDeviceFlowService.java
deleted file mode 100644
index 9e46782..0000000
--- a/impl/src/main/java/org/opencord/olt/internalapi/AccessDeviceFlowService.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.opencord.olt.internalapi;
-
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.flowobjective.ForwardingObjective;
-import org.onosproject.net.flowobjective.ObjectiveError;
-import org.onosproject.net.meter.MeterId;
-import org.opencord.olt.AccessDevicePort;
-import org.opencord.sadis.UniTagInformation;
-
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-
-/**
- * Olt service for flow operations.
- */
-public interface AccessDeviceFlowService {
-
-    /**
-     * Provisions or removes trap-to-controller DHCP packets.
-     *
-     * @param port               the uni port for which this trap flow is designated
-     * @param upstreamMeterId    the upstream meter id that includes the upstream
-     *                           bandwidth profile values such as PIR,CIR. If no meter id needs to be referenced,
-     *                           null can be sent
-     * @param upstreamOltMeterId the upstream meter id of OLT device that includes the upstream
-     *                           bandwidth profile values such as PIR,CIR. If no meter id needs to be referenced,
-     *                           null can be sent
-     * @param tagInformation     the uni tag (ctag, stag) information
-     * @param install            true to install the flow, false to remove the flow
-     * @param upstream           true if trapped packets are flowing upstream towards
-     *                           server, false if packets are flowing downstream towards client
-     * @param dhcpFuture         gets result of dhcp objective when complete
-     */
-    void processDhcpFilteringObjectives(AccessDevicePort port,
-                                        MeterId upstreamMeterId,
-                                        MeterId upstreamOltMeterId,
-                                        UniTagInformation tagInformation,
-                                        boolean install,
-                                        boolean upstream,
-                                        Optional<CompletableFuture<ObjectiveError>> dhcpFuture);
-
-    /**
-     * Trap igmp packets to the controller.
-     *
-     * @param port                  Uni Port number
-     * @param upstreamMeterId       upstream meter id that represents the upstream bandwidth profile
-     * @param upstreamOltMeterId    upstream meter id of OLT device that represents the upstream bandwidth profile
-     * @param tagInformation        the uni tag information of the subscriber
-     * @param install               the indicator to install or to remove the flow
-     * @param upstream              determines the direction of the flow
-     */
-    void processIgmpFilteringObjectives(AccessDevicePort port,
-                                        MeterId upstreamMeterId,
-                                        MeterId upstreamOltMeterId,
-                                        UniTagInformation tagInformation,
-                                        boolean install,
-                                        boolean upstream);
-
-    /**
-     * Trap eapol authentication packets to the controller.
-     *
-     * @param port         the port for which this trap flow is designated
-     * @param bpId         bandwidth profile id to add the related meter to the flow
-     * @param oltBpId      bandwidth profile id of OLT device to add the related meter to the flow
-     * @param filterFuture completable future for this filtering objective operation
-     * @param vlanId       the default or customer tag for a subscriber
-     * @param install      true to install the flow, false to remove the flow
-     */
-    void processEapolFilteringObjectives(AccessDevicePort port,
-                                         String bpId,
-                                         Optional<String> oltBpId,
-                                         CompletableFuture<ObjectiveError> filterFuture,
-                                         VlanId vlanId,
-                                         boolean install);
-
-    /**
-     * Trap PPPoE discovery packets to the controller.
-     *
-     * @param port               the uni port for which this trap flow is designated
-     * @param upstreamMeterId    the upstream meter id that includes the upstream
-     *                           bandwidth profile values such as PIR,CIR. If no meter id needs to be referenced,
-     *                           null can be sent
-     * @param upstreamOltMeterId the upstream meter id of OLT device that includes the upstream
-     *                           bandwidth profile values such as PIR,CIR. If no meter id needs to be referenced,
-     *                           null can be sent
-     * @param tagInformation     the uni tag (ctag, stag) information
-     * @param install            true to install the flow, false to remove the flow
-     * @param upstream           true if trapped packets are flowing upstream towards
-     *                           server, false if packets are flowing downstream towards client
-     **/
-    void processPPPoEDFilteringObjectives(AccessDevicePort port,
-                                          MeterId upstreamMeterId,
-                                          MeterId upstreamOltMeterId,
-                                          UniTagInformation tagInformation,
-                                          boolean install,
-                                          boolean upstream);
-
-    /**
-     * Trap lldp packets to the controller.
-     *
-     * @param port    the port for which this trap flow is designated
-     * @param install true to install the flow, false to remove the flow
-     */
-    void processLldpFilteringObjective(AccessDevicePort port, boolean install);
-
-    /**
-     * Installs trap filtering objectives for particular traffic types (LLDP, IGMP and DHCP) on an
-     * NNI port.
-     *
-     * @param port    port number
-     * @param install true to install, false to remove
-     */
-    void processNniFilteringObjectives(AccessDevicePort port, boolean install);
-
-    /**
-     * Creates a ForwardingObjective builder with double-tag match criteria and output
-     * action. The treatment will not contain pop or push actions.
-     * If the last parameter is true, use the upstream meter id and vice versa.
-     *
-     * @param uplinkPort      the nni port
-     * @param subscriberPort  the uni port
-     * @param meterId         the meter id that is assigned to upstream or downstream flows
-     * @param tagInfo         the uni tag information
-     * @param upstream        true to create upstream, false to create downstream builder
-     * @return ForwardingObjective.Builder
-     */
-    ForwardingObjective.Builder createTransparentBuilder(AccessDevicePort uplinkPort,
-                                                         AccessDevicePort subscriberPort,
-                                                         MeterId meterId,
-                                                         UniTagInformation tagInfo,
-                                                         boolean upstream);
-
-    /**
-     * Creates a ForwardingObjective builder for the upstream flows.
-     * The treatment will contain push action
-     *
-     * @param uplinkPort         the nni port
-     * @param subscriberPort     the uni port
-     * @param upstreamMeterId    the meter id that is assigned to upstream flows
-     * @param upstreamOltMeterId the meter id that is assigned to upstream flows for OLT device
-     * @param uniTagInformation  the uni tag information
-     * @return ForwardingObjective.Builder
-     */
-    ForwardingObjective.Builder createUpBuilder(AccessDevicePort uplinkPort,
-                                                AccessDevicePort subscriberPort,
-                                                MeterId upstreamMeterId,
-                                                MeterId upstreamOltMeterId,
-                                                UniTagInformation uniTagInformation);
-
-    /**
-     * Creates a ForwardingObjective builder for the downstream flows.
-     * The treatment will contain pop action
-     *
-     * @param uplinkPort           the nni port
-     * @param subscriberPort       the uni port
-     * @param downstreamMeterId    the meter id that is assigned to downstream flows
-     * @param downstreamOltMeterId the meter id that is assigned to downstream flows
-     * @param tagInformation       the uni tag information
-     * @param macAddress           the mac address
-     * @return ForwardingObjective.Builder
-     */
-    ForwardingObjective.Builder createDownBuilder(AccessDevicePort uplinkPort,
-                                                  AccessDevicePort subscriberPort,
-                                                  MeterId downstreamMeterId,
-                                                  MeterId downstreamOltMeterId,
-                                                  UniTagInformation tagInformation,
-                                                  Optional<MacAddress> macAddress);
-
-    /**
-     * Clears pending mappings and state for device.
-     * @param deviceId the device id
-     */
-    void clearDeviceState(DeviceId deviceId);
-}
diff --git a/impl/src/main/java/org/opencord/olt/internalapi/AccessDeviceMeterService.java b/impl/src/main/java/org/opencord/olt/internalapi/AccessDeviceMeterService.java
deleted file mode 100644
index ca04ed4..0000000
--- a/impl/src/main/java/org/opencord/olt/internalapi/AccessDeviceMeterService.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.opencord.olt.internalapi;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.meter.MeterId;
-import org.onosproject.net.meter.MeterKey;
-import org.opencord.sadis.BandwidthProfileInformation;
-
-import java.util.Collection;
-import java.util.concurrent.CompletableFuture;
-
-/**
- * Olt service for meter operations.
- */
-public interface AccessDeviceMeterService {
-
-    /**
-     * Returns information about bandwidthProfile-meterKey (device / meter) mappings
-     * that have been programmed in the data-plane.
-     *
-     * @return an immutable map of bandwidthProfile-meterKey (device / meter) mappings
-     */
-    ImmutableMap<String, Collection<MeterKey>> getBpMeterMappings();
-
-    /**
-     * Returns the meter id for a given bandwidth profile.
-     *
-     * @param deviceId         the access device id
-     * @param bandwidthProfile the bandwidth profile id
-     * @return the meter id
-     */
-    MeterId getMeterIdFromBpMapping(DeviceId deviceId, String bandwidthProfile);
-
-    /**
-     * Returns information about device-meter relations that have been programmed in the
-     * data-plane.
-     *
-     * @return an immutable set of device-meter mappings
-     */
-    ImmutableSet<MeterKey> getProgMeters();
-
-    /**
-     * Creates a meter and sends it to the device.
-     *
-     * @param deviceId    the access device id
-     * @param bpInfo      the bandwidth profile information
-     * @param meterFuture the meter future to indicate whether the meter creation is
-     *                    successful or not.
-     * @return meter id that is generated for the given parameters
-     */
-    MeterId createMeter(DeviceId deviceId, BandwidthProfileInformation bpInfo,
-                        CompletableFuture<Object> meterFuture);
-
-    /**
-     * Removes the DeviceBandwidthProfile from the pendingMeters.
-     *
-     * @param deviceId the device
-     * @param bwpInfo the bandwidth profile info
-     *
-     */
-    void removeFromPendingMeters(DeviceId deviceId, BandwidthProfileInformation bwpInfo);
-
-    /**
-     * Checks if DeviceBandwidthProfile is pending installation.
-     * If so immediately returns false meaning that no further action is needed,
-     * if not it adds the bandwidth profile do the pending list and returns true,
-     * meaning that further action to install the meter is required.
-     *
-     * @param deviceId the device
-     * @param bwpInfo the bandwidth profile info
-     *
-     * @return true if it was added to pending and a create meter action is needed,
-     * false if it is already pending and no further action is needed.
-     */
-    boolean checkAndAddPendingMeter(DeviceId deviceId, BandwidthProfileInformation bwpInfo);
-
-    /**
-     * Clears out meters for the given device.
-     *
-     * @param deviceId device ID
-     */
-    void clearMeters(DeviceId deviceId);
-
-    /**
-     * Clears out local state for the given device.
-     *
-     * @param deviceId device ID
-     */
-    void clearDeviceState(DeviceId deviceId);
-}
diff --git a/impl/src/main/java/org/opencord/olt/internalapi/package-info.java b/impl/src/main/java/org/opencord/olt/internalapi/package-info.java
deleted file mode 100644
index 2b5d98d..0000000
--- a/impl/src/main/java/org/opencord/olt/internalapi/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * 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.
- */
-
-/**
- * Internal APIs for the OLT application.
- */
-package org.opencord.olt.internalapi;
diff --git a/impl/src/main/resources/olt-drivers.xml b/impl/src/main/resources/olt-drivers.xml
index fa7b585..761d962 100644
--- a/impl/src/main/resources/olt-drivers.xml
+++ b/impl/src/main/resources/olt-drivers.xml
@@ -15,20 +15,6 @@
   ~ limitations under the License.
   -->
 <drivers>
-    <driver name="celestica" extends="default"
-            manufacturer="PMC GPON Networks" hwVersion="PAS5211 v2" swVersion="vOLT version 1.5.3.*">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.opencord.olt.driver.OltPipeline"/>
-        <behaviour api="org.onosproject.net.behaviour.MeterQuery"
-                   impl="org.onosproject.driver.query.FullMetersAvailable"/>
-    </driver>
-    <driver name="pmc-olt" extends="default"
-            manufacturer="PMC GPON Networks" hwVersion="PASffffffff v-1" swVersion="vOLT.*">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.opencord.olt.driver.OltPipeline"/>
-        <behaviour api="org.onosproject.net.behaviour.MeterQuery"
-                   impl="org.onosproject.driver.query.FullMetersAvailable"/>
-    </driver>
     <driver name="voltha" extends="default"
             manufacturer="VOLTHA Project" hwVersion=".*" swVersion=".*">
         <behaviour api="org.onosproject.net.behaviour.Pipeliner"
@@ -37,26 +23,5 @@
                    impl="org.onosproject.driver.query.FullMetersAvailable"/>
         <property name="accumulatorEnabled">true</property>
     </driver>
-    <driver name="fj-olt" extends="default"
-            manufacturer="Fujitsu" hwVersion="svkOLT" swVersion="v1.0">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.opencord.olt.driver.OltPipeline"/>
-        <behaviour api="org.onosproject.net.behaviour.MeterQuery"
-                   impl="org.onosproject.driver.query.FullMetersAvailable"/>
-    </driver>
-    <driver name="nokia-olt" extends="default"
-            manufacturer="Nokia" hwVersion="SDOLT" swVersion="5.2.1">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.opencord.olt.driver.NokiaOltPipeline"/>
-        <behaviour api="org.onosproject.net.behaviour.MeterQuery"
-                   impl="org.onosproject.driver.query.FullMetersAvailable"/>
-    </driver>
-    <driver name="g.fast" extends="default"
-            manufacturer="TEST1" hwVersion="TEST2" swVersion="TEST3">
-        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.opencord.olt.driver.OltPipeline"/>
-        <behaviour api="org.onosproject.net.behaviour.MeterQuery"
-                   impl="org.onosproject.driver.query.FullMetersAvailable"/>
-    </driver>
 </drivers>
 
diff --git a/impl/src/test/java/org/opencord/olt/impl/ConsistentHasherTest.java b/impl/src/test/java/org/opencord/olt/impl/ConsistentHasherTest.java
deleted file mode 100644
index 1f682cb..0000000
--- a/impl/src/test/java/org/opencord/olt/impl/ConsistentHasherTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2020-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.opencord.olt.impl;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.onosproject.cluster.NodeId;
-import org.onosproject.net.DeviceId;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-
-public class ConsistentHasherTest {
-
-    private static final int WEIGHT = 10;
-
-    private static final NodeId N1 = new NodeId("10.0.0.1");
-    private static final NodeId N2 = new NodeId("10.0.0.2");
-    private static final NodeId N3 = new NodeId("10.0.0.3");
-
-    private ConsistentHasher hasher;
-
-    @Before
-    public void setUp() {
-        List<NodeId> servers = new ArrayList<>();
-        servers.add(N1);
-        servers.add(N2);
-
-        hasher = new ConsistentHasher(servers, WEIGHT);
-    }
-
-    @Test
-    public void testHasher() {
-        DeviceId deviceId = DeviceId.deviceId("foo");
-        NodeId server = hasher.hash(deviceId.toString());
-
-        assertThat(server, equalTo(N1));
-
-        deviceId = DeviceId.deviceId("bsaf");
-        server = hasher.hash(deviceId.toString());
-
-        assertThat(server, equalTo(N2));
-    }
-
-    @Test
-    public void testAddServer() {
-        DeviceId deviceId = DeviceId.deviceId("foo");
-        NodeId server = hasher.hash(deviceId.toString());
-
-        assertThat(server, equalTo(N1));
-
-        hasher.addServer(N3);
-
-        server = hasher.hash(deviceId.toString());
-
-        assertThat(server, equalTo(N3));
-    }
-}
diff --git a/impl/src/test/java/org/opencord/olt/impl/OltDeviceListenerTest.java b/impl/src/test/java/org/opencord/olt/impl/OltDeviceListenerTest.java
new file mode 100644
index 0000000..f8229da
--- /dev/null
+++ b/impl/src/test/java/org/opencord/olt/impl/OltDeviceListenerTest.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.onlab.packet.ChassisId;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.provider.ProviderId;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.opencord.sadis.UniTagInformation;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+public class OltDeviceListenerTest extends OltTestHelpers {
+    private Olt olt;
+    private Olt.OltDeviceListener oltDeviceListener;
+
+    private final DeviceId deviceId = DeviceId.deviceId("test-device");
+    private final Device testDevice = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.OLT,
+            "testManufacturer", "1.0", "1.0", "SN", new ChassisId(1));
+
+    @Before
+    public void setUp() {
+        olt = new Olt();
+        olt.eventsQueues = new HashMap<>();
+        olt.mastershipService = Mockito.mock(MastershipService.class);
+        olt.oltDeviceService = Mockito.mock(OltDeviceService.class);
+        olt.oltFlowService = Mockito.mock(OltFlowService.class);
+        olt.oltMeterService = Mockito.mock(OltMeterService.class);
+        olt.deviceService = Mockito.mock(DeviceService.class);
+        olt.leadershipService = Mockito.mock(LeadershipService.class);
+        olt.clusterService = Mockito.mock(ClusterService.class);
+        olt.subsService = Mockito.mock(BaseInformationService.class);
+
+        Olt.OltDeviceListener baseClass = olt.deviceListener;
+        baseClass.eventExecutor = Mockito.mock(ExecutorService.class);
+        oltDeviceListener = Mockito.spy(baseClass);
+
+        // mock the executor so it immediately invokes the method
+        doAnswer(new Answer<Object>() {
+            public Object answer(InvocationOnMock invocation) throws Exception {
+                ((Runnable) invocation.getArguments()[0]).run();
+                return null;
+            }
+        }).when(baseClass.eventExecutor).execute(any(Runnable.class));
+
+        olt.eventsQueues.forEach((cp, q) -> q.clear());
+    }
+
+    @Test
+    public void testDeviceDisconnection() {
+        doReturn(true).when(olt.oltDeviceService).isOlt(testDevice);
+        doReturn(false).when(olt.deviceService).isAvailable(any());
+        doReturn(new LinkedList<Port>()).when(olt.deviceService).getPorts(any());
+        doReturn(true).when(olt.oltDeviceService).isLocalLeader(any());
+
+        DeviceEvent disconnect = new DeviceEvent(DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED, testDevice, null);
+        oltDeviceListener.event(disconnect);
+
+        verify(olt.oltFlowService, times(1)).purgeDeviceFlows(testDevice.id());
+        verify(olt.oltMeterService, times(1)).purgeDeviceMeters(testDevice.id());
+    }
+
+    @Test
+    public void testPortEventOwnership() {
+        // make sure that we ignore events for devices that are not local to this node
+
+        // make sure the device is recognized as an OLT and the port is not an NNI
+        doReturn(true).when(olt.oltDeviceService).isOlt(testDevice);
+        doReturn(false).when(olt.oltDeviceService).isNniPort(eq(testDevice), any());
+
+        // make sure we're not leaders of the device
+        doReturn(false).when(olt.oltDeviceService).isLocalLeader(any());
+
+        // this is a new port, should not create an entry in the queue
+        // we're not owners of the device
+        Port uniUpdateEnabled = new OltPort(testDevice, true, PortNumber.portNumber(16),
+                DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "uni-1").build());
+        DeviceEvent uniUpdateEnabledEvent =
+                new DeviceEvent(DeviceEvent.Type.PORT_UPDATED, testDevice, uniUpdateEnabled);
+        oltDeviceListener.event(uniUpdateEnabledEvent);
+
+        // the queue won't even be created
+        assert olt.eventsQueues.isEmpty();
+    }
+
+    @Test
+    public void testNniEvent() throws InterruptedException {
+        // make sure the device is recognized as an OLT and the port is recognized as an NNI,
+        // and we're local leaders
+        doReturn(true).when(olt.oltDeviceService).isOlt(testDevice);
+        doReturn(true).when(olt.oltDeviceService).isNniPort(eq(testDevice), any());
+        doReturn(true).when(olt.oltDeviceService).isLocalLeader(any());
+
+        Port enabledNniPort = new OltPort(testDevice, true, PortNumber.portNumber(1048576),
+                DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "nni-1").build());
+        DeviceEvent nniEnabledEvent = new DeviceEvent(DeviceEvent.Type.PORT_ADDED, testDevice, enabledNniPort);
+        oltDeviceListener.event(nniEnabledEvent);
+
+        // NNI events are straight forward, we can provision the flows directly
+        assert olt.eventsQueues.isEmpty();
+        verify(olt.oltFlowService, times(1))
+                .handleNniFlows(testDevice, enabledNniPort, OltFlowService.FlowOperation.ADD);
+
+        Port disabledNniPort = new OltPort(testDevice, false, PortNumber.portNumber(1048576),
+                DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "nni-1").build());
+        DeviceEvent nniDisabledEvent = new DeviceEvent(DeviceEvent.Type.PORT_UPDATED, testDevice, disabledNniPort);
+        oltDeviceListener.event(nniDisabledEvent);
+
+        assert olt.eventsQueues.isEmpty();
+        verify(olt.oltFlowService, times(1))
+                .handleNniFlows(testDevice, disabledNniPort, OltFlowService.FlowOperation.REMOVE);
+
+        // when we disable the device we receive a PORT_REMOVED event with status ENABLED
+        // make sure we're removing the flows correctly
+        DeviceEvent nniRemoveEvent = new DeviceEvent(DeviceEvent.Type.PORT_REMOVED, testDevice, enabledNniPort);
+        oltDeviceListener.event(nniRemoveEvent);
+
+        assert olt.eventsQueues.isEmpty();
+        verify(olt.oltFlowService, times(1))
+                .handleNniFlows(testDevice, enabledNniPort, OltFlowService.FlowOperation.REMOVE);
+    }
+
+    @Test
+    public void testUniEvents() {
+        DiscoveredSubscriber sub;
+        // there are few cases we need to test in the UNI port case:
+        // - [X] UNI port added in disabled state
+        // - [X] UNI port added in disabled state (with default EAPOL installed)
+        // - UNI port added in enabled state
+        // - [X] UNI port updated to enabled state
+        // - UNI port updated to disabled state
+        // - UNI port removed (assumes it's disabled state)
+
+        // make sure the device is recognized as an OLT, the port is not an NNI,
+        // and we're local masters
+        doReturn(true).when(olt.oltDeviceService).isOlt(testDevice);
+        doReturn(false).when(olt.oltDeviceService).isNniPort(eq(testDevice), any());
+        doReturn(true).when(olt.oltDeviceService).isLocalLeader(any());
+
+        PortNumber uniPortNumber = PortNumber.portNumber(16);
+        Port uniAddedDisabled = new OltPort(testDevice, false, uniPortNumber,
+                DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "uni-1").build());
+        DeviceEvent uniAddedDisabledEvent = new DeviceEvent(DeviceEvent.Type.PORT_ADDED, testDevice, uniAddedDisabled);
+        ConnectPoint cp = new ConnectPoint(testDevice.id(), uniPortNumber);
+
+        // if the port does not have default EAPOL we should not generate an event
+        oltDeviceListener.event(uniAddedDisabledEvent);
+
+        // no event == no queue is created
+        assert olt.eventsQueues.isEmpty();
+
+        // if the port has default EAPOL then create an entry in the queue to remove it
+        doReturn(true).when(olt.oltFlowService)
+                .hasDefaultEapol(uniAddedDisabled);
+        // create empty service for testing
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        UniTagInformation empty = new UniTagInformation.Builder().build();
+        uniTagInformationList.add(empty);
+
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        si.setUniTagList(uniTagInformationList);
+        doReturn(si).when(olt.subsService).get("uni-1");
+
+        oltDeviceListener.event(uniAddedDisabledEvent);
+        LinkedBlockingQueue<DiscoveredSubscriber> q = olt.eventsQueues.get(cp);
+        assert !q.isEmpty();
+        sub = q.poll();
+        assert !sub.hasSubscriber; // this is not a provision subscriber call
+        assert sub.device.equals(testDevice);
+        assert sub.port.equals(uniAddedDisabled);
+        assert sub.status.equals(DiscoveredSubscriber.Status.REMOVED); // we need to remove flows for this port (if any)
+        assert q.isEmpty(); // the queue is now empty
+
+        Port uniUpdateEnabled = new OltPort(testDevice, true, PortNumber.portNumber(16),
+                DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "uni-1").build());
+        DeviceEvent uniUpdateEnabledEvent =
+                new DeviceEvent(DeviceEvent.Type.PORT_UPDATED, testDevice, uniUpdateEnabled);
+        oltDeviceListener.event(uniUpdateEnabledEvent);
+
+        assert !q.isEmpty();
+        sub = q.poll();
+        assert !sub.hasSubscriber; // this is not a provision subscriber call
+        assert sub.device.equals(testDevice);
+        assert sub.port.equals(uniUpdateEnabled);
+        assert sub.status.equals(DiscoveredSubscriber.Status.ADDED); // we need to remove flows for this port (if any)
+        assert q.isEmpty(); // the queue is now empty
+    }
+}
diff --git a/impl/src/test/java/org/opencord/olt/impl/OltDeviceServiceTest.java b/impl/src/test/java/org/opencord/olt/impl/OltDeviceServiceTest.java
new file mode 100644
index 0000000..5623896
--- /dev/null
+++ b/impl/src/test/java/org/opencord/olt/impl/OltDeviceServiceTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
+import org.onosproject.cluster.Leader;
+import org.onosproject.cluster.Leadership;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.opencord.sadis.SadisService;
+
+import java.util.LinkedList;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+
+public class OltDeviceServiceTest {
+    OltDeviceService component;
+    private OltDeviceService oltDeviceService;
+
+    @Before
+    public void setUp() {
+        component = new OltDeviceService();
+        component.mastershipService = Mockito.mock(MastershipService.class);
+        component.deviceService = Mockito.mock(DeviceService.class);
+        component.leadershipService = Mockito.mock(LeadershipService.class);
+        component.clusterService = Mockito.mock(ClusterService.class);
+        component.sadisService = Mockito.mock(SadisService.class);
+        component.activate();
+
+        oltDeviceService = Mockito.spy(component);
+
+
+    }
+
+    @Test
+    public void testIsLocalLeader() {
+
+        NodeId nodeId = NodeId.nodeId("node1");
+        ControllerNode localNode = new DefaultControllerNode(nodeId, "host1");
+        DeviceId deviceId1 = DeviceId.deviceId("availableNotLocal");
+        DeviceId deviceId2 = DeviceId.deviceId("notAvailableButLocal");
+        Leadership leadership = new Leadership(deviceId2.toString(), new Leader(nodeId, 0, 0), new LinkedList<>());
+
+        doReturn(true).when(oltDeviceService.deviceService).isAvailable(eq(deviceId1));
+        doReturn(false).when(oltDeviceService.mastershipService).isLocalMaster(eq(deviceId1));
+        Assert.assertFalse(oltDeviceService.isLocalLeader(deviceId1));
+
+        doReturn(false).when(oltDeviceService.deviceService).isAvailable(eq(deviceId1));
+        doReturn(localNode).when(oltDeviceService.clusterService).getLocalNode();
+        doReturn(leadership).when(oltDeviceService.leadershipService).runForLeadership(eq(deviceId2.toString()));
+        Assert.assertTrue(oltDeviceService.isLocalLeader(deviceId2));
+
+    }
+}
diff --git a/impl/src/test/java/org/opencord/olt/impl/OltFlowServiceTest.java b/impl/src/test/java/org/opencord/olt/impl/OltFlowServiceTest.java
new file mode 100644
index 0000000..c9bad5f
--- /dev/null
+++ b/impl/src/test/java/org/opencord/olt/impl/OltFlowServiceTest.java
@@ -0,0 +1,669 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onlab.packet.ChassisId;
+import org.onlab.packet.EthType;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.TpPort;
+import org.onlab.packet.VlanId;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.TestStorageService;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.opencord.sadis.UniTagInformation;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.onosproject.net.AnnotationKeys.PORT_NAME;
+import static org.opencord.olt.impl.OltFlowService.OltFlowsStatus.NONE;
+import static org.opencord.olt.impl.OltFlowService.OltFlowsStatus.ADDED;
+import static org.opencord.olt.impl.OltFlowService.OltFlowsStatus.PENDING_ADD;
+import static org.opencord.olt.impl.OltFlowService.OltFlowsStatus.REMOVED;
+import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_BP_ID_DEFAULT;
+
+public class OltFlowServiceTest extends OltTestHelpers {
+
+    private OltFlowService oltFlowService;
+    OltFlowService.InternalFlowListener internalFlowListener;
+    private final ApplicationId testAppId = new DefaultApplicationId(1, "org.opencord.olt.test");
+    private final short eapolDefaultVlan = 4091;
+
+    private final DeviceId deviceId = DeviceId.deviceId("test-device");
+    private final Device testDevice = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.OLT,
+            "testManufacturer", "1.0", "1.0", "SN", new ChassisId(1));
+    Port nniPort = new OltPort(testDevice, true, PortNumber.portNumber(1048576),
+            DefaultAnnotations.builder().set(PORT_NAME, "nni-1").build());
+    Port nniPortDisabled = new OltPort(testDevice, false, PortNumber.portNumber(1048576),
+            DefaultAnnotations.builder().set(PORT_NAME, "nni-1").build());
+    Port uniUpdateEnabled = new OltPort(testDevice, true, PortNumber.portNumber(16),
+            DefaultAnnotations.builder().set(PORT_NAME, "uni-1").build());
+
+    @Before
+    public void setUp() {
+        oltFlowService = new OltFlowService();
+        oltFlowService.cfgService = new ComponentConfigAdapter();
+        oltFlowService.sadisService = Mockito.mock(SadisService.class);
+        oltFlowService.coreService = Mockito.spy(new CoreServiceAdapter());
+        oltFlowService.oltMeterService = Mockito.mock(OltMeterService.class);
+        oltFlowService.flowObjectiveService = Mockito.mock(FlowObjectiveService.class);
+        oltFlowService.hostService = Mockito.mock(HostService.class);
+        oltFlowService.flowRuleService = Mockito.mock(FlowRuleService.class);
+        oltFlowService.storageService = new TestStorageService();
+        oltFlowService.oltDeviceService = Mockito.mock(OltDeviceService.class);
+        oltFlowService.appId = testAppId;
+
+        doReturn(Mockito.mock(BaseInformationService.class))
+                .when(oltFlowService.sadisService).getSubscriberInfoService();
+        doReturn(testAppId).when(oltFlowService.coreService).registerApplication("org.opencord.olt");
+        oltFlowService.activate(null);
+        oltFlowService.bindSadisService(oltFlowService.sadisService);
+
+        internalFlowListener = spy(oltFlowService.internalFlowListener);
+    }
+
+    @After
+    public void tearDown() {
+        oltFlowService.deactivate(null);
+    }
+
+    @Test
+    public void testUpdateConnectPointStatus() {
+
+        DeviceId deviceId = DeviceId.deviceId("test-device");
+        ProviderId pid = new ProviderId("of", "foo");
+        Device device =
+                new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
+        Port port1 = new DefaultPort(device, PortNumber.portNumber(1), true,
+                DefaultAnnotations.builder().set(PORT_NAME, "port-1").build());
+        Port port2 = new DefaultPort(device, PortNumber.portNumber(2), true,
+                DefaultAnnotations.builder().set(PORT_NAME, "port-2").build());
+        Port port3 = new DefaultPort(device, PortNumber.portNumber(3), true,
+                DefaultAnnotations.builder().set(PORT_NAME, "port-3").build());
+
+        ServiceKey sk1 = new ServiceKey(new AccessDevicePort(port1), new UniTagInformation());
+        ServiceKey sk2 = new ServiceKey(new AccessDevicePort(port2), new UniTagInformation());
+        ServiceKey sk3 = new ServiceKey(new AccessDevicePort(port3), new UniTagInformation());
+
+        // cpStatus map for the test
+        oltFlowService.cpStatus = oltFlowService.storageService.
+                <ServiceKey, OltPortStatus>consistentMapBuilder().build().asJavaMap();
+        OltPortStatus cp1Status = new OltPortStatus(PENDING_ADD, NONE, NONE);
+        oltFlowService.cpStatus.put(sk1, cp1Status);
+
+        //check that we only update the provided value
+        oltFlowService.updateConnectPointStatus(sk1, ADDED, null, null);
+        OltPortStatus updated = oltFlowService.cpStatus.get(sk1);
+        Assert.assertEquals(ADDED, updated.defaultEapolStatus);
+        Assert.assertEquals(NONE, updated.subscriberFlowsStatus);
+        Assert.assertEquals(NONE, updated.dhcpStatus);
+
+        // check that it creates an entry if it does not exist
+        oltFlowService.updateConnectPointStatus(sk2, PENDING_ADD, NONE, NONE);
+        Assert.assertNotNull(oltFlowService.cpStatus.get(sk2));
+
+        // check that if we create a new entry with null values they're converted to NONE
+        oltFlowService.updateConnectPointStatus(sk3, null, null, null);
+        updated = oltFlowService.cpStatus.get(sk3);
+        Assert.assertEquals(NONE, updated.defaultEapolStatus);
+        Assert.assertEquals(NONE, updated.subscriberFlowsStatus);
+        Assert.assertEquals(NONE, updated.dhcpStatus);
+    }
+
+    @Test
+    public void testHasDefaultEapol() {
+        DeviceId deviceId = DeviceId.deviceId("test-device");
+        ProviderId pid = new ProviderId("of", "foo");
+
+        Device device =
+                new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
+
+        Port port = new DefaultPort(device, PortNumber.portNumber(16), true,
+                                    DefaultAnnotations.builder().set(PORT_NAME, "name-1").build());
+        ServiceKey skWithStatus = new ServiceKey(new AccessDevicePort(port),
+                oltFlowService.defaultEapolUniTag);
+
+        Port port17 = new DefaultPort(device, PortNumber.portNumber(17), true,
+                                      DefaultAnnotations.builder().set(PORT_NAME, "name-1").build());
+
+        OltPortStatus portStatusAdded = new OltPortStatus(
+                OltFlowService.OltFlowsStatus.ADDED,
+                NONE,
+                null
+        );
+
+        OltPortStatus portStatusRemoved = new OltPortStatus(
+                REMOVED,
+                NONE,
+                null
+        );
+
+        oltFlowService.cpStatus.put(skWithStatus, portStatusAdded);
+        Assert.assertTrue(oltFlowService.hasDefaultEapol(port));
+
+        oltFlowService.cpStatus.put(skWithStatus, portStatusRemoved);
+
+        Assert.assertFalse(oltFlowService.hasDefaultEapol(port17));
+    }
+
+    @Test
+    public void testHasSubscriberFlows() {
+        // TODO test with multiple services
+        DeviceId deviceId = DeviceId.deviceId("test-device");
+        ProviderId pid = new ProviderId("of", "foo");
+
+        Device device =
+                new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
+
+        Port port = new DefaultPort(device, PortNumber.portNumber(16), true,
+                DefaultAnnotations.builder().set(PORT_NAME, "name-1").build());
+
+        UniTagInformation uti = new UniTagInformation.Builder().setServiceName("test").build();
+        ServiceKey skWithStatus = new ServiceKey(new AccessDevicePort(port),
+                uti);
+
+        OltPortStatus withDefaultEapol = new OltPortStatus(
+                ADDED,
+                NONE,
+                NONE
+        );
+
+        OltPortStatus withDhcp = new OltPortStatus(
+                REMOVED,
+                NONE,
+                ADDED
+        );
+
+        OltPortStatus withSubFlow = new OltPortStatus(
+                REMOVED,
+                ADDED,
+                ADDED
+        );
+
+        oltFlowService.cpStatus.put(skWithStatus, withDefaultEapol);
+        Assert.assertFalse(oltFlowService.hasSubscriberFlows(port, uti));
+
+        oltFlowService.cpStatus.put(skWithStatus, withDhcp);
+        Assert.assertTrue(oltFlowService.hasDhcpFlows(port, uti));
+
+        oltFlowService.cpStatus.put(skWithStatus, withSubFlow);
+        Assert.assertTrue(oltFlowService.hasSubscriberFlows(port, uti));
+    }
+
+    @Test
+    public void testHandleBasicPortFlowsNoEapol() throws Exception {
+        oltFlowService.enableEapol = false;
+        // create empty service for testing
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        UniTagInformation empty = new UniTagInformation.Builder().build();
+        uniTagInformationList.add(empty);
+
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        si.setUniTagList(uniTagInformationList);
+
+        final DiscoveredSubscriber addedSub =
+                new DiscoveredSubscriber(testDevice,
+                                         uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
+                                         false, si);
+        oltFlowService.handleBasicPortFlows(addedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
+        // if eapol is not enabled there's nothing we need to do,
+        // so make sure we don't even call sadis
+        verify(oltFlowService.subsService, never()).get(any());
+    }
+
+    @Test
+    public void testHandleBasicPortFlowsWithEapolNoMeter() throws Exception {
+        // create empty service for testing
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        UniTagInformation empty = new UniTagInformation.Builder().build();
+        uniTagInformationList.add(empty);
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        si.setUniTagList(uniTagInformationList);
+        final DiscoveredSubscriber addedSub =
+                new DiscoveredSubscriber(testDevice,
+                                         uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
+                                         false, si);
+        // whether the meter is pending or not is up to the createMeter method to handle
+        // we just don't proceed with the subscriber till it's ready
+        doReturn(false).when(oltFlowService.oltMeterService)
+                .createMeter(addedSub.device.id(), DEFAULT_BP_ID_DEFAULT);
+        boolean res = oltFlowService.handleBasicPortFlows(addedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
+
+        Assert.assertFalse(res);
+
+        // we do not create flows
+        verify(oltFlowService.flowObjectiveService, never())
+                .filter(eq(addedSub.device.id()), any());
+    }
+
+    @Test
+    public void testHandleBasicPortFlowsWithEapolAddedMeter() throws Exception {
+        // create empty service for testing
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        UniTagInformation empty = new UniTagInformation.Builder().build();
+        uniTagInformationList.add(empty);
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        si.setUniTagList(uniTagInformationList);
+        final DiscoveredSubscriber addedSub =
+                new DiscoveredSubscriber(testDevice,
+                                         uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
+                                         false, si);
+        // this is the happy case, we have the meter so we check that the default EAPOL flow
+        // is installed
+        doReturn(true).when(oltFlowService.oltMeterService)
+                .createMeter(deviceId, DEFAULT_BP_ID_DEFAULT);
+        doReturn(true).when(oltFlowService.oltMeterService)
+                .hasMeterByBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT);
+        doReturn(MeterId.meterId(1)).when(oltFlowService.oltMeterService)
+                .getMeterIdForBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT);
+
+        FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
+                .permit()
+                .withKey(Criteria.matchInPort(uniUpdateEnabled.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
+                .fromApp(testAppId)
+                .withPriority(10000)
+                .withMeta(
+                        DefaultTrafficTreatment.builder()
+                                .meter(MeterId.meterId(1))
+                                .writeMetadata(oltFlowService.createTechProfValueForWriteMetadata(
+                                        VlanId.vlanId(eapolDefaultVlan),
+                                        oltFlowService.defaultTechProfileId, MeterId.meterId(1)), 0)
+                                .setOutput(PortNumber.CONTROLLER)
+                                .pushVlan()
+                                .setVlanId(VlanId.vlanId(eapolDefaultVlan)).build()
+                )
+                .add();
+
+
+        oltFlowService.handleBasicPortFlows(addedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
+
+        // we check for an existing meter (present)
+        // FIXME understand why the above test invokes this call and this one doesn't
+//        verify(oltFlowService.oltMeterService, times(1))
+//                .hasMeterByBandwidthProfile(eq(addedSub.device.id()), eq(DEFAULT_BP_ID_DEFAULT));
+
+        // the meter exist, no need to check for PENDING or to create it
+        verify(oltFlowService.oltMeterService, never())
+                .hasPendingMeterByBandwidthProfile(eq(deviceId), eq(DEFAULT_BP_ID_DEFAULT));
+        verify(oltFlowService.oltMeterService, never())
+                .createMeterForBp(eq(deviceId), eq(DEFAULT_BP_ID_DEFAULT));
+
+        verify(oltFlowService.flowObjectiveService, times(1))
+                .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
+    }
+
+    @Test
+    public void testHandleBasicPortFlowsRemovedSub() throws Exception {
+        // create empty service for testing
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        UniTagInformation empty = new UniTagInformation.Builder().build();
+        uniTagInformationList.add(empty);
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        si.setUniTagList(uniTagInformationList);
+        final DiscoveredSubscriber removedSub =
+                new DiscoveredSubscriber(testDevice,
+                                         uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
+                                         false, si);
+        // we are testing that when a port goes down we remove the default EAPOL flow
+
+        doReturn(MeterId.meterId(1)).when(oltFlowService.oltMeterService)
+                .getMeterIdForBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT);
+
+        FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
+                .deny()
+                .withKey(Criteria.matchInPort(uniUpdateEnabled.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
+                .fromApp(testAppId)
+                .withPriority(10000)
+                .withMeta(
+                        DefaultTrafficTreatment.builder()
+                                .meter(MeterId.meterId(1))
+                                .writeMetadata(oltFlowService.createTechProfValueForWriteMetadata(
+                                        VlanId.vlanId(eapolDefaultVlan),
+                                        oltFlowService.defaultTechProfileId, MeterId.meterId(1)), 0)
+                                .setOutput(PortNumber.CONTROLLER)
+                                .pushVlan()
+                                .setVlanId(VlanId.vlanId(eapolDefaultVlan)).build()
+                )
+                .add();
+
+        oltFlowService.handleBasicPortFlows(removedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
+
+        verify(oltFlowService.flowObjectiveService, times(1))
+                .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
+    }
+
+    @Test
+    public void testHandleNniFlowsOnlyLldp() {
+        oltFlowService.enableDhcpOnNni = false;
+        oltFlowService.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
+
+        FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
+                .permit()
+                .withKey(Criteria.matchInPort(nniPort.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.LLDP.ethType()))
+                .fromApp(testAppId)
+                .withPriority(10000)
+                .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
+                .add();
+
+        verify(oltFlowService.flowObjectiveService, times(1))
+                .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
+        verify(oltFlowService.flowObjectiveService, times(1))
+                .filter(eq(deviceId), any());
+    }
+
+    @Test
+    public void testHandleNniFlowsDhcpV4() {
+        oltFlowService.enableDhcpOnNni = true;
+        oltFlowService.enableDhcpV4 = true;
+        oltFlowService.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
+
+        FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
+                .permit()
+                .withKey(Criteria.matchInPort(nniPort.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
+                .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
+                .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(67)))
+                .addCondition(Criteria.matchUdpDst(TpPort.tpPort(68)))
+                .fromApp(testAppId)
+                .withPriority(10000)
+                .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
+                .add();
+
+        // invoked with the correct DHCP filtering objective
+        verify(oltFlowService.flowObjectiveService, times(1))
+                .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
+        // invoked only twice, LLDP and DHCP
+        verify(oltFlowService.flowObjectiveService, times(2))
+                .filter(eq(deviceId), any());
+    }
+
+    @Test
+    public void testRemoveNniFlowsDhcpV4() {
+        oltFlowService.enableDhcpOnNni = true;
+        oltFlowService.enableDhcpV4 = true;
+        oltFlowService.handleNniFlows(testDevice, nniPortDisabled, OltFlowService.FlowOperation.REMOVE);
+
+        FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
+                .deny()
+                .withKey(Criteria.matchInPort(nniPort.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
+                .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
+                .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(67)))
+                .addCondition(Criteria.matchUdpDst(TpPort.tpPort(68)))
+                .fromApp(testAppId)
+                .withPriority(10000)
+                .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
+                .add();
+
+        // invoked with the correct DHCP filtering objective
+        verify(oltFlowService.flowObjectiveService, times(1))
+                .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
+        // invoked only twice, LLDP and DHCP
+        verify(oltFlowService.flowObjectiveService, times(2))
+                .filter(eq(deviceId), any());
+    }
+
+    @Test
+    public void testHandleNniFlowsDhcpV6() {
+        oltFlowService.enableDhcpOnNni = true;
+        oltFlowService.enableDhcpV4 = false;
+        oltFlowService.enableDhcpV6 = true;
+        oltFlowService.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
+
+        FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
+                .permit()
+                .withKey(Criteria.matchInPort(nniPort.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.IPV6.ethType()))
+                .addCondition(Criteria.matchIPProtocol(IPv6.PROTOCOL_UDP))
+                .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(546)))
+                .addCondition(Criteria.matchUdpDst(TpPort.tpPort(547)))
+                .fromApp(testAppId)
+                .withPriority(10000)
+                .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
+                .add();
+
+        // invoked with the correct DHCP filtering objective
+        verify(oltFlowService.flowObjectiveService, times(1))
+                .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
+        // invoked only twice, LLDP and DHCP
+        verify(oltFlowService.flowObjectiveService, times(2))
+                .filter(eq(deviceId), any());
+    }
+
+    @Test
+    public void testHandleNniFlowsIgmp() {
+        oltFlowService.enableDhcpOnNni = false;
+        oltFlowService.enableIgmpOnNni = true;
+        oltFlowService.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
+
+        FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
+                .permit()
+                .withKey(Criteria.matchInPort(nniPort.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
+                .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_IGMP))
+                .fromApp(testAppId)
+                .withPriority(10000)
+                .add();
+
+        // invoked with the correct DHCP filtering objective
+        verify(oltFlowService.flowObjectiveService, times(1))
+                .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
+        // invoked only twice, LLDP and DHCP
+        verify(oltFlowService.flowObjectiveService, times(2))
+                .filter(eq(deviceId), any());
+    }
+
+    @Test
+    public void testMacAddressNotRequired() {
+        // create a single service that doesn't require mac address
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        UniTagInformation hsia = new UniTagInformation.Builder()
+                .setEnableMacLearning(false)
+                .build();
+        uniTagInformationList.add(hsia);
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        si.setUniTagList(uniTagInformationList);
+
+        boolean isMacAvailable = oltFlowService.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
+        // we return true as we don't care wether it's available or not
+        Assert.assertTrue(isMacAvailable);
+    }
+
+    @Test
+    public void testIsMacAddressAvailableViaMacLearning() {
+
+        // create a single service that requires macLearning to be enabled
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        VlanId hsiaCtag = VlanId.vlanId((short) 11);
+        UniTagInformation hsia = new UniTagInformation.Builder()
+                .setPonCTag(hsiaCtag)
+                .setEnableMacLearning(true).build();
+        uniTagInformationList.add(hsia);
+
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        si.setUniTagList(uniTagInformationList);
+
+        // with no hosts discovered, return false
+        boolean isMacAvailable = oltFlowService.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
+        Assert.assertFalse(isMacAvailable);
+
+        // with a discovered host, return true
+        Host fakeHost = new DefaultHost(ProviderId.NONE, HostId.hostId(MacAddress.NONE), MacAddress.ZERO,
+                hsiaCtag, HostLocation.NONE, new HashSet<>(), DefaultAnnotations.builder().build());
+        Set<Host> hosts = new HashSet<>(Arrays.asList(fakeHost));
+        doReturn(hosts).when(oltFlowService.hostService).getConnectedHosts((ConnectPoint) any());
+
+        isMacAvailable = oltFlowService.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
+        Assert.assertTrue(isMacAvailable);
+    }
+
+    @Test
+    public void testIsMacAddressAvailableViaConfiguration() {
+        // create a single service that has a macAddress configured
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        UniTagInformation hsia = new UniTagInformation.Builder()
+                .setConfiguredMacAddress("2e:0a:00:01:00:00")
+                .build();
+        uniTagInformationList.add(hsia);
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        si.setUniTagList(uniTagInformationList);
+
+        boolean isMacAvailable = oltFlowService.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
+        Assert.assertTrue(isMacAvailable);
+    }
+
+    @Test
+    public void testHandleSubscriberDhcpFlowsAdd() {
+
+        String usBp = "usBp";
+        String usOltBp = "usOltBp";
+        oltFlowService.enableDhcpV4 = true;
+
+        // create two services, one requires DHCP the other doesn't
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        VlanId hsiaCtag = VlanId.vlanId((short) 11);
+        UniTagInformation hsia = new UniTagInformation.Builder()
+                .setPonCTag(hsiaCtag)
+                .setTechnologyProfileId(64)
+                .setUniTagMatch(VlanId.vlanId(VlanId.NO_VID))
+                .setUpstreamBandwidthProfile(usBp)
+                .setUpstreamOltBandwidthProfile(usOltBp)
+                .setIsDhcpRequired(true).build();
+        UniTagInformation mc = new UniTagInformation.Builder()
+                .setIsDhcpRequired(false).build();
+        uniTagInformationList.add(hsia);
+        uniTagInformationList.add(mc);
+
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        si.setUniTagList(uniTagInformationList);
+
+        final DiscoveredSubscriber addedSub =
+                new DiscoveredSubscriber(testDevice,
+                                         uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
+                                         false, si);
+
+        // return meter IDs
+        doReturn(MeterId.meterId(2)).when(oltFlowService.oltMeterService)
+                .getMeterIdForBandwidthProfile(addedSub.device.id(), usBp);
+        doReturn(MeterId.meterId(3)).when(oltFlowService.oltMeterService)
+                .getMeterIdForBandwidthProfile(addedSub.device.id(), usOltBp);
+
+        // TODO improve the matches on the filter
+        FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
+                .permit()
+                .withKey(Criteria.matchInPort(addedSub.port.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
+                .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
+                .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(68)))
+                .addCondition(Criteria.matchUdpDst(TpPort.tpPort(67)))
+                .fromApp(testAppId)
+                .withPriority(10000)
+                .add();
+
+        oltFlowService.handleSubscriberDhcpFlows(addedSub.device.id(), addedSub.port,
+                OltFlowService.FlowOperation.ADD, si);
+        verify(oltFlowService.flowObjectiveService, times(1))
+                .filter(eq(addedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
+    }
+
+    @Test
+    public void testInternalFlowListenerNotMaster() {
+        doReturn(false).when(oltFlowService.oltDeviceService).isLocalLeader(any());
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .forDevice(DeviceId.deviceId("foo"))
+                .fromApp(testAppId)
+                .makePermanent()
+                .withPriority(1000)
+                .build();
+        FlowRuleEvent event = new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED,
+                flowRule);
+
+        internalFlowListener.event(event);
+
+        // if we're not master of the device, we should not update
+        verify(internalFlowListener, never()).updateCpStatus(any(), any(), any());
+    }
+
+    @Test
+    public void testInternalFlowListenerDifferentApp() {
+        ApplicationId someAppId = new DefaultApplicationId(1, "org.opencord.olt.not-test");
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .forDevice(DeviceId.deviceId("foo"))
+                .fromApp(someAppId)
+                .makePermanent()
+                .withPriority(1000)
+                .build();
+        FlowRuleEvent event = new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED,
+                flowRule);
+
+        internalFlowListener.event(event);
+
+        // if we're not master of the device, we should not update
+        verify(internalFlowListener, never()).updateCpStatus(any(), any(), any());
+    }
+}
\ No newline at end of file
diff --git a/impl/src/test/java/org/opencord/olt/impl/OltFlowTest.java b/impl/src/test/java/org/opencord/olt/impl/OltFlowTest.java
deleted file mode 100644
index 752e44d..0000000
--- a/impl/src/test/java/org/opencord/olt/impl/OltFlowTest.java
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.opencord.olt.impl;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-
-import com.google.common.collect.Maps;
-import org.apache.commons.lang3.tuple.Pair;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.packet.EthType;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.cluster.NodeId;
-import org.onosproject.cluster.RoleInfo;
-import org.onosproject.mastership.MastershipInfo;
-import org.onosproject.mastership.MastershipListener;
-import org.onosproject.net.AnnotationKeys;
-import org.onosproject.net.DefaultAnnotations;
-import org.onosproject.net.DefaultPort;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.MastershipRole;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.EthTypeCriterion;
-import org.onosproject.net.flow.criteria.PortCriterion;
-import org.onosproject.net.flow.criteria.VlanIdCriterion;
-import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.flow.instructions.L2ModificationInstruction;
-import org.onosproject.net.flowobjective.FilteringObjQueueKey;
-import org.onosproject.net.flowobjective.FilteringObjective;
-import org.onosproject.net.flowobjective.ForwardingObjQueueKey;
-import org.onosproject.net.flowobjective.ForwardingObjective;
-import org.onosproject.net.flowobjective.NextObjQueueKey;
-import org.onosproject.net.flowobjective.NextObjective;
-import org.onosproject.net.flowobjective.Objective;
-import org.onosproject.net.meter.MeterId;
-import org.onosproject.net.meter.MeterKey;
-import org.opencord.olt.AccessDevicePort;
-import org.opencord.sadis.BandwidthProfileInformation;
-import org.opencord.sadis.UniTagInformation;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ListMultimap;
-
-public class OltFlowTest extends TestBase {
-    private OltFlowService oltFlowService;
-    AccessDevicePort uniPort1 = new AccessDevicePort(new DefaultPort(olt, PortNumber.portNumber(1), true,
-            DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "BBSM00010001-1").build()),
-            AccessDevicePort.Type.UNI);
-    AccessDevicePort uniPort2 = new AccessDevicePort(new DefaultPort(olt, PortNumber.portNumber(2), true,
-            DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "BBSM00010002-1").build()),
-            AccessDevicePort.Type.UNI);
-    AccessDevicePort nniPort = new AccessDevicePort(new DefaultPort(olt, PortNumber.portNumber(65535), true,
-            DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "nni-1048576").build()),
-            AccessDevicePort.Type.NNI);
-
-    MacAddress macAddress = MacAddress.valueOf("00:00:00:00:0a:0b");
-
-    UniTagInformation.Builder tagInfoBuilder = new UniTagInformation.Builder();
-    UniTagInformation uniTagInfo = tagInfoBuilder.setUniTagMatch(VlanId.vlanId((short) 35))
-            .setPonCTag(VlanId.vlanId((short) 33))
-            .setPonSTag(VlanId.vlanId((short) 7))
-            .setDsPonCTagPriority(0)
-            .setUsPonSTagPriority(0)
-            .setTechnologyProfileId(64)
-            .setDownstreamBandwidthProfile(dsBpId)
-            .setUpstreamBandwidthProfile(usBpId)
-            .setIsDhcpRequired(true)
-            .setIsIgmpRequired(true)
-            .build();
-
-    UniTagInformation.Builder tagInfoBuilderNoPcp = new UniTagInformation.Builder();
-    UniTagInformation uniTagInfoNoPcp = tagInfoBuilderNoPcp.setUniTagMatch(VlanId.vlanId((short) 35))
-            .setPonCTag(VlanId.vlanId((short) 34))
-            .setPonSTag(VlanId.vlanId((short) 7))
-            .setDsPonCTagPriority(-1)
-            .setUsPonSTagPriority(-1)
-            .setUsPonCTagPriority(-1)
-            .setDsPonSTagPriority(-1)
-            .setTechnologyProfileId(64)
-            .setDownstreamBandwidthProfile(dsBpId)
-            .setUpstreamBandwidthProfile(usBpId)
-            .setIsDhcpRequired(true)
-            .setIsIgmpRequired(true)
-            .build();
-
-    UniTagInformation.Builder tagInfoBuilder2 = new UniTagInformation.Builder();
-    UniTagInformation uniTagInfoNoDhcpNoIgmp = tagInfoBuilder2
-            .setUniTagMatch(VlanId.vlanId((short) 35))
-            .setPonCTag(VlanId.vlanId((short) 33))
-            .setPonSTag(VlanId.vlanId((short) 7))
-            .setDsPonCTagPriority(0)
-            .setUsPonSTagPriority(0)
-            .setTechnologyProfileId(64)
-            .setDownstreamBandwidthProfile(dsBpId)
-            .setUpstreamBandwidthProfile(usBpId)
-            .build();
-
-    @Before
-    public void setUp() {
-        oltFlowService = new OltFlowService();
-        oltFlowService.oltMeterService = new MockOltMeterService();
-        oltFlowService.flowObjectiveService = new MockOltFlowObjectiveService();
-        oltFlowService.mastershipService = new MockMastershipService();
-        oltFlowService.sadisService = new MockSadisService();
-        oltFlowService.bpService = oltFlowService.sadisService.getBandwidthProfileService();
-        oltFlowService.appId = appId;
-        oltFlowService.pendingEapolForDevice = Maps.newConcurrentMap();
-    }
-
-    @Test
-    public void testDhcpFiltering() {
-        System.out.println(uniPort1);
-        oltFlowService.flowObjectiveService.clearQueue();
-        // ensure upstream dhcp traps can be added and removed
-        oltFlowService.processDhcpFilteringObjectives(uniPort1,
-                usMeterId, null, uniTagInfo,
-                true, true, Optional.empty());
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 1;
-        oltFlowService.processDhcpFilteringObjectives(uniPort1,
-                usMeterId, null, uniTagInfo,
-                false, true, Optional.empty());
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 2;
-
-        // Ensure upstream flow has no pcp unless properly specified.
-        oltFlowService.processDhcpFilteringObjectives(uniPort2,
-                usMeterId, null, uniTagInfoNoPcp,
-                true, true, Optional.empty());
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 3;
-
-        // ensure upstream flows are not added if uniTagInfo is missing dhcp requirement
-        oltFlowService.processDhcpFilteringObjectives(uniPort1,
-                usMeterId, null, uniTagInfoNoDhcpNoIgmp,
-                true, true, Optional.empty());
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 3;
-
-        // ensure downstream traps don't succeed without global config for nni ports
-        oltFlowService.processDhcpFilteringObjectives(nniPort,
-                null, null, null,
-                true, false, Optional.empty());
-        oltFlowService.processDhcpFilteringObjectives(nniPort,
-                null, null, null,
-                false, false, Optional.empty());
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 3;
-        // do global config for nni ports and now it should succeed
-        oltFlowService.enableDhcpOnNni = true;
-        oltFlowService.processDhcpFilteringObjectives(nniPort,
-                null, null, null,
-                true, false, Optional.empty());
-        oltFlowService.processDhcpFilteringObjectives(nniPort,
-                null, null, null,
-                false, false, Optional.empty());
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 5;
-
-        // turn on DHCPv6 and we should get 2 flows
-        oltFlowService.enableDhcpV6 = true;
-        oltFlowService.processDhcpFilteringObjectives(uniPort1,
-                usMeterId, null, uniTagInfo,
-                true, true, Optional.empty());
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 7;
-
-        // turn off DHCPv4 and it's only v6
-        oltFlowService.enableDhcpV4 = false;
-        oltFlowService.processDhcpFilteringObjectives(uniPort1,
-                usMeterId, null, uniTagInfo,
-                true, true, Optional.empty());
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 8;
-
-        // cleanup
-        oltFlowService.flowObjectiveService.clearQueue();
-        oltFlowService.enableDhcpV4 = true;
-        oltFlowService.enableDhcpV6 = false;
-    }
-
-    @Test
-    public void testPppoedFiltering() {
-        oltFlowService.flowObjectiveService.clearQueue();
-
-        // ensure pppoed traps are not added if global config is off.
-        oltFlowService.enablePppoe = false;
-        oltFlowService.processPPPoEDFilteringObjectives(uniPort1,
-                usMeterId, null, uniTagInfo,
-                true, true);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 0;
-
-        // ensure upstream pppoed traps can be added and removed
-        oltFlowService.enablePppoe = true;
-        oltFlowService.processPPPoEDFilteringObjectives(uniPort1,
-                usMeterId, null, uniTagInfo,
-                true, true);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 1;
-        oltFlowService.processPPPoEDFilteringObjectives(uniPort1,
-                usMeterId, null, uniTagInfo,
-                false, true);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 2;
-
-        // ensure downstream pppoed traps can be added and removed
-        oltFlowService.processPPPoEDFilteringObjectives(nniPort,
-                null, null, null,
-                true, false);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 3;
-        oltFlowService.processPPPoEDFilteringObjectives(nniPort,
-                null, null, null,
-                false, false);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 4;
-
-        // cleanup
-        oltFlowService.flowObjectiveService.clearQueue();
-    }
-
-    @Test
-    public void testIgmpFiltering() {
-        oltFlowService.flowObjectiveService.clearQueue();
-
-        // ensure igmp flows can be added and removed
-        oltFlowService.processIgmpFilteringObjectives(uniPort1,
-                usMeterId, null, uniTagInfo,
-                true, true);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 1;
-        oltFlowService.processIgmpFilteringObjectives(uniPort1, usMeterId,
-                null, uniTagInfo,
-                false, true);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 2;
-
-        // ensure igmp flow is not added if uniTag has no igmp requirement
-        oltFlowService.processIgmpFilteringObjectives(uniPort1,
-                usMeterId, null, uniTagInfoNoDhcpNoIgmp,
-                true, true);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 2;
-
-        //ensure igmp flow on NNI fails without global setting
-        oltFlowService.processIgmpFilteringObjectives(nniPort,
-                null, null, null,
-                true, false);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 2;
-
-        // igmp trap on NNI should succeed with global config
-        oltFlowService.enableIgmpOnNni = true;
-        oltFlowService.processIgmpFilteringObjectives(nniPort,
-                null, null, null,
-                true, false);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 3;
-        // cleanup
-        oltFlowService.flowObjectiveService.clearQueue();
-
-    }
-
-    @Test
-    public void testEapolFiltering() {
-        addBandwidthProfile(uniTagInfo.getUpstreamBandwidthProfile());
-        oltFlowService.enableEapol = true;
-
-        //will install
-        oltFlowService.processEapolFilteringObjectives(uniPort1,
-                uniTagInfo.getUpstreamBandwidthProfile(), Optional.empty(), new CompletableFuture<>(),
-                uniTagInfo.getUniTagMatch(), true);
-
-        //bp profile doesn't exist
-        oltFlowService.processEapolFilteringObjectives(uniPort1,
-                uniTagInfo.getDownstreamBandwidthProfile(), Optional.empty(), new CompletableFuture<>(),
-                uniTagInfo.getUniTagMatch(), true);
-    }
-
-    @Test
-    public void testLldpFiltering() {
-        oltFlowService.processLldpFilteringObjective(nniPort, true);
-        oltFlowService.processLldpFilteringObjective(nniPort, false);
-    }
-
-    @Test
-    public void testNniFiltering() {
-        oltFlowService.flowObjectiveService.clearQueue();
-        oltFlowService.enableDhcpOnNni = true;
-        oltFlowService.enableIgmpOnNni = true;
-        oltFlowService.processNniFilteringObjectives(nniPort, true);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives()
-                .size() == 3;
-        oltFlowService.processNniFilteringObjectives(nniPort, false);
-        assert oltFlowService.flowObjectiveService.getPendingFlowObjectives()
-                .size() == 6;
-        oltFlowService.flowObjectiveService.clearQueue();
-    }
-
-    @Test
-    public void testUpBuilder() {
-        ForwardingObjective objective =
-                oltFlowService.createUpBuilder(nniPort, uniPort1, usMeterId, usMeterId, uniTagInfo).add();
-        checkObjective(objective, true);
-    }
-
-    @Test
-    public void testDownBuilder() {
-        ForwardingObjective objective =
-                oltFlowService.createDownBuilder(nniPort, uniPort1, dsMeterId, dsMeterId, uniTagInfo,
-                        Optional.of(macAddress)).remove();
-        checkObjective(objective, false);
-    }
-
-    private void checkObjective(ForwardingObjective fwd, boolean upstream) {
-        TrafficTreatment treatment = fwd.treatment();
-
-        //check instructions
-        Set<Instructions.MeterInstruction> meters = treatment.meters();
-        assert !meters.isEmpty();
-
-        Instructions.MetadataInstruction writeMetadata = treatment.writeMetadata();
-        assert writeMetadata != null;
-
-        List<Instruction> immediateInstructions = treatment.immediate();
-        Optional<Instruction> vlanInstruction = immediateInstructions.stream()
-                .filter(i -> i.type() == Instruction.Type.L2MODIFICATION)
-                .filter(i -> ((L2ModificationInstruction) i).subtype() ==
-                        L2ModificationInstruction.L2SubType.VLAN_PUSH ||
-                        ((L2ModificationInstruction) i).subtype() ==
-                                L2ModificationInstruction.L2SubType.VLAN_POP)
-                .findAny();
-
-        assert vlanInstruction.isPresent();
-
-        //check match criteria
-        TrafficSelector selector = fwd.selector();
-        assert selector.getCriterion(Criterion.Type.IN_PORT) != null;
-        assert selector.getCriterion(Criterion.Type.VLAN_VID) != null;
-
-        if (!upstream) {
-            assert selector.getCriterion(Criterion.Type.METADATA) != null;
-            assert selector.getCriterion(Criterion.Type.ETH_DST) != null;
-        }
-    }
-
-    private class MockOltMeterService implements org.opencord.olt.internalapi.AccessDeviceMeterService {
-        @Override
-        public ImmutableMap<String, Collection<MeterKey>> getBpMeterMappings() {
-            return null;
-        }
-
-        @Override
-        public MeterId getMeterIdFromBpMapping(DeviceId deviceId, String bandwidthProfile) {
-            return null;
-        }
-
-
-        @Override
-        public ImmutableSet<MeterKey> getProgMeters() {
-            return null;
-        }
-
-        @Override
-        public MeterId createMeter(DeviceId deviceId, BandwidthProfileInformation bpInfo,
-                                   CompletableFuture<Object> meterFuture) {
-            return usMeterId;
-        }
-
-        @Override
-        public void removeFromPendingMeters(DeviceId deviceId, BandwidthProfileInformation bwpInfo) {
-
-        }
-
-        @Override
-        public boolean checkAndAddPendingMeter(DeviceId deviceId, BandwidthProfileInformation bwpInfo) {
-            return false;
-        }
-
-
-        @Override
-        public void clearMeters(DeviceId deviceId) {
-        }
-
-        @Override
-        public void clearDeviceState(DeviceId deviceId) {
-
-        }
-    }
-
-    private class MockOltFlowObjectiveService implements org.onosproject.net.flowobjective.FlowObjectiveService {
-        List<String> flowObjectives = new ArrayList<>();
-
-        @Override
-        public void filter(DeviceId deviceId, FilteringObjective filteringObjective) {
-            flowObjectives.add(filteringObjective.toString());
-            EthTypeCriterion ethType = (EthTypeCriterion)
-                    filterForCriterion(filteringObjective.conditions(), Criterion.Type.ETH_TYPE);
-
-            Instructions.MeterInstruction meter = filteringObjective.meta().metered();
-            Instruction writeMetadata = filteringObjective.meta().writeMetadata();
-            VlanIdCriterion vlanIdCriterion = (VlanIdCriterion)
-                    filterForCriterion(filteringObjective.conditions(), Criterion.Type.VLAN_VID);
-            PortCriterion portCriterion = (PortCriterion) filteringObjective.key();
-
-            filteringObjective.meta().allInstructions().forEach(instruction -> {
-                if (instruction.type().equals(Instruction.Type.L2MODIFICATION)) {
-                    L2ModificationInstruction l2Instruction = (L2ModificationInstruction) instruction;
-                    if (l2Instruction.subtype().equals(L2ModificationInstruction.L2SubType.VLAN_PCP)) {
-                        //this, given the uniTagInfo we provide, should not be present
-                        assert false;
-                    }
-                }
-            });
-
-
-            if (ethType.ethType().equals(EthType.EtherType.LLDP.ethType()) ||
-                    portCriterion.port().equals(nniPort.number())) {
-                assert meter == null;
-                assert writeMetadata == null;
-                assert vlanIdCriterion == null;
-            } else {
-                assert meter.meterId().equals(usMeterId) || meter.meterId().equals(dsMeterId);
-                assert writeMetadata != null;
-                assert vlanIdCriterion == null || vlanIdCriterion.vlanId() == uniTagInfo.getUniTagMatch()
-                        || vlanIdCriterion.vlanId() == uniTagInfoNoPcp.getUniTagMatch();
-            }
-
-        }
-
-        @Override
-        public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
-
-        }
-
-        @Override
-        public void next(DeviceId deviceId, NextObjective nextObjective) {
-
-        }
-
-        @Override
-        public int allocateNextId() {
-            return 0;
-        }
-
-        @Override
-        public void initPolicy(String s) {
-
-        }
-
-        @Override
-        public void apply(DeviceId deviceId, Objective objective) {
-
-        }
-
-        @Override
-        public Map<Pair<Integer, DeviceId>, List<String>> getNextMappingsChain() {
-            return null;
-        }
-
-        @Override
-        public List<String> getNextMappings() {
-            return null;
-        }
-
-        @Override
-        public List<String> getPendingFlowObjectives() {
-            return ImmutableList.copyOf(flowObjectives);
-        }
-
-        @Override
-        public ListMultimap<FilteringObjQueueKey, Objective> getFilteringObjQueue() {
-            return null;
-        }
-
-        @Override
-        public ListMultimap<ForwardingObjQueueKey, Objective> getForwardingObjQueue() {
-            return null;
-        }
-
-        @Override
-        public ListMultimap<NextObjQueueKey, Objective> getNextObjQueue() {
-            return null;
-        }
-
-        @Override
-        public Map<FilteringObjQueueKey, Objective> getFilteringObjQueueHead() {
-            return null;
-        }
-
-        @Override
-        public Map<ForwardingObjQueueKey, Objective> getForwardingObjQueueHead() {
-            return null;
-        }
-
-        @Override
-        public Map<NextObjQueueKey, Objective> getNextObjQueueHead() {
-            return null;
-        }
-
-        @Override
-        public void clearQueue() {
-            flowObjectives.clear();
-        }
-
-        private Criterion filterForCriterion(Collection<Criterion> criteria, Criterion.Type type) {
-            return criteria.stream()
-                    .filter(c -> c.type().equals(type))
-                    .limit(1)
-                    .findFirst().orElse(null);
-        }
-    }
-
-    private class MockMastershipService implements org.onosproject.mastership.MastershipService {
-        @Override
-        public MastershipRole getLocalRole(DeviceId deviceId) {
-            return null;
-        }
-
-        @Override
-        public boolean isLocalMaster(DeviceId deviceId) {
-            return true;
-        }
-
-        @Override
-        public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
-            return null;
-        }
-
-        @Override
-        public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
-            return null;
-        }
-
-        @Override
-        public NodeId getMasterFor(DeviceId deviceId) {
-            return null;
-        }
-
-        @Override
-        public RoleInfo getNodesFor(DeviceId deviceId) {
-            return null;
-        }
-
-        @Override
-        public MastershipInfo getMastershipFor(DeviceId deviceId) {
-            return null;
-        }
-
-        @Override
-        public Set<DeviceId> getDevicesOf(NodeId nodeId) {
-            return null;
-        }
-
-        @Override
-        public void addListener(MastershipListener mastershipListener) {
-
-        }
-
-        @Override
-        public void removeListener(MastershipListener mastershipListener) {
-
-        }
-    }
-}
diff --git a/impl/src/test/java/org/opencord/olt/impl/OltMeterServiceTest.java b/impl/src/test/java/org/opencord/olt/impl/OltMeterServiceTest.java
new file mode 100644
index 0000000..a7d653c
--- /dev/null
+++ b/impl/src/test/java/org/opencord/olt/impl/OltMeterServiceTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterServiceAdapter;
+import org.onosproject.net.meter.MeterState;
+import org.onosproject.store.service.StorageServiceAdapter;
+import org.onosproject.store.service.TestStorageService;
+import org.opencord.sadis.SadisService;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_BP_ID_DEFAULT;
+
+public class OltMeterServiceTest extends OltTestHelpers {
+    OltMeterService oltMeterService;
+    OltMeterService component;
+
+    DeviceId deviceId = DeviceId.deviceId("foo");
+
+    @Before
+    public void setUp() {
+        component = new OltMeterService();
+        component.cfgService = new ComponentConfigAdapter();
+        component.coreService = new CoreServiceAdapter();
+        component.storageService = new StorageServiceAdapter();
+        component.sadisService = Mockito.mock(SadisService.class);
+        component.meterService = new MeterServiceAdapter();
+        component.storageService = new TestStorageService();
+        component.activate(null);
+        oltMeterService = Mockito.spy(component);
+    }
+
+    @After
+    public void tearDown() {
+        component.deactivate(null);
+    }
+
+    @Test
+    public void testHasMeter() {
+
+        MeterData meterPending = new MeterData(MeterId.meterId(1),
+                MeterState.PENDING_ADD, "pending");
+        MeterData meterAdded = new MeterData(MeterId.meterId(2),
+                MeterState.ADDED, DEFAULT_BP_ID_DEFAULT);
+
+        Map<String, MeterData> deviceMeters = new HashMap<>();
+        deviceMeters.put("pending", meterPending);
+        deviceMeters.put(DEFAULT_BP_ID_DEFAULT, meterAdded);
+        oltMeterService.programmedMeters.put(deviceId, deviceMeters);
+
+        assert oltMeterService.hasMeterByBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT);
+        assert !oltMeterService.hasMeterByBandwidthProfile(deviceId, "pending");
+        assert !oltMeterService.hasMeterByBandwidthProfile(deviceId, "someBandwidthProfile");
+
+        assert !oltMeterService.hasMeterByBandwidthProfile(DeviceId.deviceId("bar"), DEFAULT_BP_ID_DEFAULT);
+    }
+
+    @Test
+    public void testGetMeterId() {
+
+        MeterData meterAdded = new MeterData(MeterId.meterId(2),
+                MeterState.ADDED, DEFAULT_BP_ID_DEFAULT);
+
+        Map<String, MeterData> deviceMeters = new HashMap<>();
+        deviceMeters.put(DEFAULT_BP_ID_DEFAULT, meterAdded);
+        oltMeterService.programmedMeters.put(deviceId, deviceMeters);
+
+        Assert.assertNull(oltMeterService.getMeterIdForBandwidthProfile(deviceId, "pending"));
+        Assert.assertEquals(MeterId.meterId(2),
+                oltMeterService.getMeterIdForBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT));
+    }
+
+    @Test
+    public void testCreateMeter() {
+
+        DeviceId deviceId = DeviceId.deviceId("foo");
+        String bp = "Default";
+
+        // if we already have a meter do nothing and return true
+        doReturn(true).when(oltMeterService).hasMeterByBandwidthProfile(deviceId, bp);
+        Assert.assertTrue(oltMeterService.createMeter(deviceId, bp));
+        verify(oltMeterService, never()).createMeterForBp(any(), any());
+
+        // if we have a pending meter, do nothing and return false
+        doReturn(false).when(oltMeterService).hasMeterByBandwidthProfile(deviceId, bp);
+        doReturn(true).when(oltMeterService).hasPendingMeterByBandwidthProfile(deviceId, bp);
+        Assert.assertFalse(oltMeterService.createMeter(deviceId, bp));
+        verify(oltMeterService, never()).createMeterForBp(any(), any());
+
+        // if the meter is not present at all, create it and return false
+        doReturn(false).when(oltMeterService).hasMeterByBandwidthProfile(deviceId, bp);
+        doReturn(false).when(oltMeterService).hasPendingMeterByBandwidthProfile(deviceId, bp);
+        Assert.assertFalse(oltMeterService.createMeter(deviceId, bp));
+        verify(oltMeterService, times(1)).createMeterForBp(deviceId, bp);
+    }
+
+    @Test
+    public void testConcurrentMeterCreation() throws InterruptedException {
+
+        ExecutorService executor = Executors.newFixedThreadPool(4);
+
+        DeviceId deviceId = DeviceId.deviceId("foo");
+        String bp = "Default";
+
+        // try to create 4 meters at the same time, only one should be created
+        for (int i = 0; i < 4; i++) {
+
+            executor.execute(() -> {
+                oltMeterService.createMeter(deviceId, bp);
+            });
+        }
+
+        TimeUnit.MILLISECONDS.sleep(600);
+
+        verify(oltMeterService, times(4)).hasMeterByBandwidthProfile(deviceId, bp);
+        verify(oltMeterService, times(1)).createMeterForBp(deviceId, bp);
+    }
+}
\ No newline at end of file
diff --git a/impl/src/test/java/org/opencord/olt/impl/OltMeterTest.java b/impl/src/test/java/org/opencord/olt/impl/OltMeterTest.java
deleted file mode 100644
index 000ea35..0000000
--- a/impl/src/test/java/org/opencord/olt/impl/OltMeterTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.opencord.olt.impl;
-
-import com.google.common.collect.ImmutableMap;
-import org.junit.Before;
-import org.junit.Test;
-import org.onosproject.cfg.ComponentConfigAdapter;
-import org.onosproject.core.CoreServiceAdapter;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.meter.DefaultMeter;
-import org.onosproject.net.meter.Meter;
-import org.onosproject.net.meter.MeterId;
-import org.onosproject.net.meter.MeterKey;
-import org.onosproject.net.meter.MeterListener;
-import org.onosproject.net.meter.MeterRequest;
-import org.onosproject.store.service.TestStorageService;
-import org.opencord.sadis.BandwidthProfileInformation;
-
-import java.util.Collection;
-import java.util.concurrent.CompletableFuture;
-
-public class OltMeterTest extends TestBase {
-    private OltMeterService oltMeterService;
-
-    private BandwidthProfileInformation bandwidthProfileInformation = new BandwidthProfileInformation();
-
-    @Before
-    public void setUp() {
-        oltMeterService = new OltMeterService();
-        oltMeterService.storageService = new TestStorageService();
-        oltMeterService.meterService = new MockMeterService();
-        oltMeterService.coreService = new CoreServiceAdapter();
-        oltMeterService.componentConfigService = new ComponentConfigAdapter();
-        oltMeterService.activate(null);
-        oltMeterService.bpInfoToMeter = new MockConsistentMultimap<>();
-    }
-
-    @Test
-    public void testAddAndGetMeterIdToBpMapping() {
-        oltMeterService.addMeterIdToBpMapping(DEVICE_ID_1, usMeterId, usBpId);
-        MeterId usMeterId = oltMeterService.getMeterIdFromBpMapping(DEVICE_ID_1, usBpId);
-        assert usMeterId.equals(this.usMeterId);
-
-        oltMeterService.addMeterIdToBpMapping(DEVICE_ID_1, dsMeterId, dsBpId);
-        MeterId dsMeterId = oltMeterService.getMeterIdFromBpMapping(DEVICE_ID_1, dsBpId);
-        assert  dsMeterId.equals(this.dsMeterId);
-
-        ImmutableMap<String, Collection<MeterKey>> meterMappings = oltMeterService.getBpMeterMappings();
-        assert  meterMappings.size() == 2;
-    }
-
-    @Test
-    public void testCreateMeter() {
-        //with provided bandwidth profile information
-        bandwidthProfileInformation.setId(usBpId);
-        bandwidthProfileInformation.setExceededInformationRate(10000);
-        bandwidthProfileInformation.setExceededBurstSize(10000L);
-        bandwidthProfileInformation.setCommittedBurstSize(10000L);
-        bandwidthProfileInformation.setCommittedInformationRate(10000);
-
-        oltMeterService.addMeterIdToBpMapping(DEVICE_ID_1, usMeterId, usBpId);
-
-
-        MeterId meterId =
-                oltMeterService.createMeter(DEVICE_ID_1, bandwidthProfileInformation, new CompletableFuture<>());
-        assert meterId != null;
-
-        //with null bandwidth profile information
-        meterId = oltMeterService.createMeter(DEVICE_ID_1, null, new CompletableFuture<>());
-        assert meterId == null;
-    }
-
-
-    private class MockMeterService implements org.onosproject.net.meter.MeterService {
-        @Override
-        public Meter submit(MeterRequest meterRequest) {
-            return DefaultMeter.builder()
-                    .forDevice(DEVICE_ID_1)
-                    .fromApp(appId)
-                    .withId(usMeterId)
-                    .build();
-        }
-
-        @Override
-        public void withdraw(MeterRequest meterRequest, MeterId meterId) {
-
-        }
-
-        @Override
-        public Meter getMeter(DeviceId deviceId, MeterId meterId) {
-            return null;
-        }
-
-        @Override
-        public Collection<Meter> getAllMeters() {
-            return null;
-        }
-
-        @Override
-        public Collection<Meter> getMeters(DeviceId deviceId) {
-            return null;
-        }
-
-        @Override
-        public MeterId allocateMeterId(DeviceId deviceId) {
-            return null;
-        }
-
-        @Override
-        public void freeMeterId(DeviceId deviceId, MeterId meterId) {
-
-        }
-
-        @Override
-        public void addListener(MeterListener meterListener) {
-
-        }
-
-        @Override
-        public void removeListener(MeterListener meterListener) {
-
-        }
-    }
-}
diff --git a/impl/src/test/java/org/opencord/olt/impl/OltTest.java b/impl/src/test/java/org/opencord/olt/impl/OltTest.java
index af63004..e8a76d0 100644
--- a/impl/src/test/java/org/opencord/olt/impl/OltTest.java
+++ b/impl/src/test/java/org/opencord/olt/impl/OltTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,155 +13,196 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.opencord.olt.impl;
 
-import static org.junit.Assert.assertEquals;
-
-import java.util.Set;
-
-import com.google.common.collect.Maps;
+import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
 import org.onlab.packet.ChassisId;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
 import org.onosproject.net.AnnotationKeys;
-import org.onosproject.net.Annotations;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultAnnotations;
 import org.onosproject.net.DefaultDevice;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.Element;
 import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.TestStorageService;
+import org.opencord.sadis.SadisService;
 import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.opencord.sadis.UniTagInformation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class OltTest extends TestBase {
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_BP_ID_DEFAULT;
+
+/**
+ * Set of tests of the ONOS application component.
+ */
+
+@RunWith(MockitoJUnitRunner.class)
+public class OltTest extends OltTestHelpers {
+
+    private Olt component;
+    private final ApplicationId testAppId = new DefaultApplicationId(1, "org.opencord.olt.test");
     private final Logger log = LoggerFactory.getLogger(getClass());
-    private Olt olt;
 
-
-    private static final String SCHEME_NAME = "olt";
-    private static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
-            .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
+    private DeviceId deviceId = DeviceId.deviceId("test-device");
+    private Device testDevice = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.OLT,
+            "testManufacturer", "1.0", "1.0", "SN", new ChassisId(1));
+    private Port uniUpdateEnabled = new OltPort(testDevice, true, PortNumber.portNumber(16),
+                                                DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "uni-1")
+                                                        .build());
+    private ConnectPoint cp = new ConnectPoint(deviceId, uniUpdateEnabled.number());
+    private DiscoveredSubscriber sub;
 
     @Before
     public void setUp() {
-        olt = new Olt();
-        olt.deviceService = new MockDeviceService();
-        olt.sadisService = new MockSadisService();
-        olt.subsService = olt.sadisService.getSubscriberInfoService();
-        olt.pendingSubscribersForDevice = Maps.newConcurrentMap();
+        component = new Olt();
+        component.requeueDelay = 0; // avoid delays in the queue add to make things easier in testing
+        component.cfgService = new ComponentConfigAdapter();
+        component.deviceService = Mockito.mock(DeviceService.class);
+        component.storageService = new TestStorageService();
+        component.coreService = Mockito.spy(new CoreServiceAdapter());
+        component.oltDeviceService = Mockito.mock(OltDeviceService.class);
+
+        doReturn(testAppId).when(component.coreService).registerApplication("org.opencord.olt");
+
+        component.discoveredSubscriberExecutor =
+                Executors.newSingleThreadScheduledExecutor(
+                        groupedThreads("onos/olt",
+                "discovered-cp-%d", log));
+        component.flowsExecutor =
+                Executors.newFixedThreadPool(component.flowProcessingThreads,
+                                             groupedThreads("onos/olt-service",
+                                                            "flows-installer-%d"));
+
+        component.subscriberExecutor = Executors.newFixedThreadPool(component.subscriberProcessingThreads,
+                                                          groupedThreads("onos/olt-service",
+                                                                         "subscriber-installer-%d"));
+        SadisService sadisService = Mockito.mock(SadisService.class);
+        component.oltFlowService = Mockito.mock(OltFlowService.class);
+        component.sadisService = sadisService;
+
+        // reset the spy on oltFlowService
+        reset(component.oltFlowService);
+
+        component.bindSadisService(sadisService);
+        component.eventsQueues = component.storageService.
+                <ConnectPoint, LinkedBlockingQueue<DiscoveredSubscriber>>consistentMapBuilder().build().asJavaMap();
+        component.eventsQueues.put(cp, new LinkedBlockingQueue<>());
+
+        component.discoveredSubscriberExecutor.execute(() -> {
+            component.processDiscoveredSubscribers();
+        });
+        // create empty service for testing
+        List<UniTagInformation> uniTagInformationList = new LinkedList<>();
+        UniTagInformation empty = new UniTagInformation.Builder().build();
+        uniTagInformationList.add(empty);
+        SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
+        si.setUniTagList(uniTagInformationList);
+        sub = new DiscoveredSubscriber(testDevice,
+                                         uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
+                                         false, si);
     }
 
-    /**
-     * Tests that the getSubscriber method does throw a NullPointerException with a meaningful message.
-     */
+    @After
+    public void tearDown() {
+        component.deactivate(null);
+    }
+
     @Test
-    public void testGetSubscriberError() {
-        ConnectPoint cp = ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1);
-        try {
-            olt.getSubscriber(cp);
-        } catch (NullPointerException e) {
-            assertEquals(e.getMessage(), "Invalid connect point");
-        }
+    public void testProcessDiscoveredSubscribersBasicPortSuccess() throws Exception {
+        doReturn(true).when(component.deviceService).isAvailable(any());
+        doReturn(sub.port).when(component.deviceService).getPort(any(), any());
+        doReturn(true).when(component.oltFlowService).handleBasicPortFlows(eq(sub), eq(DEFAULT_BP_ID_DEFAULT),
+                eq(DEFAULT_BP_ID_DEFAULT));
+        doReturn(true).when(component.oltDeviceService).isLocalLeader(cp.deviceId());
+
+        // adding the discovered subscriber to the queue
+        LinkedBlockingQueue<DiscoveredSubscriber> q = component.eventsQueues.get(cp);
+        q.add(sub);
+        component.eventsQueues.put(cp, q);
+
+        // check that we're calling the correct method
+        TimeUnit.MILLISECONDS.sleep(600);
+        verify(component.oltFlowService, atLeastOnce()).handleBasicPortFlows(eq(sub), eq(DEFAULT_BP_ID_DEFAULT),
+                eq(DEFAULT_BP_ID_DEFAULT));
+
+        // check if the method doesn't throw an exception we're removing the subscriber from the queue
+        LinkedBlockingQueue<DiscoveredSubscriber> updatedQueue = component.eventsQueues.get(cp);
+        assert updatedQueue.isEmpty();
     }
 
-    /**
-     * Tests that the getSubscriber method returns Subscriber informations.
-     */
     @Test
-    public void testGetSubscriber() {
-        ConnectPoint cp = ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 2);
+    public void testProcessDiscoveredSubscribersBasicPortException() throws Exception {
+        doReturn(true).when(component.deviceService).isAvailable(any());
+        doReturn(sub.port).when(component.deviceService).getPort(any(), any());
+        doReturn(false).when(component.oltFlowService).handleBasicPortFlows(any(), eq(DEFAULT_BP_ID_DEFAULT),
+                eq(DEFAULT_BP_ID_DEFAULT));
+        doReturn(true).when(component.oltDeviceService).isLocalLeader(cp.deviceId());
+        // replace the queue with a spy
+        LinkedBlockingQueue<DiscoveredSubscriber> q = component.eventsQueues.get(cp);
+        LinkedBlockingQueue<DiscoveredSubscriber> spiedQueue = spy(q);
+        // adding the discovered subscriber to the queue
+        spiedQueue.add(sub);
+        component.eventsQueues.put(cp, spiedQueue);
 
-        SubscriberAndDeviceInformation s = olt.getSubscriber(cp);
+        TimeUnit.MILLISECONDS.sleep(600);
 
-        assertEquals(s.circuitId(), CLIENT_CIRCUIT_ID);
-        assertEquals(s.nasPortId(), CLIENT_NAS_PORT_ID);
+        // check that we're calling the correct method,
+        // since the subscriber is not removed from the queue we're calling the method multiple times
+        verify(component.oltFlowService, atLeastOnce()).handleBasicPortFlows(eq(sub), eq(DEFAULT_BP_ID_DEFAULT),
+                eq(DEFAULT_BP_ID_DEFAULT));
+
+        // check if the method throws an exception we are not removing the subscriber from the queue
+        verify(spiedQueue, never()).remove(sub);
     }
 
-    private class MockDevice extends DefaultDevice {
+    @Test
+    public void testAddSubscriberToQueue() {
 
-        public MockDevice(ProviderId providerId, DeviceId id, Type type,
-                          String manufacturer, String hwVersion, String swVersion,
-                          String serialNumber, ChassisId chassisId, Annotations... annotations) {
-            super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber,
-                    chassisId, annotations);
-        }
+        // replace the queue with a spy
+        LinkedBlockingQueue<DiscoveredSubscriber> q = component.eventsQueues.get(cp);
+        LinkedBlockingQueue<DiscoveredSubscriber> spiedQueue = spy(q);
+        component.eventsQueues.put(cp, spiedQueue);
+
+        // trying to add the same event twice should result in a single item in the queue
+        component.addSubscriberToQueue(sub);
+        component.addSubscriberToQueue(sub);
+
+        verify(spiedQueue, times(1)).add(sub);
+        Assert.assertEquals(1, spiedQueue.size());
+
+
+
     }
 
-    private class MockDeviceService extends DeviceServiceAdapter {
-
-        private ProviderId providerId = new ProviderId("of", "foo");
-        private final Device device1 = new MockDevice(providerId, DEVICE_ID_1, Device.Type.SWITCH,
-                "foo.inc", "0", "0", OLT_DEV_ID, new ChassisId(),
-                DEVICE_ANNOTATIONS);
-
-        @Override
-        public Device getDevice(DeviceId devId) {
-            return device1;
-
-        }
-
-        @Override
-        public Port getPort(ConnectPoint cp) {
-            log.info("Looking up port {}", cp.port().toString());
-            if (cp.port().toString().equals("1")) {
-                return null;
-            }
-            return new MockPort();
-        }
-    }
-
-    private class MockPort implements Port {
-
-        @Override
-        public boolean isEnabled() {
-            return true;
-        }
-
-        @Override
-        public long portSpeed() {
-            return 1000;
-        }
-
-        @Override
-        public Element element() {
-            return null;
-        }
-
-        @Override
-        public PortNumber number() {
-            return null;
-        }
-
-        @Override
-        public Annotations annotations() {
-            return new MockAnnotations();
-        }
-
-        @Override
-        public Type type() {
-            return Port.Type.FIBER;
-        }
-
-        private class MockAnnotations implements Annotations {
-
-            @Override
-            public String value(String val) {
-                return "BRCM12345678";
-            }
-
-            @Override
-            public Set<String> keys() {
-                return null;
-            }
-        }
-    }
-
-
-}
\ No newline at end of file
+}
diff --git a/impl/src/test/java/org/opencord/olt/impl/OltTestHelpers.java b/impl/src/test/java/org/opencord/olt/impl/OltTestHelpers.java
new file mode 100644
index 0000000..6965bd2
--- /dev/null
+++ b/impl/src/test/java/org/opencord/olt/impl/OltTestHelpers.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.olt.impl;
+
+import com.google.common.collect.Maps;
+import org.mockito.ArgumentMatcher;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.Element;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.opencord.sadis.BandwidthProfileInformation;
+
+import java.util.Map;
+
+@SuppressWarnings("checkstyle:HideUtilityClassConstructor")
+public class OltTestHelpers {
+
+    protected static final String CLIENT_NAS_PORT_ID = "PON 1/1";
+    protected static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
+    protected static final String OLT_DEV_ID = "of:00000000000000aa";
+    Map<String, BandwidthProfileInformation> bpInformation = Maps.newConcurrentMap();
+
+    protected class FilteringObjectiveMatcher extends ArgumentMatcher<FilteringObjective> {
+
+        private FilteringObjective left;
+
+        public FilteringObjectiveMatcher(FilteringObjective left) {
+            this.left = left;
+        }
+
+        @Override
+        public boolean matches(Object right) {
+            // NOTE this matcher can be improved
+            FilteringObjective r = (FilteringObjective) right;
+            boolean matches = left.type().equals(r.type()) &&
+                    left.key().equals(r.key()) &&
+                    left.conditions().equals(r.conditions()) &&
+                    left.appId().equals(r.appId()) &&
+                    left.priority() == r.priority();
+
+            if (left.meta() != null) {
+                if (left.meta().equals(r.meta())) {
+                    return matches;
+                } else {
+                    return false;
+                }
+            }
+            return matches;
+        }
+    }
+
+    public class OltPort implements Port {
+
+        public boolean enabled;
+        public PortNumber portNumber;
+        public Annotations annotations;
+        public Element element;
+
+        public OltPort(Element element, boolean enabled, PortNumber portNumber, Annotations annotations) {
+            this.enabled = enabled;
+            this.portNumber = portNumber;
+            this.annotations = annotations;
+            this.element = element;
+        }
+
+        @Override
+        public Element element() {
+            return element;
+        }
+
+        @Override
+        public PortNumber number() {
+            return portNumber;
+        }
+
+        @Override
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        @Override
+        public Type type() {
+            return null;
+        }
+
+        @Override
+        public long portSpeed() {
+            return 0;
+        }
+
+        @Override
+        public Annotations annotations() {
+            return annotations;
+        }
+    }
+}
diff --git a/impl/src/test/java/org/opencord/olt/impl/TestBase.java b/impl/src/test/java/org/opencord/olt/impl/TestBase.java
deleted file mode 100644
index 87db5d1..0000000
--- a/impl/src/test/java/org/opencord/olt/impl/TestBase.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.opencord.olt.impl;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multiset;
-import org.onlab.packet.ChassisId;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.MacAddress;
-import org.onosproject.core.DefaultApplicationId;
-import org.onosproject.net.DefaultDevice;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.meter.MeterId;
-import org.onosproject.store.service.AsyncConsistentMultimap;
-import org.onosproject.store.service.ConsistentMultimap;
-import org.onosproject.store.service.ConsistentMultimapBuilder;
-import org.onosproject.store.service.MultimapEventListener;
-import org.onosproject.store.service.TestConsistentMultimap;
-import org.onosproject.store.service.Versioned;
-import org.opencord.sadis.BandwidthProfileInformation;
-import org.opencord.sadis.BaseInformationService;
-import org.opencord.sadis.SadisService;
-import org.opencord.sadis.SubscriberAndDeviceInformation;
-
-import java.util.AbstractMap;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.stream.Collectors;
-
-public class TestBase {
-
-    protected static final String CLIENT_NAS_PORT_ID = "PON 1/1";
-    protected static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
-    protected static final String OLT_DEV_ID = "of:00000000000000aa";
-    protected static final DeviceId DEVICE_ID_1 = DeviceId.deviceId(OLT_DEV_ID);
-    protected MeterId usMeterId = MeterId.meterId(1);
-    protected MeterId dsMeterId = MeterId.meterId(2);
-    protected MeterId usOltMeterId = MeterId.meterId(3);
-    protected MeterId dsOltMeterId = MeterId.meterId(4);
-    protected String usBpId = "HSIA-US";
-    protected String dsBpId = "HSIA-DS";
-    protected DefaultApplicationId appId = new DefaultApplicationId(1, "OltServices");
-
-    protected static Device olt = new DefaultDevice(null, DeviceId.deviceId(OLT_DEV_ID), Device.Type.SWITCH,
-            "VOLTHA Project", "open_pon", "open_pon", "BBSIM_OLT_1", new ChassisId("a0a0a0a0a01"));
-
-    Map<String, BandwidthProfileInformation> bpInformation = Maps.newConcurrentMap();
-
-    protected void addBandwidthProfile(String id) {
-        BandwidthProfileInformation bpInfo = new BandwidthProfileInformation();
-        bpInfo.setGuaranteedInformationRate(0);
-        bpInfo.setCommittedInformationRate(10000);
-        bpInfo.setCommittedBurstSize(1000L);
-        bpInfo.setExceededBurstSize(2000L);
-        bpInfo.setExceededInformationRate(20000);
-        bpInformation.put(id, bpInfo);
-    }
-
-    protected class MockSadisService implements SadisService {
-
-        @Override
-        public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
-            return new MockSubService();
-        }
-
-        @Override
-        public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
-            return new MockBpService();
-        }
-    }
-
-    private class MockBpService implements BaseInformationService<BandwidthProfileInformation> {
-        @Override
-        public void clearLocalData() {
-
-        }
-
-        @Override
-        public void invalidateAll() {
-
-        }
-
-        @Override
-        public void invalidateId(String id) {
-
-        }
-
-        @Override
-        public BandwidthProfileInformation get(String id) {
-            return bpInformation.get(id);
-        }
-
-        @Override
-        public BandwidthProfileInformation getfromCache(String id) {
-            return null;
-        }
-    }
-
-    private class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
-        MockSubscriberAndDeviceInformation sub =
-                new MockSubscriberAndDeviceInformation(CLIENT_NAS_PORT_ID,
-                        CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null);
-
-        @Override
-        public SubscriberAndDeviceInformation get(String id) {
-            return sub;
-        }
-
-        @Override
-        public void clearLocalData() {
-
-        }
-
-        @Override
-        public void invalidateAll() {
-        }
-
-        @Override
-        public void invalidateId(String id) {
-        }
-
-        @Override
-        public SubscriberAndDeviceInformation getfromCache(String id) {
-            return null;
-        }
-    }
-
-    private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
-
-        MockSubscriberAndDeviceInformation(String id, String nasPortId,
-                                           String circuitId, MacAddress hardId,
-                                           Ip4Address ipAddress) {
-            this.setHardwareIdentifier(hardId);
-            this.setId(id);
-            this.setIPAddress(ipAddress);
-            this.setNasPortId(nasPortId);
-            this.setCircuitId(circuitId);
-        }
-    }
-
-    class MockConsistentMultimap<K, V> implements ConsistentMultimap<K, V> {
-        private HashMultimap<K, Versioned<V>> innermap;
-        private AtomicLong counter = new AtomicLong();
-
-        public MockConsistentMultimap() {
-            this.innermap = HashMultimap.create();
-        }
-
-        private Versioned<V> version(V v) {
-            return new Versioned<>(v, counter.incrementAndGet(), System.currentTimeMillis());
-        }
-
-        private Versioned<Collection<? extends V>> versionCollection(Collection<? extends V> collection) {
-            return new Versioned<>(collection, counter.incrementAndGet(), System.currentTimeMillis());
-        }
-
-        @Override
-        public int size() {
-            return innermap.size();
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return innermap.isEmpty();
-        }
-
-        @Override
-        public boolean containsKey(K key) {
-            return innermap.containsKey(key);
-        }
-
-        @Override
-        public boolean containsValue(V value) {
-            return innermap.containsValue(value);
-        }
-
-        @Override
-        public boolean containsEntry(K key, V value) {
-            return innermap.containsEntry(key, value);
-        }
-
-        @Override
-        public boolean put(K key, V value) {
-            return innermap.put(key, version(value));
-        }
-
-        @Override
-        public Versioned<Collection<? extends V>> putAndGet(K key, V value) {
-            innermap.put(key, version(value));
-            return (Versioned<Collection<? extends V>>) innermap.get(key);
-        }
-
-        @Override
-        public boolean remove(K key, V value) {
-            return innermap.remove(key, value);
-        }
-
-        @Override
-        public Versioned<Collection<? extends V>> removeAndGet(K key, V value) {
-            innermap.remove(key, value);
-            return (Versioned<Collection<? extends V>>) innermap.get(key);
-        }
-
-        @Override
-        public boolean removeAll(K key, Collection<? extends V> values) {
-            return false;
-        }
-
-        @Override
-        public Versioned<Collection<? extends V>> removeAll(K key) {
-            return null;
-        }
-
-        @Override
-        public boolean removeAll(Map<K, Collection<? extends V>> mapping) {
-            return false;
-        }
-
-        @Override
-        public boolean putAll(K key, Collection<? extends V> values) {
-            return false;
-        }
-
-        @Override
-        public boolean putAll(Map<K, Collection<? extends V>> mapping) {
-            return false;
-        }
-
-        @Override
-        public Versioned<Collection<? extends V>> replaceValues(K key, Collection<V> values) {
-            return null;
-        }
-
-        @Override
-        public void clear() {
-            innermap.clear();
-        }
-
-        @Override
-        public Versioned<Collection<? extends V>> get(K key) {
-            Collection<? extends V> values = innermap.get(key).stream()
-                    .map(v -> v.value())
-                    .collect(Collectors.toList());
-            return versionCollection(values);
-        }
-
-        @Override
-        public Set<K> keySet() {
-            return innermap.keySet();
-        }
-
-        @Override
-        public Multiset<K> keys() {
-            return innermap.keys();
-        }
-
-        @Override
-        public Multiset<V> values() {
-            return null;
-        }
-
-        @Override
-        public Collection<Map.Entry<K, V>> entries() {
-            return null;
-        }
-
-        @Override
-        public Iterator<Map.Entry<K, V>> iterator() {
-            return new ConsistentMultimapIterator(innermap.entries().iterator());
-        }
-
-        @Override
-        public Map<K, Collection<V>> asMap() {
-            return null;
-        }
-
-        @Override
-        public void addListener(MultimapEventListener<K, V> listener, Executor executor) {
-        }
-
-        @Override
-        public void removeListener(MultimapEventListener<K, V> listener) {
-        }
-
-        @Override
-        public String name() {
-            return "mock multimap";
-        }
-
-        @Override
-        public Type primitiveType() {
-            return null;
-        }
-
-        private class ConsistentMultimapIterator implements Iterator<Map.Entry<K, V>> {
-
-            private final Iterator<Map.Entry<K, Versioned<V>>> it;
-
-            public ConsistentMultimapIterator(Iterator<Map.Entry<K, Versioned<V>>> it) {
-                this.it = it;
-            }
-
-            @Override
-            public boolean hasNext() {
-                return it.hasNext();
-            }
-
-            @Override
-            public Map.Entry<K, V> next() {
-                Map.Entry<K, Versioned<V>> e = it.next();
-                return new AbstractMap.SimpleEntry<>(e.getKey(), e.getValue().value());
-            }
-        }
-
-    }
-
-    public static TestConsistentMultimap.Builder builder() {
-        return new TestConsistentMultimap.Builder();
-    }
-
-    public static class Builder<K, V> extends ConsistentMultimapBuilder<K, V> {
-
-        @Override
-        public AsyncConsistentMultimap<K, V> buildMultimap() {
-            return null;
-        }
-
-        @Override
-        public ConsistentMultimap<K, V> build() {
-            return new TestConsistentMultimap<K, V>();
-        }
-    }
-}
diff --git a/pom.xml b/pom.xml
index a8fa27a..dd82c5d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  ~ Copyright 2015-present Open Networking Foundation
+  ~ Copyright 2021 Open Networking Foundation
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,34 +14,30 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.onosproject</groupId>
-        <artifactId>onos-dependencies</artifactId>
-        <version>2.5.2</version>
-    </parent>
-
-    <groupId>org.opencord</groupId>
-    <artifactId>olt</artifactId>
-    <version>4.6.0-SNAPSHOT</version>
-    <packaging>pom</packaging>
-
-    <properties>
-        <sadis.api.version>5.4.0</sadis.api.version>
-        <olt.api.version>4.6.0-SNAPSHOT</olt.api.version>
-    </properties>
-
     <modules>
         <module>api</module>
         <module>impl</module>
         <module>web</module>
         <module>app</module>
     </modules>
-
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-dependencies</artifactId>
+        <version>2.5.2</version>
+    </parent>
+    <groupId>org.opencord</groupId>
+    <artifactId>olt</artifactId>
+    <version>5.0.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <description>OLT Application</description>
+    <url>http://onosproject.org</url>
+    <properties>
+        <sadis.api.version>5.5.0-SNAPSHOT</sadis.api.version>
+        <olt.api.version>5.0.0-SNAPSHOT</olt.api.version>
+    </properties>
     <dependencies>
         <dependency>
             <groupId>org.onosproject</groupId>
@@ -56,9 +52,7 @@
             <version>${onos.version}</version>
             <scope>provided</scope>
         </dependency>
-
     </dependencies>
-
     <build>
         <plugins>
             <plugin>
@@ -90,7 +84,6 @@
             </plugin>
         </plugins>
     </build>
-
     <repositories>
         <repository>
             <id>central</id>
diff --git a/spotbugs-security-exclude.xml b/spotbugs-security-exclude.xml
index 4aa0021..d16aa3c 100644
--- a/spotbugs-security-exclude.xml
+++ b/spotbugs-security-exclude.xml
@@ -1,5 +1,5 @@
 <!--
-  ~ Copyright 2020-present Open Networking Foundation
+  ~ Copyright 2021-present Open Networking Foundation
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,4 +14,7 @@
   ~ limitations under the License.
   -->
 <FindBugsFilter>
+    <Match>
+        <Bug pattern="CRLF_INJECTION_LOGS"/>
+    </Match>
 </FindBugsFilter>
\ No newline at end of file
diff --git a/spotbugs-security-include.xml b/spotbugs-security-include.xml
index b3b408f..5341623 100644
--- a/spotbugs-security-include.xml
+++ b/spotbugs-security-include.xml
@@ -1,5 +1,5 @@
 <!--
-  ~ Copyright 2020-present Open Networking Foundation
+  ~ Copyright 2021-present Open Networking Foundation
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
diff --git a/web/pom.xml b/web/pom.xml
index 7c64f96..6b95b8d 100644
--- a/web/pom.xml
+++ b/web/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  ~ Copyright 2016-present Open Networking Foundation
+  ~ Copyright 2021 Open Networking Foundation
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -18,12 +18,10 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <groupId>org.opencord</groupId>
         <artifactId>olt</artifactId>
-        <version>4.6.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
+        <groupId>org.opencord</groupId>
+        <version>5.0.0-SNAPSHOT</version>
     </parent>
-
     <modelVersion>4.0.0</modelVersion>
     <artifactId>olt-web</artifactId>
     <packaging>bundle</packaging>
@@ -38,70 +36,19 @@
         </api.description>
         <api.package>org.opencord.olt.rest</api.package>
     </properties>
-
     <dependencies>
         <dependency>
-            <groupId>org.opencord</groupId>
-            <artifactId>olt-api</artifactId>
-            <version>${olt.api.version}</version>
-            <scope>compile</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.opencord</groupId>
-            <artifactId>olt-impl</artifactId>
-            <version>${project.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.opencord</groupId>
-            <artifactId>sadis-api</artifactId>
-            <version>${sadis.api.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.onosproject</groupId>
-            <artifactId>onos-cli</artifactId>
-            <version>${onos.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.onosproject</groupId>
-            <artifactId>onos-api</artifactId>
-            <version>${onos.version}</version>
-            <classifier>tests</classifier>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.onosproject</groupId>
-            <artifactId>onos-core-serializers</artifactId>
-            <version>${onos.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.karaf.shell</groupId>
-            <artifactId>org.apache.karaf.shell.console</artifactId>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.karaf.shell</groupId>
-            <artifactId>org.apache.karaf.shell.core</artifactId>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
             <groupId>javax.ws.rs</groupId>
             <artifactId>javax.ws.rs-api</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opencord</groupId>
+            <artifactId>olt-api</artifactId>
+            <version>5.0.0-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
-
     <build>
         <plugins>
             <plugin>
@@ -123,10 +70,9 @@
                             *,org.glassfish.jersey.servlet
                         </Import-Package>
                         <Web-ContextPath>${web.context}</Web-ContextPath>
-                        <Karaf-Commands>org.opencord.olt.cli</Karaf-Commands>
                     </instructions>
                 </configuration>
             </plugin>
         </plugins>
     </build>
-</project>
+</project>
\ No newline at end of file
diff --git a/web/src/main/java/org/opencord/olt/rest/OltWebResource.java b/web/src/main/java/org/opencord/olt/rest/OltWebResource.java
index 7b19b18..c512304 100644
--- a/web/src/main/java/org/opencord/olt/rest/OltWebResource.java
+++ b/web/src/main/java/org/opencord/olt/rest/OltWebResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,12 +21,11 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.rest.AbstractWebResource;
 import org.opencord.olt.AccessDeviceService;
-import org.opencord.olt.AccessSubscriberId;
 import org.slf4j.Logger;
 
-import java.util.Optional;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
@@ -34,6 +33,8 @@
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+import java.util.Optional;
+
 import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -43,10 +44,15 @@
 
 @Path("oltapp")
 public class OltWebResource extends AbstractWebResource {
-
     private final Logger log = getLogger(getClass());
 
 
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("status")
+    public Response status() {
+        return Response.ok().build();
+    }
     /**
      * Provision a subscriber.
      *
@@ -64,6 +70,7 @@
         DeviceId deviceId = DeviceId.deviceId(device);
         PortNumber portNumber = PortNumber.portNumber(port);
         ConnectPoint connectPoint = new ConnectPoint(deviceId, portNumber);
+
         try {
             service.provisionSubscriber(connectPoint);
         } catch (Exception e) {
@@ -113,7 +120,39 @@
 
         Optional<VlanId> emptyVlan = Optional.empty();
         Optional<Integer> emptyTpId = Optional.empty();
-        if (service.provisionSubscriber(new AccessSubscriberId(portName), emptyVlan, emptyVlan, emptyTpId)) {
+        // Check if we can find the connect point to which this subscriber is connected
+        ConnectPoint cp = service.findSubscriberConnectPoint(portName);
+        if (cp == null) {
+            log.warn("ConnectPoint not found for {}", portName);
+            return Response.status(INTERNAL_SERVER_ERROR)
+                    .entity("ConnectPoint not found for " + portName).build();
+        }
+        if (service.provisionSubscriber(cp)) {
+            return ok("").build();
+        }
+        return Response.noContent().build();
+    }
+
+    /**
+     * Removes services for a subscriber.
+     *
+     * @param portName Name of the port on which the subscriber is connected
+     * @return 200 OK or 204 NO CONTENT
+     */
+    @DELETE
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("services/{portName}")
+    public Response deleteServices(
+            @PathParam("portName") String portName) {
+        AccessDeviceService service = get(AccessDeviceService.class);
+
+        ConnectPoint cp = service.findSubscriberConnectPoint(portName);
+        if (cp == null) {
+            log.warn("ConnectPoint not found for {}", portName);
+            return Response.status(INTERNAL_SERVER_ERROR)
+                    .entity("ConnectPoint not found for " + portName).build();
+        }
+        if (service.removeSubscriber(cp)) {
             return ok("").build();
         }
         return Response.noContent().build();
@@ -141,30 +180,16 @@
         VlanId cTag = VlanId.vlanId(cTagVal);
         VlanId sTag = VlanId.vlanId(sTagVal);
         Integer tpId = Integer.valueOf(tpIdVal);
-
-        if (service.provisionSubscriber(new AccessSubscriberId(portName), Optional.of(sTag),
-                Optional.of(cTag), Optional.of(tpId))) {
-            return ok("").build();
+        // TODO this is not optimal, because we call device service 2 times here and
+        // 2 times in the provisionSubscriber call, optimize byu having 2 more methods
+        // in the OltService that allow provisioning with portName.
+        ConnectPoint cp = service.findSubscriberConnectPoint(portName);
+        if (cp == null) {
+            log.warn("ConnectPoint not found for {}", portName);
+            return Response.status(INTERNAL_SERVER_ERROR)
+                    .entity("ConnectPoint not found for " + portName).build();
         }
-        return Response.noContent().build();
-    }
-
-    /**
-     * Removes services for a subscriber.
-     *
-     * @param portName Name of the port on which the subscriber is connected
-     * @return 200 OK or 204 NO CONTENT
-     */
-    @DELETE
-    @Produces(MediaType.APPLICATION_JSON)
-    @Path("services/{portName}")
-    public Response deleteServices(
-            @PathParam("portName") String portName) {
-        AccessDeviceService service = get(AccessDeviceService.class);
-
-        Optional<VlanId> emptyVlan = Optional.empty();
-        Optional<Integer> emptyTpId = Optional.empty();
-        if (service.removeSubscriber(new AccessSubscriberId(portName), emptyVlan, emptyVlan, emptyTpId)) {
+        if (service.provisionSubscriber(cp, cTag, sTag, tpId)) {
             return ok("").build();
         }
         return Response.noContent().build();
@@ -192,12 +217,18 @@
         VlanId cTag = VlanId.vlanId(cTagVal);
         VlanId sTag = VlanId.vlanId(sTagVal);
         Integer tpId = Integer.valueOf(tpIdVal);
-
-        if (service.removeSubscriber(new AccessSubscriberId(portName), Optional.of(sTag),
-                Optional.of(cTag), Optional.of(tpId))) {
+        // TODO this is not optimal, because we call device service 2 times here and
+        // 2 times in the provisionSubscriber call, optimize byu having 2 more methods
+        // in the OltService that allow provisioning with portName.
+        ConnectPoint cp = service.findSubscriberConnectPoint(portName);
+        if (cp == null) {
+            log.warn("ConnectPoint not found for {}", portName);
+            return Response.status(INTERNAL_SERVER_ERROR)
+                    .entity("ConnectPoint not found for " + portName).build();
+        }
+        if (service.removeSubscriber(cp, cTag, sTag, tpId)) {
             return ok("").build();
         }
         return Response.noContent().build();
     }
-
 }
