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>();
-        }
-    }
-}
