diff --git a/app/pom.xml b/app/pom.xml
index a15db81..b50a4d6 100644
--- a/app/pom.xml
+++ b/app/pom.xml
@@ -45,7 +45,7 @@
         <onos.app.readme>CORD OLT Access management application</onos.app.readme>
         <api.package>org.opencord.olt.rest</api.package>
         <olt.api.version>${project.version}</olt.api.version>
-        <sadis.api.version>3.1.0</sadis.api.version>
+        <sadis.api.version>3.1.1-SNAPSHOT</sadis.api.version>
     </properties>
 
     <dependencies>
@@ -97,7 +97,6 @@
             <plugin>
                 <groupId>org.onosproject</groupId>
                 <artifactId>onos-maven-plugin</artifactId>
-                <version>1.11</version>
             </plugin>
             <plugin>
                 <groupId>org.apache.felix</groupId>
diff --git a/app/src/main/java/org/opencord/olt/cli/ShowBpMeterMappingsCommand.java b/app/src/main/java/org/opencord/olt/cli/ShowBpMeterMappingsCommand.java
index 83b518f..630ae4a 100644
--- a/app/src/main/java/org/opencord/olt/cli/ShowBpMeterMappingsCommand.java
+++ b/app/src/main/java/org/opencord/olt/cli/ShowBpMeterMappingsCommand.java
@@ -19,10 +19,10 @@
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.net.meter.MeterKey;
-import org.opencord.olt.AccessDeviceService;
+import org.opencord.olt.internalapi.AccessDeviceMeterService;
 
-import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 @Command(scope = "onos", name = "volt-bpmeter-mappings",
         description = "Shows information about bandwidthProfile-meterKey (device / meter) mappings")
@@ -30,12 +30,12 @@
 
     @Override
     protected void execute() {
-        AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
-        Map<String, List<MeterKey>> bpMeterMappings = service.getBpMeterMappings();
+        AccessDeviceMeterService service = AbstractShellCommand.get(AccessDeviceMeterService.class);
+        Map<String, Set<MeterKey>> bpMeterMappings = service.getBpMeterMappings();
         bpMeterMappings.forEach(this::display);
     }
 
-    private void display(String bpInfo, List<MeterKey> meterKeyList) {
+    private void display(String bpInfo, Set<MeterKey> meterKeyList) {
         meterKeyList.forEach(meterKey ->
                 print("bpInfo=%s deviceId=%s meterId=%s",
                         bpInfo, meterKey.deviceId(), meterKey.meterId()));
diff --git a/app/src/main/java/org/opencord/olt/cli/ShowOltCommand.java b/app/src/main/java/org/opencord/olt/cli/ShowOltCommand.java
index d01e8e2..0c0441f 100644
--- a/app/src/main/java/org/opencord/olt/cli/ShowOltCommand.java
+++ b/app/src/main/java/org/opencord/olt/cli/ShowOltCommand.java
@@ -30,8 +30,6 @@
     @Override
     protected void execute() {
         AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
-        service.fetchOlts().forEach(did -> {
-            print("OLT %s", did);
-        });
+        service.fetchOlts().forEach(did -> print("OLT %s", did));
     }
 }
diff --git a/app/src/main/java/org/opencord/olt/cli/ShowProgrammedMetersCommand.java b/app/src/main/java/org/opencord/olt/cli/ShowProgrammedMetersCommand.java
index 6fa8c9d..6615002 100644
--- a/app/src/main/java/org/opencord/olt/cli/ShowProgrammedMetersCommand.java
+++ b/app/src/main/java/org/opencord/olt/cli/ShowProgrammedMetersCommand.java
@@ -19,7 +19,7 @@
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.net.meter.MeterKey;
-import org.opencord.olt.AccessDeviceService;
+import org.opencord.olt.internalapi.AccessDeviceMeterService;
 
 import java.util.Set;
 
@@ -33,7 +33,7 @@
 
     @Override
     protected void execute() {
-        AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
+        AccessDeviceMeterService service = AbstractShellCommand.get(AccessDeviceMeterService.class);
         Set<MeterKey> programmedMeters = service.getProgMeters();
         programmedMeters.forEach(this::display);
     }
diff --git a/app/src/main/java/org/opencord/olt/cli/ShowProgrammedSubscribersCommand.java b/app/src/main/java/org/opencord/olt/cli/ShowProgrammedSubscribersCommand.java
index 2a4409e..be2b6dd 100644
--- a/app/src/main/java/org/opencord/olt/cli/ShowProgrammedSubscribersCommand.java
+++ b/app/src/main/java/org/opencord/olt/cli/ShowProgrammedSubscribersCommand.java
@@ -17,12 +17,13 @@
 package org.opencord.olt.cli;
 
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.net.ConnectPoint;
 import org.opencord.olt.AccessDeviceService;
-import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.opencord.sadis.UniTagInformation;
 
 /**
  * Shows subscriber information for those subscriber which have been programmed
@@ -35,11 +36,12 @@
     @Override
     protected void execute() {
         AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
-        Map<ConnectPoint, SubscriberAndDeviceInformation> info = service.getProgSubs();
+        Map<ConnectPoint, Set<UniTagInformation>> info = service.getProgSubs();
         info.forEach(this::display);
     }
 
-    private void display(ConnectPoint cp, SubscriberAndDeviceInformation sub) {
-        print("location=%s subscriber=%s", cp, sub);
+    private void display(ConnectPoint cp, Set<UniTagInformation> uniTagInformation) {
+        uniTagInformation.forEach(uniTag ->
+                print("location=%s tagInformation=%s", cp, uniTag));
     }
 }
diff --git a/app/src/main/java/org/opencord/olt/cli/ShowSubscribersCommand.java b/app/src/main/java/org/opencord/olt/cli/ShowSubscribersCommand.java
deleted file mode 100644
index 711d1fa..0000000
--- a/app/src/main/java/org/opencord/olt/cli/ShowSubscribersCommand.java
+++ /dev/null
@@ -1,47 +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 java.util.Map;
-
-import org.apache.karaf.shell.commands.Command;
-import org.onlab.packet.VlanId;
-import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.net.ConnectPoint;
-import org.opencord.olt.AccessDeviceService;
-
-/**
- * Shows provisioned (configured) subscribers. The data plane flows for the
- * subscribers may or may not have been programmed.
- */
-@Command(scope = "onos", name = "volt-subscribers",
-        description = "Shows pre-provisioned subscribers")
-public class ShowSubscribersCommand extends AbstractShellCommand {
-
-    private static final String FORMAT = "port=%s, svlan=%s, cvlan=%s";
-
-    @Override
-    protected void execute() {
-        AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
-        service.getSubscribers().forEach(this::display);
-    }
-
-    private void display(Map.Entry<ConnectPoint, Map.Entry<VlanId, VlanId>> subscriber) {
-        print(FORMAT, subscriber.getKey(), subscriber.getValue().getKey(),
-                subscriber.getValue().getValue());
-    }
-}
diff --git a/app/src/main/java/org/opencord/olt/cli/UniTagAddCommand.java b/app/src/main/java/org/opencord/olt/cli/UniTagAddCommand.java
new file mode 100644
index 0000000..9ea5439
--- /dev/null
+++ b/app/src/main/java/org/opencord/olt/cli/UniTagAddCommand.java
@@ -0,0 +1,63 @@
+/*
+ * 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.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onlab.packet.VlanId;
+import org.onosproject.cli.AbstractShellCommand;
+import org.opencord.olt.AccessDeviceService;
+import org.opencord.olt.AccessSubscriberId;
+
+import java.util.Optional;
+
+/**
+ * Adds a subscriber uni tag.
+ */
+@Command(scope = "onos", name = "volt-add-subscriber-unitag",
+        description = "Adds a uni tag to an access device")
+public class UniTagAddCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "portName", description = "Port name",
+            required = true, multiValued = false)
+    private String strPortName = null;
+
+    @Option(name = "--cTag", description = "Inner vlan id",
+            required = false, multiValued = false)
+    private String strCtag = null;
+
+    @Option(name = "--sTag", description = "Outer vlan id",
+            required = false, multiValued = false)
+    private String strStag = null;
+
+    @Option(name = "--tpId", description = "Technology profile id",
+            required = false, multiValued = false)
+    private String strTpId = null;
+
+    @Override
+    protected void execute() {
+
+        AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
+        AccessSubscriberId portName = new AccessSubscriberId(strPortName);
+
+        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);
+    }
+}
diff --git a/app/src/main/java/org/opencord/olt/cli/UniTagRemoveCommand.java b/app/src/main/java/org/opencord/olt/cli/UniTagRemoveCommand.java
new file mode 100644
index 0000000..74d05b7
--- /dev/null
+++ b/app/src/main/java/org/opencord/olt/cli/UniTagRemoveCommand.java
@@ -0,0 +1,63 @@
+/*
+ * 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.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onlab.packet.VlanId;
+import org.onosproject.cli.AbstractShellCommand;
+import org.opencord.olt.AccessDeviceService;
+import org.opencord.olt.AccessSubscriberId;
+
+import java.util.Optional;
+
+/**
+ * Removes a uni tag from a subscriber (portname).
+ */
+@Command(scope = "onos", name = "volt-remove-subscriber-unitag",
+        description = "Removes a uni tag from an access device")
+public class UniTagRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "portName", description = "Port name",
+            required = true, multiValued = false)
+    private String strPortName = null;
+
+    @Option(name = "--cTag", description = "Inner vlan id",
+            required = false, multiValued = false)
+    private String strCtag = null;
+
+    @Option(name = "--sTag", description = "Outer vlan id",
+            required = false, multiValued = false)
+    private String strStag = null;
+
+    @Option(name = "--tpId", description = "Technology profile id",
+            required = false, multiValued = false)
+    private String strTpId = null;
+
+    @Override
+    protected void execute() {
+
+        AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class);
+        AccessSubscriberId portName = new AccessSubscriberId(strPortName);
+
+        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);
+    }
+}
diff --git a/app/src/main/java/org/opencord/olt/impl/Olt.java b/app/src/main/java/org/opencord/olt/impl/Olt.java
index e0ac2b3..d4ed2ff 100644
--- a/app/src/main/java/org/opencord/olt/impl/Olt.java
+++ b/app/src/main/java/org/opencord/olt/impl/Olt.java
@@ -22,10 +22,7 @@
 import static org.onlab.util.Tools.groupedThreads;
 import static org.slf4j.LoggerFactory.getLogger;
 
-import java.util.AbstractMap;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.Dictionary;
 import java.util.List;
 import java.util.Map;
@@ -34,7 +31,6 @@
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.stream.Collectors;
@@ -47,12 +43,7 @@
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
-import org.onlab.packet.EthType;
-import org.onlab.packet.IPv4;
-import org.onlab.packet.IPv6;
-import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
-import org.onlab.util.Tools;
 import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
@@ -67,48 +58,27 @@
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flowobjective.DefaultFilteringObjective;
-import org.onosproject.net.flowobjective.DefaultForwardingObjective;
-import org.onosproject.net.flowobjective.FilteringObjective;
 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.meter.Band;
-import org.onosproject.net.meter.DefaultBand;
-import org.onosproject.net.meter.DefaultMeterRequest;
-import org.onosproject.net.meter.Meter;
-import org.onosproject.net.meter.MeterContext;
-import org.onosproject.net.meter.MeterEvent;
-import org.onosproject.net.meter.MeterFailReason;
 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.net.meter.MeterService;
-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.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;
+import org.opencord.sadis.UniTagInformation;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
@@ -122,16 +92,10 @@
         implements AccessDeviceService {
     private static final String APP_NAME = "org.opencord.olt";
 
-    private static final short DEFAULT_VLAN = 0;
     private static final short EAPOL_DEFAULT_VLAN = 4091;
-    private static final int DEFAULT_TP_ID = 64;
     private static final String DEFAULT_BP_ID = "Default";
-    private static final String ADDITIONAL_VLANS = "additional-vlans";
+    private static final String DEFAULT_MCAST_SERVICE_NAME = "MC";
     private static final String NO_UPLINK_PORT = "No uplink port found for OLT device {}";
-    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 final Logger log = getLogger(getClass());
 
@@ -154,73 +118,38 @@
     protected SadisService sadisService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected MeterService meterService;
+    protected AccessDeviceFlowService oltFlowService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected StorageService storageService;
-
-    @Property(name = "defaultVlan", intValue = DEFAULT_VLAN,
-            label = "Default VLAN RG<->ONU traffic")
-    private int defaultVlan = DEFAULT_VLAN;
-
-    @Property(name = "enableDhcpOnProvisioning", boolValue = true,
-            label = "Create the DHCP Flow rules when a subscriber is provisioned")
-    protected boolean enableDhcpOnProvisioning = false;
-
-    @Property(name = "enableDhcpV4", boolValue = true,
-            label = "Enable flows for DHCP v4")
-    protected boolean enableDhcpV4 = true;
-
-    @Property(name = "enableDhcpV6", boolValue = true,
-            label = "Enable flows for DHCP v6")
-    protected boolean enableDhcpV6 = false;
-
-    @Property(name = "enableIgmpOnProvisioning", boolValue = false,
-            label = "Create IGMP Flow rules when a subscriber is provisioned")
-    protected boolean enableIgmpOnProvisioning = false;
-
-    @Property(name = "deleteMeters", boolValue = true,
-            label = "Deleting Meters based on flow count statistics")
-    protected boolean deleteMeters = true;
-
-    @Property(name = "defaultTechProfileId", intValue = DEFAULT_TP_ID,
-            label = "Default technology profile id that is used for authentication trap flows")
-    protected int defaultTechProfileId = DEFAULT_TP_ID;
+    protected AccessDeviceMeterService oltMeterService;
 
     @Property(name = "defaultBpId", value = DEFAULT_BP_ID,
             label = "Default bandwidth profile id that is used for authentication trap flows")
     protected String defaultBpId = DEFAULT_BP_ID;
 
-    @Property(name = "enableEapol", boolValue = true,
-            label = "Send EAPOL authentication trap flows before subscriber provisioning")
-    protected boolean enableEapol = true;
+    @Property(name = "multicastServiceName", value = DEFAULT_MCAST_SERVICE_NAME,
+            label = "The multicast service name")
+    protected String mcastServiceName = DEFAULT_MCAST_SERVICE_NAME;
 
     private final DeviceListener deviceListener = new InternalDeviceListener();
-    private final MeterListener meterListener = new InternalMeterListener();
 
-    private ApplicationId appId;
     protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
     private BaseInformationService<BandwidthProfileInformation> bpService;
 
-    private Map<String, List<MeterKey>> bpInfoToMeter = new ConcurrentHashMap<>();
-
     private ExecutorService oltInstallers = Executors.newFixedThreadPool(4,
             groupedThreads("onos/olt-service",
                     "olt-installer-%d"));
 
-    private ConsistentMultimap<ConnectPoint, Map.Entry<VlanId, VlanId>> additionalVlans;
-
     protected ExecutorService eventExecutor;
 
-    private Map<ConnectPoint, SubscriberAndDeviceInformation> programmedSubs;
-    private Set<MeterKey> programmedMeters;
-
+    private Map<ConnectPoint, Set<UniTagInformation>> programmedSubs;
 
     @Activate
     public void activate(ComponentContext context) {
-        eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/olt", "events-%d", log));
+        eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/olt",
+                "events-%d", log));
         modified(context);
-        appId = coreService.registerApplication(APP_NAME);
+        ApplicationId appId = coreService.registerApplication(APP_NAME);
 
         // ensure that flow rules are purged from flow-store upon olt-disconnection
         // when olt reconnects, the port-numbers may change for the ONUs
@@ -233,7 +162,6 @@
                         "purgeOnDisconnection", "true");
         componentConfigService.registerProperties(getClass());
         programmedSubs = Maps.newConcurrentMap();
-        programmedMeters = ConcurrentHashMap.newKeySet();
 
         eventDispatcher.addSink(AccessDeviceEvent.class, listenerRegistry);
 
@@ -247,15 +175,7 @@
             checkAndCreateDeviceFlows(d);
         }
 
-        additionalVlans = storageService.<ConnectPoint, Map.Entry<VlanId, VlanId>>consistentMultimapBuilder()
-                .withName(ADDITIONAL_VLANS)
-                .withSerializer(Serializer.using(Arrays.asList(KryoNamespaces.API),
-                        AbstractMap.SimpleEntry.class))
-                .build();
-
         deviceService.addListener(deviceListener);
-        meterService.addListener(meterListener);
-
         log.info("Started with Application ID {}", appId.id());
     }
 
@@ -263,7 +183,6 @@
     public void deactivate() {
         componentConfigService.unregisterProperties(getClass(), false);
         deviceService.removeListener(deviceListener);
-        meterService.removeListener(meterListener);
         eventDispatcher.removeSink(AccessDeviceEvent.class);
         log.info("Stopped");
     }
@@ -273,50 +192,15 @@
         Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
 
         try {
-            String s = get(properties, "defaultVlan");
-            defaultVlan = isNullOrEmpty(s) ? DEFAULT_VLAN : Integer.parseInt(s.trim());
+            defaultBpId = get(properties, "defaultBpId");
 
-            Boolean o = Tools.isPropertyEnabled(properties, "enableDhcpOnProvisioning");
-            if (o != null) {
-                enableDhcpOnProvisioning = o;
-            }
+            String serviceName = get(properties, "multicastServiceName");
+            mcastServiceName = isNullOrEmpty(serviceName) ? DEFAULT_MCAST_SERVICE_NAME : serviceName;
 
-            Boolean v4 = Tools.isPropertyEnabled(properties, "enableDhcpV4");
-            if (v4 != null) {
-                enableDhcpV4 = v4;
-            }
-
-            Boolean v6 = Tools.isPropertyEnabled(properties, "enableDhcpV6");
-            if (v6 != null) {
-                enableDhcpV6 = v6;
-            }
-
-            Boolean p = Tools.isPropertyEnabled(properties, "enableIgmpOnProvisioning");
-            if (p != null) {
-                enableIgmpOnProvisioning = p;
-            }
-
-            log.info("DHCP Settings [enableDhcpOnProvisioning: {}, enableDhcpV4: {}, enableDhcpV6: {}]",
-                    enableDhcpOnProvisioning, enableDhcpV4, enableDhcpV6);
-
-            Boolean d = Tools.isPropertyEnabled(properties, "deleteMeters");
-            if (d != null) {
-                deleteMeters = d;
-            }
-
-            String tpId = get(properties, "defaultTechProfileId");
-            defaultTechProfileId = isNullOrEmpty(s) ? DEFAULT_TP_ID : Integer.parseInt(tpId.trim());
-
-            String bpId = get(properties, "defaultBpId");
-            defaultBpId = bpId;
-
-            Boolean eap = Tools.isPropertyEnabled(properties, "enableEapol");
-            if (eap != null) {
-                enableEapol = eap;
-            }
+            log.debug("OLT properties: DefaultBpId: {}, MulticastServiceName: {}", defaultBpId, mcastServiceName);
 
         } catch (Exception e) {
-            defaultVlan = DEFAULT_VLAN;
+            log.error("Error while modifying the properties", e);
         }
     }
 
@@ -327,7 +211,8 @@
         PortNumber subscriberPortNo = connectPoint.port();
 
         checkNotNull(deviceService.getPort(deviceId, subscriberPortNo),
-                "Invalid connect point");
+                "Invalid connect point:" + connectPoint);
+
         // Find the subscriber on this connect point
         SubscriberAndDeviceInformation sub = getSubscriber(connectPoint);
         if (sub == null) {
@@ -342,37 +227,17 @@
             return false;
         }
 
-        SubscriberAndDeviceInformation prgSub = programmedSubs.get(connectPoint);
-        if (prgSub != null) {
-            log.warn("Subscriber {} on connectionPoint {} was previously programmed .. "
-                    + "taking no action. Note that updating a subscribers params "
-                    + "(vlans, bw, tpid etc) requires removing the subscriber"
-                    + "before re-provisioning the subscriber", prgSub.id(),
-                     connectPoint);
-            return true;
-        }
-
         //delete Eapol authentication flow with default bandwidth
         //wait until Eapol rule with defaultBpId is removed to install subscriber-based rules
-        CompletableFuture<ObjectiveError> filterFuture = new CompletableFuture();
-        processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId, filterFuture,
-                VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
-        // do not remove meter from bpInfoToMeter mapping as flows for other ONUs
-        // could still be using it - this also prevents duplicate meters from being
-        // created for the same bandwidth profile
-        // we still need to remove from programmedMeters so the meter can be
-        // deleted if its reference count drops to zero
-        removeMeterIdFromPrgMeters(deviceId, defaultBpId);
-
         //install subscriber flows
+        CompletableFuture<ObjectiveError> filterFuture = new CompletableFuture();
+        oltFlowService.processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId, filterFuture,
+                VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
         filterFuture.thenAcceptAsync(filterStatus -> {
             if (filterStatus == null) {
-                provisionSubscriberBasedFlows(connectPoint, uplinkPort.number(), Optional.empty(), sub);
+                provisionUniTagList(connectPoint, uplinkPort.number(), sub);
             }
         });
-
-        // cache subscriber info
-        programmedSubs.put(connectPoint, sub);
         return true;
     }
 
@@ -385,8 +250,8 @@
         DeviceId deviceId = connectPoint.deviceId();
         PortNumber subscriberPortNo = connectPoint.port();
 
-        SubscriberAndDeviceInformation subscriber = programmedSubs.get(connectPoint);
-        if (subscriber == null) {
+        Set<UniTagInformation> uniTagInformationSet = programmedSubs.get(connectPoint);
+        if (uniTagInformationSet == null || uniTagInformationSet.isEmpty()) {
             log.warn("Subscriber on connectionPoint {} was not previously programmed, " +
                     "no need to remove it", connectPoint);
             return true;
@@ -399,53 +264,38 @@
             return false;
         }
 
-        //delete dhcp & igmp trap flows
-        MeterId upstreamMeterId = getMeterIdFromBpMapping(deviceId, subscriber.upstreamBandwidthProfile());
+        for (UniTagInformation uniTag : uniTagInformationSet) {
 
-        // remove dhcp filters
-        processDhcpFilteringObjectives(deviceId, subscriberPortNo,
-                upstreamMeterId, subscriber.technologyProfileId(), false, true);
+            if (mcastServiceName.equals(uniTag.getServiceName())) {
+                continue;
+            }
 
-        // remove igmp filters
-        processIgmpFilteringObjectives(deviceId, subscriberPortNo,
-                upstreamMeterId, subscriber.technologyProfileId(), false);
+            unprovisionVlans(deviceId, uplinkPort.number(), subscriberPortNo, uniTag);
 
-        //unprovision vlans
-        unprovisionVlans(deviceId, uplinkPort.number(), subscriberPortNo, subscriber, Optional.empty());
+            // re-install eapol with default bandwidth profile
+            oltFlowService.processEapolFilteringObjectives(deviceId, subscriberPortNo,
+                    uniTag.getUpstreamBandwidthProfile(), null, uniTag.getPonCTag(), false);
 
-        // Remove if there are any flows for the additional Vlans
-        Collection<? extends Map.Entry<VlanId, VlanId>> vlansList = additionalVlans.get(connectPoint).value();
-
-        // Remove the flows for the additional vlans for this subscriber
-        for (Map.Entry<VlanId, VlanId> vlans : vlansList) {
-            unprovisionTransparentFlows(deviceId, uplinkPort.number(), subscriberPortNo,
-                    vlans.getValue(), vlans.getKey());
-
-            // Remove it from the map also
-            additionalVlans.remove(connectPoint, vlans);
+            Port port = deviceService.getPort(deviceId, subscriberPortNo);
+            if (port != null && port.isEnabled()) {
+                oltFlowService.processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId,
+                        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);
+            }
         }
-
-        // re-install eapol with default bandwidth profile
-        processEapolFilteringObjectives(deviceId, subscriberPortNo,
-                subscriber.upstreamBandwidthProfile(), null, subscriber.cTag(), false);
-
-        Port port = deviceService.getPort(deviceId, subscriberPortNo);
-        if (port != null && port.isEnabled()) {
-            processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId,
-                    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);
-        }
-
-        programmedSubs.remove(connectPoint);
         return true;
     }
 
-    @Override
-    public boolean provisionSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag, Optional<VlanId> cTag) {
 
-        log.info("Provisioning subscriber using subscriberId {}, sTag {}, cTag {}", subscriberId, sTag, cTag);
+
+    @Override
+    public boolean provisionSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag,
+                                       Optional<VlanId> cTag, Optional<Integer> tpId) {
+
+        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 subsPort = findSubscriberConnectPoint(subscriberId.toString());
@@ -456,31 +306,23 @@
 
         if (!sTag.isPresent() && !cTag.isPresent()) {
             return provisionSubscriber(subsPort);
-        } else if (sTag.isPresent() && cTag.isPresent()) {
+        } else if (sTag.isPresent() && cTag.isPresent() && tpId.isPresent()) {
             Port uplinkPort = getUplinkPort(deviceService.getDevice(subsPort.deviceId()));
             if (uplinkPort == null) {
                 log.warn(NO_UPLINK_PORT, subsPort.deviceId());
                 return false;
             }
 
-            CompletableFuture<ObjectiveError> filterFuture = new CompletableFuture();
-
             //delete Eapol authentication flow with default bandwidth
             //wait until Eapol rule with defaultBpId is removed to install subscriber-based rules
-            processEapolFilteringObjectives(subsPort.deviceId(), subsPort.port(), defaultBpId, filterFuture,
-                    VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
-            // do not remove meter from bpInfoToMeter mapping as flows for other ONUs
-            // could still be using it - this also prevents duplicate meters from being
-            // created for the same bandwidth profile
-            // we still need to remove from programmedMeters so the meter can be
-            // deleted if its reference count drops to zero
-            removeMeterIdFromPrgMeters(subsPort.deviceId(), defaultBpId);
-
             //install subscriber flows
+            CompletableFuture<ObjectiveError> filterFuture = new CompletableFuture();
+            oltFlowService.processEapolFilteringObjectives(subsPort.deviceId(), subsPort.port(), defaultBpId,
+                    filterFuture, VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
             filterFuture.thenAcceptAsync(filterStatus -> {
                 if (filterStatus == null) {
-                    provisionTransparentFlows(subsPort.deviceId(), uplinkPort.number(), subsPort.port(),
-                            cTag.get(), sTag.get());
+                    provisionUniTagInformation(subsPort.deviceId(), uplinkPort.number(), subsPort.port(),
+                            cTag.get(), sTag.get(), tpId.get());
                 }
             });
             return true;
@@ -491,7 +333,8 @@
     }
 
     @Override
-    public boolean removeSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag, Optional<VlanId> cTag) {
+    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 subsPort = findSubscriberConnectPoint(subscriberId.toString());
         if (subsPort == null) {
@@ -501,7 +344,7 @@
 
         if (!sTag.isPresent() && !cTag.isPresent()) {
             return removeSubscriber(subsPort);
-        } else if (sTag.isPresent() && cTag.isPresent()) {
+        } else if (sTag.isPresent() && cTag.isPresent() && tpId.isPresent()) {
             // Get the uplink port
             Port uplinkPort = getUplinkPort(deviceService.getDevice(subsPort.deviceId()));
             if (uplinkPort == null) {
@@ -509,60 +352,28 @@
                 return false;
             }
 
-            unprovisionTransparentFlows(subsPort.deviceId(), uplinkPort.number(), subsPort.port(),
-                    cTag.get(), sTag.get());
+            Optional<UniTagInformation> tagInfo = getUniTagInformation(subsPort, cTag.get(), sTag.get(), tpId.get());
+            if (!tagInfo.isPresent()) {
+                log.warn("UniTagInformation does not exist for Device/Port {}, cTag {}, sTag {}, tpId {}",
+                        subsPort, cTag, sTag, tpId);
+                return false;
+            }
 
-            programmedSubs.remove(subsPort);
-
+            unprovisionVlans(subsPort.deviceId(), uplinkPort.number(), subsPort.port(), tagInfo.get());
             return true;
         } else {
-            log.warn("Removing subscriber failed for: {}", subscriberId);
+            log.warn("Removing subscriber is not possible - please check the provided information" +
+                    "for the subscriber: {}", subscriberId);
             return false;
         }
     }
 
     @Override
-    public Collection<Map.Entry<ConnectPoint, Map.Entry<VlanId, VlanId>>> getSubscribers() {
-        ArrayList<Map.Entry<ConnectPoint, Map.Entry<VlanId, VlanId>>> subs = new ArrayList<>();
-
-        // Get the subscribers for all the devices configured in sadis
-        // If the port is UNI, is enabled and exists in Sadis then copy it
-        for (Device d : deviceService.getDevices()) {
-            if (getOltInfo(d) == null) {
-                continue; // not an olt, or not configured in sadis
-            }
-            for (Port p : deviceService.getPorts(d.id())) {
-                if (isUniPort(d, p) && p.isEnabled()) {
-                    ConnectPoint cp = new ConnectPoint(d.id(), p.number());
-
-                    SubscriberAndDeviceInformation sub = getSubscriber(cp);
-                    if (sub != null) {
-                        Map.Entry<VlanId, VlanId> vlans = new AbstractMap.SimpleEntry(sub.sTag(), sub.cTag());
-                        subs.add(new AbstractMap.SimpleEntry(cp, vlans));
-                    }
-                }
-            }
-        }
-
-        return subs;
-    }
-
-    @Override
-    public ImmutableMap<ConnectPoint, SubscriberAndDeviceInformation> getProgSubs() {
+    public ImmutableMap<ConnectPoint, Set<UniTagInformation>> getProgSubs() {
         return ImmutableMap.copyOf(programmedSubs);
     }
 
     @Override
-    public ImmutableSet<MeterKey> getProgMeters() {
-        return ImmutableSet.copyOf(programmedMeters);
-    }
-
-    @Override
-    public ImmutableMap<String, List<MeterKey>> getBpMeterMappings() {
-        return ImmutableMap.copyOf(bpInfoToMeter);
-    }
-
-    @Override
     public List<DeviceId> fetchOlts() {
         // look through all the devices and find the ones that are OLTs as per Sadis
         List<DeviceId> olts = new ArrayList<>();
@@ -597,6 +408,12 @@
         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 (bandwidthProfile == null) {
             return null;
@@ -610,30 +427,37 @@
      * @param deviceId       the device identifier
      * @param uplink         uplink port of the OLT
      * @param subscriberPort uni port
-     * @param subscriber     subscriber info that includes s, c tags, tech profile and bandwidth profile references
-     * @param defaultVlan    default vlan of the subscriber
+     * @param uniTag         uni tag information
      */
     private void unprovisionVlans(DeviceId deviceId, PortNumber uplink,
-                                  PortNumber subscriberPort, SubscriberAndDeviceInformation subscriber,
-                                  Optional<VlanId> defaultVlan) {
-        log.info("Unprovisioning vlans for subscriber {} on dev/port: {}/{}",
-                 subscriber, deviceId, subscriberPort);
+                                  PortNumber subscriberPort, UniTagInformation uniTag) {
+
+        log.info("Unprovisioning vlans for {} at {}/{}", uniTag, deviceId, subscriberPort);
 
         CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
         CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
 
-        VlanId deviceVlan = subscriber.sTag();
-        VlanId subscriberVlan = subscriber.cTag();
+        VlanId deviceVlan = uniTag.getPonSTag();
+        VlanId subscriberVlan = uniTag.getPonCTag();
 
-        MeterId upstreamMeterId = getMeterIdFromBpMapping(deviceId, subscriber.upstreamBandwidthProfile());
-        MeterId downstreamMeterId = getMeterIdFromBpMapping(deviceId, subscriber.downstreamBandwidthProfile());
+        MeterId upstreamMeterId = oltMeterService
+                .getMeterIdFromBpMapping(deviceId, uniTag.getUpstreamBandwidthProfile());
+        MeterId downstreamMeterId = oltMeterService
+                .getMeterIdFromBpMapping(deviceId, uniTag.getDownstreamBandwidthProfile());
 
-        ForwardingObjective.Builder upFwd = upBuilder(uplink, subscriberPort,
-                subscriberVlan, deviceVlan,
-                defaultVlan, upstreamMeterId, subscriber.technologyProfileId());
-        ForwardingObjective.Builder downFwd = downBuilder(uplink, subscriberPort,
-                subscriberVlan, deviceVlan,
-                defaultVlan, downstreamMeterId, subscriber.technologyProfileId());
+        ForwardingObjective.Builder upFwd =
+                oltFlowService.createUpBuilder(uplink, subscriberPort, upstreamMeterId, uniTag);
+        ForwardingObjective.Builder downFwd =
+                oltFlowService.createDownBuilder(uplink, subscriberPort, downstreamMeterId, uniTag);
+
+        if (uniTag.getIsIgmpRequired()) {
+            oltFlowService.processIgmpFilteringObjectives(deviceId, subscriberPort,
+                    upstreamMeterId, uniTag, false, true);
+        }
+        if (uniTag.getIsDhcpRequired()) {
+            oltFlowService.processDhcpFilteringObjectives(deviceId, subscriberPort,
+                    upstreamMeterId, uniTag, false, true);
+        }
 
         flowObjectiveService.forward(deviceId, upFwd.remove(new ObjectiveContext() {
             @Override
@@ -660,317 +484,148 @@
         }));
 
         upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
+            AccessDeviceEvent.Type type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTERED;
             if (upStatus == null && downStatus == null) {
-                post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_UNREGISTERED,
-                        deviceId,
-                        deviceVlan,
-                        subscriberVlan));
+                log.debug("Uni tag information is unregistered successfully for cTag {}, sTag {}, tpId {}, and" +
+                                "Device/Port{}", uniTag.getPonCTag(), uniTag.getPonSTag(),
+                        uniTag.getTechnologyProfileId(), subscriberPort);
+                updateProgrammedSubscriber(new ConnectPoint(deviceId, subscriberPort), uniTag, false);
             } else if (downStatus != null) {
                 log.error("Subscriber with vlan {} on device {} " +
                                 "on port {} failed downstream uninstallation: {}",
                         subscriberVlan, deviceId, subscriberPort, downStatus);
+                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTRATION_FAILED;
             } else if (upStatus != null) {
                 log.error("Subscriber with vlan {} on device {} " +
                                 "on port {} failed upstream uninstallation: {}",
                         subscriberVlan, deviceId, subscriberPort, upStatus);
+                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTRATION_FAILED;
             }
+            Port port = deviceService.getPort(deviceId, subscriberPort);
+            post(new AccessDeviceEvent(type, deviceId, port, deviceVlan, subscriberVlan,
+                    uniTag.getTechnologyProfileId()));
         }, oltInstallers);
-
-        programmedMeters.remove(MeterKey.key(deviceId, upstreamMeterId));
-        programmedMeters.remove(MeterKey.key(deviceId, downstreamMeterId));
-        log.debug("programmed Meters size {}", programmedMeters.size());
     }
 
     /**
      * Adds subscriber vlan flows, dhcp, eapol and igmp trap flows for the related uni port.
      *
-     * @param port        the connection point of the subscriber
-     * @param uplinkPort  uplink port of the OLT
-     * @param defaultVlan default vlan of the subscriber
-     * @param sub         subscriber information that includes s, c tags, tech profile and bandwidth profile references
+     * @param connectPoint 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 provisionSubscriberBasedFlows(ConnectPoint port, PortNumber uplinkPort,
-                                               Optional<VlanId> defaultVlan,
-                                               SubscriberAndDeviceInformation sub) {
+    private void provisionUniTagList(ConnectPoint connectPoint, PortNumber uplinkPort,
+                                     SubscriberAndDeviceInformation sub) {
 
-        log.info("Provisioning vlans for subscriber {} on dev/port: {}",
-                 sub, port);
+        log.info("Provisioning vlans for subscriber {} on dev/port: {}", sub, connectPoint);
 
-        DeviceId deviceId = port.deviceId();
-        PortNumber subscriberPort = port.port();
-        VlanId deviceVlan = sub.sTag();
-        VlanId subscriberVlan = sub.cTag();
-        int techProfId = sub.technologyProfileId();
+        if (sub.uniTagList() == null || sub.uniTagList().isEmpty()) {
+            log.warn("Unitaglist doesn't exist for the subscriber {}", sub.id());
+            return;
+        }
 
-        BandwidthProfileInformation upstreamBpInfo = getBandwidthProfileInformation(sub.upstreamBandwidthProfile());
-        BandwidthProfileInformation downstreamBpInfo = getBandwidthProfileInformation(sub.downstreamBandwidthProfile());
+        DeviceId deviceId = connectPoint.deviceId();
+        PortNumber subscriberPort = connectPoint.port();
 
-        CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
-        CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
-        CompletableFuture<Object> upstreamMeterFuture = new CompletableFuture<>();
-        CompletableFuture<Object> downsteamMeterFuture = new CompletableFuture<>();
+        for (UniTagInformation uniTag : sub.uniTagList()) {
+            handleSubscriberFlows(deviceId, uplinkPort, subscriberPort, uniTag);
+        }
+    }
 
-        MeterId upstreamMeterId = createMeter(deviceId, upstreamBpInfo, upstreamMeterFuture);
-        MeterId downstreamMeterId = createMeter(deviceId, downstreamBpInfo, downsteamMeterFuture);
+    /**
+     * Finds the uni tag information and provisions the found information.
+     * If the uni tag information is not found, returns
+     *
+     * @param deviceId       the access device id
+     * @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(DeviceId deviceId, PortNumber uplinkPort,
+                                            PortNumber subscriberPort,
+                                            VlanId innerVlan,
+                                            VlanId outerVlan,
+                                            Integer tpId) {
 
-        //install upstream flows
-        upstreamMeterFuture.thenAcceptAsync(result -> {
-            if (result == null) {
-                log.info("Upstream Meter {} is in the device {}. " +
-                        "Sending subscriber flows.", upstreamMeterId, deviceId);
-                ForwardingObjective.Builder upFwd = upBuilder(uplinkPort, subscriberPort,
-                        subscriberVlan, deviceVlan,
-                        defaultVlan, upstreamMeterId, techProfId);
+        ConnectPoint cp = new ConnectPoint(deviceId, subscriberPort);
+        Optional<UniTagInformation> gotTagInformation = getUniTagInformation(cp, innerVlan, outerVlan, tpId);
+        if (!gotTagInformation.isPresent()) {
+            return;
+        }
+        UniTagInformation tagInformation = gotTagInformation.get();
+        handleSubscriberFlows(deviceId, uplinkPort, subscriberPort, tagInformation);
+    }
 
-
-                flowObjectiveService.forward(deviceId, upFwd.add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        upFuture.complete(null);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        upFuture.complete(error);
-                    }
-                }));
-            } else {
-                log.error("Meter installation error for {} on {} while sending upstream flows. " +
-                        "Result {} and MeterId {}", deviceId, subscriberPort, result, upstreamMeterId);
-            }
-        });
-
-        //install downstream flows
-        downsteamMeterFuture.thenAcceptAsync(result -> {
-            if (result == null) {
-                log.info("Downstream Meter {} is in the device {}. " +
-                        "Sending subscriber flows.", downstreamMeterId, deviceId);
-                ForwardingObjective.Builder downFwd = downBuilder(uplinkPort, subscriberPort,
-                        subscriberVlan, deviceVlan,
-                        defaultVlan, downstreamMeterId, techProfId);
-
-                flowObjectiveService.forward(deviceId, downFwd.add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        downFuture.complete(null);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        downFuture.complete(error);
-                    }
-                }));
-            } else {
-                log.error("Meter installation error for {} on {} while sending downstream flows. " +
-                        "Result {} and MeterId {}", deviceId, subscriberPort, result, downstreamMeterId);
-            }
-        });
-
-        //send eapol & dhcp & igmp flows
-        //send Subscriber Registered event
-        upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
-            if (upStatus == null && downStatus == null) {
-
-                if (upstreamMeterId != null) {
-                    //re-install Eapol authentication flow with the subscribers' upstream bandwidth profile
-                    processEapolFilteringObjectives(deviceId, subscriberPort, sub.upstreamBandwidthProfile(),
-                            null, sub.cTag(), true);
-
-                    processDhcpFilteringObjectives(deviceId, subscriberPort,
-                            upstreamMeterId, sub.technologyProfileId(), true, true);
-
-                    processIgmpFilteringObjectives(deviceId, subscriberPort,
-                            upstreamMeterId, sub.technologyProfileId(), true);
+    private void updateProgrammedSubscriber(ConnectPoint connectPoint, UniTagInformation tagInformation, Boolean add) {
+        programmedSubs.compute(connectPoint, (k, v) -> {
+            if (add) {
+                if (v == null) {
+                    v = Sets.newHashSet();
                 }
-
-                post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_REGISTERED,
-                        deviceId,
-                        deviceVlan,
-                        subscriberVlan));
-
-            } else if (downStatus != null) {
-                log.error("Subscriber with vlan {} on device {} " +
-                                "on port {} failed downstream installation: {}",
-                        subscriberVlan, deviceId, subscriberPort, downStatus);
-            } else if (upStatus != null) {
-                log.error("Subscriber with vlan {} on device {} " +
-                                "on port {} failed upstream installation: {}",
-                        subscriberVlan, deviceId, subscriberPort, upStatus);
+                v.add(tagInformation);
+            } else {
+                if (v != null) {
+                    v.remove(tagInformation);
+                }
             }
-        }, oltInstallers);
+            return v;
+        });
     }
 
-    private MeterId createMeter(DeviceId deviceId, BandwidthProfileInformation bpInfo,
-                                CompletableFuture<Object> meterFuture) {
-        if (bpInfo == null) {
-            log.warn("Bandwidth profile information cannot be null when creating meter");
-            return null;
+    /**
+     * Installs a uni tag information flow.
+     *
+     * @param deviceId       the access device id
+     * @param uplinkPort     the nni port
+     * @param subscriberPort the uni port
+     * @param tagInfo        the uni tag information
+     */
+    private void handleSubscriberFlows(DeviceId deviceId, PortNumber uplinkPort, PortNumber subscriberPort,
+                                       UniTagInformation tagInfo) {
+
+        log.info("Provisioning vlan-based flows for the uniTagInformation {}", tagInfo);
+
+        Port port = deviceService.getPort(deviceId, subscriberPort);
+
+        if (mcastServiceName.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, port, tagInfo.getPonSTag(), tagInfo.getPonCTag(),
+                    tagInfo.getTechnologyProfileId()));
+            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;
-        }
-
-        List<Band> meterBands = createMeterBands(bpInfo);
-
-        MeterRequest meterRequest = DefaultMeterRequest.builder()
-                .withBands(meterBands)
-                .withUnit(Meter.Unit.KB_PER_SEC)
-                .withContext(new MeterContext() {
-                    @Override
-                    public void onSuccess(MeterRequest op) {
-                        log.debug("meter addition confirmed for bpInfo:{}", bpInfo);
-                        meterFuture.complete(null);
-                    }
-
-                    @Override
-                    public void onError(MeterRequest op, MeterFailReason reason) {
-                        meterFuture.complete(reason);
-                    }
-                })
-                .forDevice(deviceId)
-                .fromApp(appId)
-                .burst()
-                .add();
-
-        Meter meter = meterService.submit(meterRequest);
-        addMeterIdToBpMapping(deviceId, meter.id(), bpInfo.id());
-        log.info("Meter creation message sent for Meter Id {}", meter.id());
-        programmedMeters.add(MeterKey.key(deviceId, meter.id()));
-        return meter.id();
-    }
-
-    private List<Band> createMeterBands(BandwidthProfileInformation bpInfo) {
-        List<Band> meterBands = new ArrayList<>();
-
-        meterBands.add(createMeterBand(bpInfo.committedInformationRate(), bpInfo.committedBurstSize()));
-        meterBands.add(createMeterBand(bpInfo.exceededInformationRate(), bpInfo.exceededBurstSize()));
-        meterBands.add(createMeterBand(bpInfo.assuredInformationRate(), 0L));
-
-        return meterBands;
-    }
-
-    private Band createMeterBand(long rate, Long burst) {
-        return DefaultBand.builder()
-                .withRate(rate) //already Kbps
-                .burstSize(burst) // already Kbits
-                .ofType(Band.Type.DROP) // no matter
-                .build();
-    }
-
-    private ForwardingObjective.Builder downBuilder(PortNumber uplinkPort,
-                                                    PortNumber subscriberPort,
-                                                    VlanId subscriberVlan,
-                                                    VlanId deviceVlan,
-                                                    Optional<VlanId> defaultVlan,
-                                                    MeterId meterId,
-                                                    int techProfId) {
-        TrafficSelector downstream = DefaultTrafficSelector.builder()
-                .matchVlanId(deviceVlan)
-                .matchInPort(uplinkPort)
-                .matchInnerVlanId(subscriberVlan)
-                .build();
-
-        TrafficTreatment.Builder downstreamTreatmentBuilder = DefaultTrafficTreatment.builder()
-                .popVlan()
-                .setVlanId(defaultVlan.orElse(VlanId.vlanId((short) this.defaultVlan)))
-                .setOutput(subscriberPort);
-
-        if (meterId != null) {
-            downstreamTreatmentBuilder.meter(meterId);
-        }
-
-        downstreamTreatmentBuilder.writeMetadata(createMetadata(subscriberVlan, techProfId, subscriberPort), 0);
-
-        return DefaultForwardingObjective.builder()
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .withPriority(1000)
-                .makePermanent()
-                .withSelector(downstream)
-                .fromApp(appId)
-                .withTreatment(downstreamTreatmentBuilder.build());
-    }
-
-    private ForwardingObjective.Builder upBuilder(PortNumber uplinkPort,
-                                                  PortNumber subscriberPort,
-                                                  VlanId subscriberVlan,
-                                                  VlanId deviceVlan,
-                                                  Optional<VlanId> defaultVlan,
-                                                  MeterId meterId,
-                                                  int technologyProfileId) {
-
-
-        VlanId dVlan = defaultVlan.orElse(VlanId.vlanId((short) this.defaultVlan));
-
-        if (subscriberVlan.toShort() == 4096) {
-            dVlan = subscriberVlan;
-        }
-
-        TrafficSelector upstream = DefaultTrafficSelector.builder()
-                .matchVlanId(dVlan)
-                .matchInPort(subscriberPort)
-                .build();
-
-
-        TrafficTreatment.Builder upstreamTreatmentBuilder = DefaultTrafficTreatment.builder()
-                .pushVlan()
-                .setVlanId(subscriberVlan)
-                .pushVlan()
-                .setVlanId(deviceVlan)
-                .setOutput(uplinkPort);
-
-        if (meterId != null) {
-            upstreamTreatmentBuilder.meter(meterId);
-        }
-
-        upstreamTreatmentBuilder.writeMetadata(createMetadata(deviceVlan, technologyProfileId, uplinkPort), 0L);
-
-        return DefaultForwardingObjective.builder()
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .withPriority(1000)
-                .makePermanent()
-                .withSelector(upstream)
-                .fromApp(appId)
-                .withTreatment(upstreamTreatmentBuilder.build());
-    }
-
-    private void provisionTransparentFlows(DeviceId deviceId, PortNumber uplinkPort,
-                                           PortNumber subscriberPort,
-                                           VlanId innerVlan,
-                                           VlanId outerVlan) {
-
         ConnectPoint cp = new ConnectPoint(deviceId, subscriberPort);
 
-        SubscriberAndDeviceInformation subInfo = getSubscriber(cp);
-
-        BandwidthProfileInformation upstreamBpInfo = getBandwidthProfileInformation(
-                subInfo.upstreamBandwidthProfile());
-        BandwidthProfileInformation downstreamBpInfo = getBandwidthProfileInformation(
-                subInfo.downstreamBandwidthProfile());
+        BandwidthProfileInformation upstreamBpInfo =
+                getBandwidthProfileInformation(tagInfo.getUpstreamBandwidthProfile());
+        BandwidthProfileInformation downstreamBpInfo =
+                getBandwidthProfileInformation(tagInfo.getDownstreamBandwidthProfile());
 
         CompletableFuture<Object> upstreamMeterFuture = new CompletableFuture<>();
         CompletableFuture<Object> downsteamMeterFuture = new CompletableFuture<>();
-        CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
-        CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
+        CompletableFuture<ObjectiveError> upFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> downFuture = new CompletableFuture<>();
 
-        MeterId upstreamMeterId = createMeter(deviceId, upstreamBpInfo, upstreamMeterFuture);
-        MeterId downstreamMeterId = createMeter(deviceId, downstreamBpInfo, downsteamMeterFuture);
+        MeterId upstreamMeterId = oltMeterService.createMeter(deviceId, upstreamBpInfo, upstreamMeterFuture);
+
+        MeterId downstreamMeterId = oltMeterService.createMeter(deviceId, downstreamBpInfo, downsteamMeterFuture);
 
         upstreamMeterFuture.thenAcceptAsync(result -> {
             if (result == null) {
                 log.info("Upstream Meter {} is sent to the device {}. " +
                         "Sending subscriber flows.", upstreamMeterId, deviceId);
 
-                ForwardingObjective.Builder upFwd = transparentUpBuilder(uplinkPort, subscriberPort,
-                        innerVlan, outerVlan, upstreamMeterId, subInfo);
+                ForwardingObjective.Builder upFwd =
+                        oltFlowService.createUpBuilder(uplinkPort, subscriberPort, upstreamMeterId, tagInfo);
 
                 flowObjectiveService.forward(deviceId, upFwd.add(new ObjectiveContext() {
                     @Override
                     public void onSuccess(Objective objective) {
+                        log.info("Upstream flow installed successfully");
                         upFuture.complete(null);
                     }
 
@@ -980,9 +635,15 @@
                     }
                 }));
 
+            } else if (upstreamBpInfo == null) {
+                log.warn("No meter installed since no Upstream BW Profile definition found for " +
+                                "ctag {} stag {} tpId {} and Device/port: {}:{}",
+                        tagInfo.getPonCTag(), tagInfo.getPonSTag(),
+                        tagInfo.getTechnologyProfileId(),
+                        deviceId, subscriberPort);
             } else {
-                log.error("Meter installation error for {} on {} while sending upstream flows. " +
-                        "Result {} and MeterId {}", deviceId, subscriberPort, result, upstreamMeterId);
+                log.warn("Meter installation error while sending upstream flows. " +
+                        "Result {} and MeterId {}", result, upstreamMeterId);
             }
         });
 
@@ -991,12 +652,13 @@
                 log.info("Downstream Meter {} is sent to the device {}. " +
                         "Sending subscriber flows.", downstreamMeterId, deviceId);
 
-                ForwardingObjective.Builder downFwd = transparentDownBuilder(uplinkPort, subscriberPort,
-                        innerVlan, outerVlan, downstreamMeterId, subInfo);
+                ForwardingObjective.Builder downFwd =
+                        oltFlowService.createDownBuilder(uplinkPort, subscriberPort, downstreamMeterId, tagInfo);
 
                 flowObjectiveService.forward(deviceId, downFwd.add(new ObjectiveContext() {
                     @Override
                     public void onSuccess(Objective objective) {
+                        log.info("Downstream flow installed successfully");
                         downFuture.complete(null);
                     }
 
@@ -1005,500 +667,94 @@
                         downFuture.complete(error);
                     }
                 }));
+
+            } else if (downstreamBpInfo == null) {
+                log.warn("No meter installed since no Downstream BW Profile definition found for " +
+                                "ctag {} stag {} tpId {} and Device/port: {}:{}",
+                        tagInfo.getPonCTag(), tagInfo.getPonSTag(),
+                        tagInfo.getTechnologyProfileId(),
+                        deviceId, subscriberPort);
             } else {
-                log.error("Meter installation error for {} on {} while sending downstream flows. " +
-                        "Result {} and MeterId {}", deviceId, subscriberPort, result, downstreamMeterId);
+                log.warn("Meter installation error while sending upstream flows. " +
+                        "Result {} and MeterId {}", result, downstreamMeterId);
             }
         });
 
-        additionalVlans.put(cp, new AbstractMap.SimpleEntry(outerVlan, innerVlan));
-
         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 device {} " +
                                 "on port {} failed downstream installation: {}",
-                        innerVlan, outerVlan, deviceId, cp, downStatus);
+                        tagInfo.getPonCTag(), tagInfo.getPonSTag(), deviceId, cp, downStatus);
+                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTRATION_FAILED;
             } else if (upStatus != null) {
                 log.error("Flow with innerVlan {} and outerVlan {} on device {} " +
                                 "on port {} failed upstream installation: {}",
-                        innerVlan, outerVlan, deviceId, cp, upStatus);
+                        tagInfo.getPonCTag(), tagInfo.getPonSTag(), deviceId, cp, upStatus);
+                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTRATION_FAILED;
             } else {
-                processEapolFilteringObjectives(deviceId, subscriberPort, subInfo.upstreamBandwidthProfile(),
-                        null, subInfo.cTag(), true);
+                log.info("Upstream and downstream data plane flows are installed successfully.");
+                oltFlowService.processEapolFilteringObjectives(deviceId, subscriberPort,
+                        tagInfo.getUpstreamBandwidthProfile(), null, tagInfo.getPonCTag(), true);
+                if (tagInfo.getIsDhcpRequired()) {
+                    oltFlowService.processDhcpFilteringObjectives(deviceId, subscriberPort,
+                            upstreamMeterId, tagInfo, true, true);
+                }
 
-                // cache subscriber info
-                programmedSubs.put(cp, subInfo);
+                if (tagInfo.getIsIgmpRequired()) {
+                    oltFlowService.processIgmpFilteringObjectives(deviceId, subscriberPort, upstreamMeterId, tagInfo,
+                            true, true);
+                }
+                updateProgrammedSubscriber(cp, tagInfo, true);
+                post(new AccessDeviceEvent(type, deviceId, port, tagInfo.getPonSTag(), tagInfo.getPonCTag(),
+                        tagInfo.getTechnologyProfileId()));
             }
         }, oltInstallers);
-
     }
 
-    private ForwardingObjective.Builder transparentDownBuilder(PortNumber uplinkPort,
-                                                               PortNumber subscriberPort,
-                                                               VlanId innerVlan,
-                                                               VlanId outerVlan,
-                                                               MeterId downstreamMeterId,
-                                                               SubscriberAndDeviceInformation subInfo) {
-        TrafficSelector downstream = DefaultTrafficSelector.builder()
-                .matchVlanId(outerVlan)
-                .matchInPort(uplinkPort)
-                .matchInnerVlanId(innerVlan)
-                .build();
-
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-        if (downstreamMeterId != null) {
-            tBuilder.meter(downstreamMeterId);
-        }
-
-        TrafficTreatment downstreamTreatment = tBuilder
-                .setOutput(subscriberPort)
-                .writeMetadata(createMetadata(subInfo.cTag(), subInfo.technologyProfileId(), subscriberPort), 0)
-                .build();
-
-        return DefaultForwardingObjective.builder()
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .withPriority(1000)
-                .makePermanent()
-                .withSelector(downstream)
-                .fromApp(appId)
-                .withTreatment(downstreamTreatment);
-    }
-
-    private ForwardingObjective.Builder transparentUpBuilder(PortNumber uplinkPort,
-                                                             PortNumber subscriberPort,
-                                                             VlanId innerVlan,
-                                                             VlanId outerVlan,
-                                                             MeterId upstreamMeterId,
-                                                             SubscriberAndDeviceInformation subInfo) {
-
-        TrafficSelector upstream = DefaultTrafficSelector.builder()
-                .matchVlanId(outerVlan)
-                .matchInPort(subscriberPort)
-                .matchInnerVlanId(innerVlan)
-                .build();
-
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-        if (upstreamMeterId != null) {
-            tBuilder.meter(upstreamMeterId);
-        }
-
-        TrafficTreatment upstreamTreatment = tBuilder
-                .setOutput(uplinkPort)
-                .writeMetadata(createMetadata(subInfo.sTag(), subInfo.technologyProfileId(), uplinkPort), 0)
-                .build();
-
-        return DefaultForwardingObjective.builder()
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .withPriority(1000)
-                .makePermanent()
-                .withSelector(upstream)
-                .fromApp(appId)
-                .withTreatment(upstreamTreatment);
-    }
-
-    private void unprovisionTransparentFlows(DeviceId deviceId, PortNumber uplink,
-                                             PortNumber subscriberPort, VlanId innerVlan,
-                                             VlanId outerVlan) {
-
-        ConnectPoint cp = new ConnectPoint(deviceId, subscriberPort);
-
-        SubscriberAndDeviceInformation subInfo = programmedSubs.get(cp);
+    /**
+     * Checks the subscriber uni tag list and find the uni tag information.
+     * using the pon c tag, pon s tag and the technology profile id
+     * May return Optional<null>
+     *
+     * @param cp        the connection point 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(ConnectPoint cp, VlanId innerVlan, VlanId outerVlan,
+                                                             int tpId) {
+        log.info("Getting uni tag information for cp: {}, innerVlan: {}, outerVlan: {}, tpId: {}", cp, innerVlan,
+                outerVlan, tpId);
+        SubscriberAndDeviceInformation subInfo = getSubscriber(cp);
         if (subInfo == null) {
-            log.warn("Subscriber is not programmed before for the connectPoint {}", cp);
-            return;
+            log.warn("Subscriber information doesn't exist for the connect point {}", cp);
+            return Optional.empty();
         }
 
-        additionalVlans.remove(cp, new AbstractMap.SimpleEntry(outerVlan, innerVlan));
+        List<UniTagInformation> uniTagList = subInfo.uniTagList();
+        if (uniTagList == null) {
+            log.warn("Uni tag list is not found for the subscriber {}", subInfo.id());
+            return Optional.empty();
+        }
 
-        CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
-        CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
-
-        MeterId upstreamMeterId = getMeterIdFromBpMapping(deviceId, subInfo.upstreamBandwidthProfile());
-        MeterId downstreamMeterId = getMeterIdFromBpMapping(deviceId, subInfo.downstreamBandwidthProfile());
-
-        ForwardingObjective.Builder upFwd = transparentUpBuilder(uplink, subscriberPort,
-                innerVlan, outerVlan, upstreamMeterId, subInfo);
-        ForwardingObjective.Builder downFwd = transparentDownBuilder(uplink, subscriberPort,
-                innerVlan, outerVlan, downstreamMeterId, subInfo);
-
-        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) -> {
-            if (downStatus != null) {
-                log.error("Flow with innerVlan {} and outerVlan {} on device {} " +
-                                "on port {} failed downstream uninstallation: {}",
-                        innerVlan, outerVlan, deviceId, subscriberPort, downStatus);
-            } else if (upStatus != null) {
-                log.error("Flow with innerVlan {} and outerVlan {} on device {} " +
-                                "on port {} failed upstream uninstallation: {}",
-                        innerVlan, outerVlan, deviceId, subscriberPort, upStatus);
-            }
-        }, oltInstallers);
-
-        //re-install eapol
-        processEapolFilteringObjectives(deviceId, subscriberPort,
-                subInfo.upstreamBandwidthProfile(), null, subInfo.cTag(), false);
-        processEapolFilteringObjectives(deviceId, subscriberPort, defaultBpId,
-                null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
-
-        programmedMeters.remove(MeterKey.key(deviceId, upstreamMeterId));
-        programmedMeters.remove(MeterKey.key(deviceId, downstreamMeterId));
-    }
-
-    private int getDefaultTechProfileId(DeviceId devId, PortNumber portNumber) {
-        Port port = deviceService.getPort(devId, portNumber);
-        if (port != null) {
-            SubscriberAndDeviceInformation info = subsService.get(port.annotations().value(AnnotationKeys.PORT_NAME));
-            if (info != null && info.technologyProfileId() != -1) {
-                return info.technologyProfileId();
+        UniTagInformation service = null;
+        for (UniTagInformation tagInfo : subInfo.uniTagList()) {
+            if (innerVlan.equals(tagInfo.getPonCTag()) && outerVlan.equals(tagInfo.getPonSTag())
+                    && tpId == tagInfo.getTechnologyProfileId()) {
+                service = tagInfo;
+                break;
             }
         }
-        return defaultTechProfileId;
-    }
 
-    /**
-     * 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
-     * @return the write metadata value including tech profile reference and innerVlan
-     */
-    private Long createTechProfValueForWm(VlanId cVlan, int techProfileId) {
-        if (cVlan == null) {
-            return (long) techProfileId << 32;
-        }
-        return ((long) (cVlan.id()) << 48 | (long) techProfileId << 32);
-    }
-
-    /**
-     * Trap eapol authentication packets to the controller.
-     *
-     * @param devId        the device identifier
-     * @param portNumber   the port for which this trap flow is designated
-     * @param bpId         bandwidth profile id 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
-     */
-    private void processEapolFilteringObjectives(DeviceId devId, PortNumber portNumber, String bpId,
-                                                 CompletableFuture<ObjectiveError> filterFuture,
-                                                 VlanId vlanId, boolean install) {
-        if (!enableEapol) {
-            log.debug("Eapol filtering is disabled.");
-            if (filterFuture != null) {
-                filterFuture.complete(null);
-            }
-            return;
+        if (service == null) {
+            log.warn("SADIS doesn't include the service with ponCtag {} ponStag {} and tpId {}",
+                    innerVlan, outerVlan, tpId);
+            return Optional.empty();
         }
 
-        if (!mastershipService.isLocalMaster(devId)) {
-            return;
-        }
-        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-        CompletableFuture<Object> meterFuture = new CompletableFuture<>();
-
-        BandwidthProfileInformation bpInfo = getBandwidthProfileInformation(bpId);
-        if (bpInfo == null) {
-            log.warn("Bandwidth profile {} is not found. Authentication flow"
-                    + " will not be installed", bpId);
-            return;
-        }
-
-        // check if meter exists and create it only for an install
-        MeterId meterId = getMeterIdFromBpMapping(devId, bpInfo.id());
-        if (meterId == null) {
-            if (install) {
-                meterId = createMeter(devId, bpInfo, meterFuture);
-                treatmentBuilder.meter(meterId);
-            } 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 for {}/{}", bpInfo.id(), devId,
-                         portNumber);
-                meterFuture.complete(null);
-            }
-        } else {
-            log.debug("Meter {} was previously created for bp {}", meterId,
-                      bpInfo.id());
-            treatmentBuilder.meter(meterId);
-            meterFuture.complete(null);
-        }
-
-        final MeterId mId = meterId;
-        meterFuture.thenAcceptAsync(result -> {
-            if (result == null) {
-                log.info("Meter {} for {} on {}/{} exists. {} EAPOL trap flow",
-                         mId, bpId, devId, portNumber,
-                        (install) ? "Installing " : "Removing ");
-                int techProfileId = getDefaultTechProfileId(devId, portNumber);
-
-                //Authentication trap flow uses only tech profile id as write metadata value
-                FilteringObjective eapol = (install ? builder.permit() : builder.deny())
-                        .withKey(Criteria.matchInPort(portNumber))
-                        .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
-                        .addCondition(Criteria.matchVlanId(vlanId))
-                        .withMeta(treatmentBuilder
-                                .writeMetadata(createTechProfValueForWm(vlanId, techProfileId), 0)
-                                .setOutput(PortNumber.CONTROLLER).build())
-                        .fromApp(appId)
-                        .withPriority(10000)
-                        .add(new ObjectiveContext() {
-                            @Override
-                            public void onSuccess(Objective objective) {
-                                log.info("Eapol filter for {} on {} {} with meter {}.",
-                                        devId, portNumber, (install) ? INSTALLED : REMOVED, mId);
-                                if (filterFuture != null) {
-                                    filterFuture.complete(null);
-                                }
-                            }
-
-                            @Override
-                            public void onError(Objective objective, ObjectiveError error) {
-                                log.info("Eapol filter for {} on {} with meter {} failed {} because {}",
-                                        devId, portNumber, mId, (install) ? INSTALLATION : REMOVAL,
-                                        error);
-                                if (filterFuture != null) {
-                                    filterFuture.complete(error);
-                                }
-                            }
-                        });
-
-                flowObjectiveService.filter(devId, eapol);
-            } else {
-                log.error("Meter installation error for {} on {} while sending eapol trap flow. " +
-                        "Result {} and MeterId {}", devId, portNumber, result, mId);
-            }
-        });
-    }
-
-    /**
-     * Installs trap filtering objectives for particular traffic types on an
-     * NNI port.
-     *
-     * @param devId   device ID
-     * @param port    port number
-     * @param install true to install, false to remove
-     */
-    private void processNniFilteringObjectives(DeviceId devId, PortNumber port, boolean install) {
-        processLldpFilteringObjective(devId, port, install);
-        processDhcpFilteringObjectives(devId, port, null, -1, install, false);
-    }
-
-    private void processLldpFilteringObjective(DeviceId devId, PortNumber port, boolean install) {
-        if (!mastershipService.isLocalMaster(devId)) {
-            return;
-        }
-        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
-
-        FilteringObjective lldp = (install ? builder.permit() : builder.deny())
-                .withKey(Criteria.matchInPort(port))
-                .addCondition(Criteria.matchEthType(EthType.EtherType.LLDP.ethType()))
-                .withMeta(DefaultTrafficTreatment.builder()
-                        .setOutput(PortNumber.CONTROLLER).build())
-                .fromApp(appId)
-                .withPriority(10000)
-                .add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        log.info("LLDP filter for device {} on port {} {}.",
-                                devId, port, (install) ? INSTALLED : REMOVED);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        log.info("LLDP filter for device {} on port {} failed {} because {}",
-                                devId, port, (install) ? INSTALLATION : REMOVAL,
-                                error);
-                    }
-                });
-
-        flowObjectiveService.filter(devId, lldp);
-
-    }
-
-    /**
-     * Trap dhcp packets to the controller.
-     *
-     * @param devId           the device identifier
-     * @param port            the 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 techProfileId   the technology profile id that is used to create write
-     *                        metadata instruction value. If no tech profile id needs to be referenced,
-     *                        -1 can be sent
-     * @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
-     */
-    private void processDhcpFilteringObjectives(DeviceId devId, PortNumber port,
-                                                MeterId upstreamMeterId,
-                                                int techProfileId,
-                                                boolean install,
-                                                boolean upstream) {
-
-        if (!enableDhcpOnProvisioning) {
-            log.debug("Dhcp provisioning is disabled.");
-            return;
-        }
-
-        if (!mastershipService.isLocalMaster(devId)) {
-            return;
-        }
-
-        if (enableDhcpV4) {
-            int udpSrc = (upstream) ? 68 : 67;
-            int udpDst = (upstream) ? 67 : 68;
-
-            EthType ethType = EthType.EtherType.IPV4.ethType();
-            byte protocol = IPv4.PROTOCOL_UDP;
-
-            this.addDhcpFilteringObjectives(devId, port, udpSrc, udpDst, ethType,
-                    upstreamMeterId, techProfileId, protocol, install);
-        }
-
-        if (enableDhcpV6) {
-            int udpSrc = (upstream) ? 547 : 546;
-            int udpDst = (upstream) ? 546 : 547;
-
-            EthType ethType = EthType.EtherType.IPV6.ethType();
-            byte protocol = IPv6.PROTOCOL_UDP;
-
-            this.addDhcpFilteringObjectives(devId, port, udpSrc, udpDst, ethType,
-                    upstreamMeterId, techProfileId, protocol, install);
-        }
-
-    }
-
-    private void addDhcpFilteringObjectives(DeviceId devId,
-                                            PortNumber port,
-                                            int udpSrc,
-                                            int udpDst,
-                                            EthType ethType,
-                                            MeterId upstreamMeterId,
-                                            int techProfileId,
-                                            byte protocol,
-                                            boolean install) {
-
-        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-
-        if (upstreamMeterId != null) {
-            treatmentBuilder.meter(upstreamMeterId);
-        }
-
-        if (techProfileId != -1) {
-            treatmentBuilder.writeMetadata(createTechProfValueForWm(null, techProfileId), 0);
-        }
-
-        FilteringObjective dhcpUpstream = (install ? builder.permit() : builder.deny())
-                .withKey(Criteria.matchInPort(port))
-                .addCondition(Criteria.matchEthType(ethType))
-                .addCondition(Criteria.matchIPProtocol(protocol))
-                .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(udpSrc)))
-                .addCondition(Criteria.matchUdpDst(TpPort.tpPort(udpDst)))
-                .withMeta(treatmentBuilder
-                        .setOutput(PortNumber.CONTROLLER).build())
-                .fromApp(appId)
-                .withPriority(10000)
-                .add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        log.info("DHCP {} filter for device {} on port {} {}.",
-                                (ethType.equals(EthType.EtherType.IPV4.ethType())) ? "v4" : "v6",
-                                devId, port, (install) ? INSTALLED : REMOVED);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        log.info("DHCP {} filter for device {} on port {} failed {} because {}",
-                                (ethType.equals(EthType.EtherType.IPV4.ethType())) ? "v4" : "v6",
-                                devId, port, (install) ? INSTALLATION : REMOVAL,
-                                error);
-                    }
-                });
-
-        flowObjectiveService.filter(devId, dhcpUpstream);
-    }
-
-    private void processIgmpFilteringObjectives(DeviceId devId, PortNumber port,
-                                                MeterId upstreamMeterId,
-                                                int techProfileId,
-                                                boolean install) {
-
-        if (!enableIgmpOnProvisioning) {
-            log.debug("Igmp provisioning is disabled.");
-            return;
-        }
-
-        if (!mastershipService.isLocalMaster(devId)) {
-            return;
-        }
-
-        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-
-        if (upstreamMeterId != null) {
-            treatmentBuilder.meter(upstreamMeterId);
-        }
-
-        if (techProfileId != -1) {
-            treatmentBuilder.writeMetadata(createTechProfValueForWm(null, techProfileId), 0);
-        }
-
-        builder = install ? builder.permit() : builder.deny();
-
-        FilteringObjective igmp = builder
-                .withKey(Criteria.matchInPort(port))
-                .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
-                .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_IGMP))
-                .withMeta(treatmentBuilder
-                        .setOutput(PortNumber.CONTROLLER).build())
-                .fromApp(appId)
-                .withPriority(10000)
-                .add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        log.info("Igmp filter for {} on {} {}.",
-                                devId, port, (install) ? INSTALLED : REMOVED);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        log.info("Igmp filter for {} on {} failed {} because {}.",
-                                devId, port, (install) ? INSTALLATION : REMOVAL,
-                                error);
-                    }
-                });
-
-        flowObjectiveService.filter(devId, igmp);
+        return Optional.of(service);
     }
 
     /**
@@ -1514,16 +770,20 @@
         }
         // check if this device is provisioned in Sadis
         SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
-        log.debug("checkAndCreateDeviceFlows: deviceInfo {}", deviceInfo);
+        log.info("checkAndCreateDeviceFlows: deviceInfo {}", deviceInfo);
 
         if (deviceInfo != null) {
             // This is an OLT device as per Sadis, we create flows for UNI and NNI ports
             for (Port p : deviceService.getPorts(dev.id())) {
+                if (PortNumber.LOCAL.equals(p.number())) {
+                    continue;
+                }
                 if (isUniPort(dev, p)) {
-                    processEapolFilteringObjectives(dev.id(), p.number(), defaultBpId, null,
+                    log.info("Creating Eapol for the uni {}", p);
+                    oltFlowService.processEapolFilteringObjectives(dev.id(), p.number(), defaultBpId, null,
                             VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
                 } else {
-                    processNniFilteringObjectives(dev.id(), p.number(), true);
+                    oltFlowService.processNniFilteringObjectives(dev.id(), p.number(), true);
                 }
             }
         }
@@ -1574,22 +834,12 @@
     }
 
     /**
-     * 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)
+     * 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 Long createMetadata(VlanId innerVlan, int techProfileId, PortNumber egressPort) {
-
-        if (techProfileId == -1) {
-            techProfileId = DEFAULT_TP_ID;
-        }
-
-        return ((long) (innerVlan.id()) << 48 | (long) techProfileId << 32) | egressPort.toLong();
-    }
-
     private boolean isUniPort(Device d, Port p) {
         Port ulPort = getUplinkPort(d);
         if (ulPort != null) {
@@ -1598,64 +848,18 @@
         return false;
     }
 
+    /**
+     * 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) {
         String devSerialNo = dev.serialNumber();
         return subsService.get(devSerialNo);
     }
 
-    private MeterId getMeterIdFromBpMapping(DeviceId deviceId, String bandwidthProfile) {
-        if (bpInfoToMeter.get(bandwidthProfile) == null) {
-            log.warn("Bandwidth Profile '{}' is not currently mapped to a meter",
-                      bandwidthProfile);
-            return null;
-        }
-
-        Optional<MeterKey> meterKeyForDevice = bpInfoToMeter.get(bandwidthProfile)
-                .stream()
-                .filter(meterKey -> meterKey.deviceId().equals(deviceId))
-                .findFirst();
-        if (meterKeyForDevice.isPresent()) {
-            log.debug("Found meter {} for bandwidth profile {}",
-                      meterKeyForDevice.get().meterId(), bandwidthProfile);
-            return meterKeyForDevice.get().meterId();
-        } else {
-            log.warn("Bandwidth profile '{}' is not currently mapped to a meter",
-                     bandwidthProfile);
-            return null;
-        }
-    }
-
-    private void addMeterIdToBpMapping(DeviceId deviceId, MeterId meterId, String bandwidthProfile) {
-
-        if (bpInfoToMeter.get(bandwidthProfile) == null) {
-            bpInfoToMeter.put(bandwidthProfile,
-                    new ArrayList<>(Arrays.asList(MeterKey.key(deviceId, meterId))));
-        } else {
-            List<MeterKey> meterKeyListForBp = bpInfoToMeter.get(bandwidthProfile);
-            meterKeyListForBp.add(MeterKey.key(deviceId, meterId));
-        }
-    }
-
-    /**
-     * Removes meter key from programmed meters. If the meter has no reference
-     * count in the data plane and is not present in the programmed-meters store
-     * it will be removed.
-     *
-     * @param deviceId device identifier
-     * @param bandwidthProfileId name of bandwidth profile
-     */
-    private void removeMeterIdFromPrgMeters(DeviceId deviceId,
-                                             String bandwidthProfileId) {
-        List<MeterKey> meterKeysForBp = bpInfoToMeter.get(bandwidthProfileId);
-        if (meterKeysForBp != null) {
-            meterKeysForBp.stream()
-                    .filter(meterKey -> meterKey.deviceId().equals(deviceId))
-                    .findFirst().ifPresent(mk -> {
-                programmedMeters.remove(mk);
-            });
-        }
-    }
-
     private class InternalDeviceListener implements DeviceListener {
         private Set<DeviceId> programmedDevices = Sets.newConcurrentHashSet();
 
@@ -1665,11 +869,16 @@
                 DeviceId devId = event.subject().id();
                 Device dev = event.subject();
                 Port port = event.port();
+                DeviceEvent.Type eventType = event.type();
 
-                if (event.type() == DeviceEvent.Type.PORT_STATS_UPDATED) {
+                if (DeviceEvent.Type.PORT_STATS_UPDATED.equals(eventType) ||
+                        DeviceEvent.Type.DEVICE_SUSPENDED.equals(eventType) ||
+                        DeviceEvent.Type.DEVICE_UPDATED.equals(eventType)) {
                     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
@@ -1681,112 +890,106 @@
                     }
                 }
 
-                log.debug("OLT got {} event for {}: {}", event.type(),
-                          event.subject().id(), event);
-
                 switch (event.type()) {
                     //TODO: Port handling and bookkeeping should be improved once
                     // olt firmware handles correct behaviour.
                     case PORT_ADDED:
                         if (isUniPort(dev, port)) {
                             post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_ADDED, devId, port));
-                            if (port.isEnabled()) {
-                                processEapolFilteringObjectives(devId, port.number(), defaultBpId,
+
+                            if (port.isEnabled() && !port.number().equals(PortNumber.LOCAL)) {
+                                log.info("eapol will be sent for port added {}", port);
+                                oltFlowService.processEapolFilteringObjectives(devId, port.number(), defaultBpId,
                                         null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
                             }
                         } else {
-                            checkAndCreateDeviceFlows(dev);
+                            SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
+                            if (deviceInfo != null) {
+                                oltFlowService.processNniFilteringObjectives(dev.id(), port.number(), true);
+                            }
                         }
                         break;
                     case PORT_REMOVED:
                         if (isUniPort(dev, port)) {
                             removeSubscriber(new ConnectPoint(devId, port.number()));
-                            processEapolFilteringObjectives(devId, port.number(), defaultBpId,
+                            log.info("eapol will be send for port removed", port);
+                            oltFlowService.processEapolFilteringObjectives(devId, port.number(), defaultBpId,
                                     null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
 
                             post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_REMOVED, devId, port));
                         }
-
                         break;
                     case PORT_UPDATED:
                         if (!isUniPort(dev, port)) {
                             break;
                         }
-
-                        SubscriberAndDeviceInformation sub = programmedSubs
+                        Set<UniTagInformation> uniTagInformationSet = programmedSubs
                                 .get(new ConnectPoint(devId, port.number()));
-                        VlanId vlanId = sub == null ? VlanId.vlanId(EAPOL_DEFAULT_VLAN) : sub.cTag();
-
-                        String bpId = getCurrentBandwidthProfile(new ConnectPoint(devId, port.number()));
-
+                        if (uniTagInformationSet == null || uniTagInformationSet.isEmpty()) {
+                            if (port.isEnabled() && !port.number().equals(PortNumber.LOCAL)) {
+                                log.info("eapol will be processed for port updated {}", port);
+                                oltFlowService.processEapolFilteringObjectives(devId, port.number(), DEFAULT_BP_ID,
+                                        null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), port.isEnabled());
+                            }
+                        } else {
+                            log.info("eapol will be processed for port updated {}", port);
+                            uniTagInformationSet.forEach(uniTag ->
+                                    oltFlowService.processEapolFilteringObjectives(devId, port.number(),
+                                            uniTag.getUpstreamBandwidthProfile(), null,
+                                            uniTag.getPonCTag(), port.isEnabled()));
+                        }
                         if (port.isEnabled()) {
-                            processEapolFilteringObjectives(devId, port.number(), bpId,
-                                    null, vlanId, true);
-
                             post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_ADDED, devId, port));
                         } else {
-                            processEapolFilteringObjectives(devId, port.number(), bpId,
-                                    null, vlanId, false);
                             post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_REMOVED, devId, port));
                         }
                         break;
                     case DEVICE_ADDED:
-                        post(new AccessDeviceEvent(
-                                AccessDeviceEvent.Type.DEVICE_CONNECTED, devId,
-                                null, null));
-                        programmedDevices.add(devId);
-                        // Send UNI_ADDED events for all existing ports
-                        deviceService.getPorts(devId).stream()
-                                .filter(p -> isUniPort(dev, p))
-                                .filter(Port::isEnabled)
-                                .forEach(p -> post(new AccessDeviceEvent(
-                                        AccessDeviceEvent.Type.UNI_ADDED, devId, p)));
-
-                        checkAndCreateDeviceFlows(dev);
+                        handleDeviceConnection(dev, true);
                         break;
                     case DEVICE_REMOVED:
-                        deviceService.getPorts(devId).stream()
-                                .filter(p -> isUniPort(dev, p))
-                                .forEach(p -> post(new AccessDeviceEvent(
-                                        AccessDeviceEvent.Type.UNI_REMOVED, devId, p)));
-                        programmedDevices.remove(devId);
-                        removeAllSubscribers(devId);
-                        removeDeviceMetersFromBpMap(devId);
-                        post(new AccessDeviceEvent(
-                                AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId,
-                                null, null));
+                        handleDeviceDisconnection(dev, true);
                         break;
                     case DEVICE_AVAILABILITY_CHANGED:
                         if (deviceService.isAvailable(devId)) {
-                            post(new AccessDeviceEvent(
-                                    AccessDeviceEvent.Type.DEVICE_CONNECTED, devId,
-                                    null, null));
-                            programmedDevices.add(devId);
-                            checkAndCreateDeviceFlows(dev);
+                            handleDeviceConnection(dev, false);
                         } else {
-                            programmedDevices.remove(devId);
-                            removeAllSubscribers(devId);
-                            removeDeviceMetersFromBpMap(devId);
-                            post(new AccessDeviceEvent(
-                                    AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId,
-                                    null, null));
+                            handleDeviceDisconnection(dev, false);
                         }
                         break;
-                    case DEVICE_UPDATED:
-                    case DEVICE_SUSPENDED:
-                    case PORT_STATS_UPDATED:
                     default:
                         return;
                 }
             });
         }
 
-        private String getCurrentBandwidthProfile(ConnectPoint connectPoint) {
-            SubscriberAndDeviceInformation sub = programmedSubs.get(connectPoint);
-            if (sub != null) {
-                return sub.upstreamBandwidthProfile();
+        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 sendUniEvent) {
+            programmedDevices.remove(device.id());
+            removeAllSubscribers(device.id());
+            post(new AccessDeviceEvent(
+                    AccessDeviceEvent.Type.DEVICE_DISCONNECTED, device.id(),
+                    null, null, null));
+            if (sendUniEvent) {
+                sendUniEvent(device, AccessDeviceEvent.Type.UNI_REMOVED);
             }
-            return defaultBpId;
+        }
+
+        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);
+            }
         }
 
         private void removeAllSubscribers(DeviceId deviceId) {
@@ -1797,64 +1000,5 @@
             connectPoints.forEach(cp -> programmedSubs.remove(cp));
         }
 
-        private void removeDeviceMetersFromBpMap(DeviceId deviceId) {
-            bpInfoToMeter.values().forEach(meterKeys -> meterKeys.stream()
-                    .filter(meterKey -> meterKey.deviceId().equals(deviceId)).findFirst().
-                            ifPresent(mk -> {
-                                meterKeys.remove(mk);
-                                programmedMeters.remove(mk);
-                                log.info("Deleted from the internal map. MeterKey {}", mk);
-                                log.info("Programmed meters {}", programmedMeters);
-                            }));
-        }
-
-    }
-
-    private class InternalMeterListener implements MeterListener {
-
-        @Override
-        public void event(MeterEvent meterEvent) {
-            if (deleteMeters && MeterEvent.Type.METER_REFERENCE_COUNT_ZERO.equals(meterEvent.type())) {
-                log.debug("Zero Count Meter {} received", meterEvent.subject());
-                Meter meter = meterEvent.subject();
-                if (meter != null && appId.equals(meter.appId()) &&
-                        !programmedMeters.contains(MeterKey.key(meter.deviceId(), meter.id()))) {
-                    log.info("Deleting unreferenced, no longer programmed Meter {}",
-                             meter.id());
-                    deleteMeter(meter.deviceId(), meter.id());
-                }
-            } else if (MeterEvent.Type.METER_REMOVED.equals(meterEvent.type())) {
-                log.debug("Meter removed event is received. Meter is {}",
-                          meterEvent.subject());
-                removeMeterFromBpMap(meterEvent.subject());
-            }
-        }
-
-        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 removeMeterFromBpMap(Meter meter) {
-            bpInfoToMeter.values().forEach(meterKeys -> meterKeys.stream()
-                    .filter(meterKey -> (meterKey.deviceId().equals(meter.deviceId()))
-                            && meterKey.meterId().equals(meter.id())).findFirst().
-                            ifPresent(mk -> {
-                                meterKeys.remove(mk);
-                                programmedMeters.remove(mk);
-                                log.info("Deleted from the internal map. MeterKey {}", mk);
-                                log.info("Programmed meters {}", programmedMeters);
-                            }));
-        }
     }
 }
diff --git a/app/src/main/java/org/opencord/olt/impl/OltFlowService.java b/app/src/main/java/org/opencord/olt/impl/OltFlowService.java
new file mode 100644
index 0000000..3f683ef
--- /dev/null
+++ b/app/src/main/java/org/opencord/olt/impl/OltFlowService.java
@@ -0,0 +1,698 @@
+/*
+ * 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.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+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.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DeviceId;
+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.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+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.meter.MeterId;
+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;
+import org.opencord.sadis.UniTagInformation;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+
+import java.util.Dictionary;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.onlab.util.Tools.get;
+import static org.slf4j.LoggerFactory.getLogger;
+
+@Service
+@Component(immediate = true)
+public class OltFlowService implements AccessDeviceFlowService {
+
+    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 int DEFAULT_TP_ID = 64;
+    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 static final String NO_MAC = "A4:23:05:00:00:00";
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected SadisService sadisService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected AccessDeviceMeterService oltMeterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService componentConfigService;
+
+    @Property(name = "enableIgmpOnProvisioning", boolValue = false,
+            label = "Create IGMP Flow rules when an NNI port is up")
+    protected boolean enableIgmpOnProvisioning = false;
+
+    @Property(name = "enableDhcpOnProvisioning", boolValue = true,
+            label = "Create the DHCP Flow rules when an NNI port is up")
+    protected boolean enableDhcpOnProvisioning = false;
+
+    @Property(name = "enableDhcpV4", boolValue = true,
+            label = "Enable flows for DHCP v4")
+    protected boolean enableDhcpV4 = true;
+
+    @Property(name = "enableDhcpV6", boolValue = false,
+            label = "Enable flows for DHCP v6")
+    protected boolean enableDhcpV6 = false;
+
+    @Property(name = "enableEapol", boolValue = false,
+            label = "Send EAPOL authentication trap flows before subscriber provisioning")
+    protected boolean enableEapol = false;
+
+    @Property(name = "defaultTechProfileId", intValue = DEFAULT_TP_ID,
+            label = "Default technology profile id that is used for authentication trap flows")
+    protected int defaultTechProfileId = DEFAULT_TP_ID;
+
+    protected ApplicationId appId;
+    protected BaseInformationService<BandwidthProfileInformation> bpService;
+    protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
+    private Set<PortNumber> pendingAddEapol = Sets.newConcurrentHashSet();
+
+    @Activate
+    public void activate(ComponentContext context) {
+        bpService = sadisService.getBandwidthProfileService();
+        subsService = sadisService.getSubscriberInfoService();
+        componentConfigService.registerProperties(getClass());
+        appId = coreService.getAppId(APP_NAME);
+        log.info("Olt Flow Service started");
+    }
+
+
+    @Deactivate
+    public void deactivate(ComponentContext context) {
+        componentConfigService.unregisterProperties(getClass(), false);
+        log.info("Olt flow service stopped");
+    }
+
+    @Modified
+    public void modified(ComponentContext context) {
+
+        Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
+
+        Boolean o = Tools.isPropertyEnabled(properties, "enableDhcpOnProvisioning");
+        if (o != null) {
+            enableDhcpOnProvisioning = o;
+        }
+
+        Boolean v4 = Tools.isPropertyEnabled(properties, "enableDhcpV4");
+        if (v4 != null) {
+            enableDhcpV4 = v4;
+        }
+
+        Boolean v6 = Tools.isPropertyEnabled(properties, "enableDhcpV6");
+        if (v6 != null) {
+            enableDhcpV6 = v6;
+        }
+
+        Boolean p = Tools.isPropertyEnabled(properties, "enableIgmpOnProvisioning");
+        if (p != null) {
+            enableIgmpOnProvisioning = p;
+        }
+
+        Boolean eap = Tools.isPropertyEnabled(properties, "enableEapol");
+        if (eap != null) {
+            enableEapol = eap;
+        }
+
+        String tpId = get(properties, "defaultTechProfileId");
+        defaultTechProfileId = isNullOrEmpty(tpId) ? DEFAULT_TP_ID : Integer.parseInt(tpId.trim());
+
+    }
+
+    @Override
+    public void processDhcpFilteringObjectives(DeviceId devId, PortNumber port,
+                                               MeterId upstreamMeterId,
+                                               UniTagInformation tagInformation,
+                                               boolean install,
+                                               boolean upstream) {
+        if (!enableDhcpOnProvisioning && !upstream) {
+            log.debug("Dhcp provisioning is disabled.");
+            return;
+        }
+
+        if (!mastershipService.isLocalMaster(devId)) {
+            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;
+
+        if (enableDhcpV4) {
+            int udpSrc = (upstream) ? 68 : 67;
+            int udpDst = (upstream) ? 67 : 68;
+
+            EthType ethType = EthType.EtherType.IPV4.ethType();
+            byte protocol = IPv4.PROTOCOL_UDP;
+
+            this.addDhcpFilteringObjectives(devId, port, udpSrc, udpDst, ethType,
+                    upstreamMeterId, techProfileId, protocol, cTag, unitagMatch, install);
+        }
+
+        if (enableDhcpV6) {
+            int udpSrc = (upstream) ? 547 : 546;
+            int udpDst = (upstream) ? 546 : 547;
+
+            EthType ethType = EthType.EtherType.IPV6.ethType();
+            byte protocol = IPv6.PROTOCOL_UDP;
+
+            this.addDhcpFilteringObjectives(devId, port, udpSrc, udpDst, ethType,
+                    upstreamMeterId, techProfileId, protocol, cTag, unitagMatch, install);
+        }
+    }
+
+    private void addDhcpFilteringObjectives(DeviceId devId, PortNumber port, int udpSrc, int udpDst,
+                                            EthType ethType, MeterId upstreamMeterId, int techProfileId, byte protocol,
+                                            VlanId cTag, VlanId unitagMatch, boolean install) {
+
+        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+
+        if (upstreamMeterId != null) {
+            treatmentBuilder.meter(upstreamMeterId);
+        }
+
+        if (techProfileId != NONE_TP_ID) {
+            treatmentBuilder.writeMetadata(createTechProfValueForWm(unitagMatch, techProfileId), 0);
+        }
+
+        FilteringObjective.Builder dhcpUpstreamBuilder = (install ? builder.permit() : builder.deny())
+                .withKey(Criteria.matchInPort(port))
+                .addCondition(Criteria.matchEthType(ethType))
+                .addCondition(Criteria.matchIPProtocol(protocol))
+                .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(udpSrc)))
+                .addCondition(Criteria.matchUdpDst(TpPort.tpPort(udpDst)))
+                .withMeta(treatmentBuilder
+                        .setOutput(PortNumber.CONTROLLER).build())
+                .fromApp(appId)
+                .withPriority(MAX_PRIORITY);
+
+        if (!VlanId.NONE.equals(cTag)) {
+            dhcpUpstreamBuilder.addCondition(Criteria.matchVlanId(cTag));
+        }
+
+        FilteringObjective dhcpUpstream = dhcpUpstreamBuilder.add(new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.info("DHCP {} filter for device {} on port {} {}.",
+                        (ethType.equals(EthType.EtherType.IPV4.ethType())) ? V4 : V6,
+                        devId, port, (install) ? INSTALLED : REMOVED);
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.info("DHCP {} filter for device {} on port {} failed {} because {}",
+                        (ethType.equals(EthType.EtherType.IPV4.ethType())) ? V4 : V6,
+                        devId, port, (install) ? INSTALLATION : REMOVAL,
+                        error);
+            }
+        });
+
+        flowObjectiveService.filter(devId, dhcpUpstream);
+
+    }
+
+    @Override
+    public void processIgmpFilteringObjectives(DeviceId devId, PortNumber port,
+                                               MeterId upstreamMeterId,
+                                               UniTagInformation tagInformation,
+                                               boolean install,
+                                               boolean upstream) {
+        if (!enableIgmpOnProvisioning && !upstream) {
+            log.debug("Igmp provisioning is disabled.");
+            return;
+        }
+
+        if (!mastershipService.isLocalMaster(devId)) {
+            return;
+        }
+
+        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+        if (upstream) {
+
+            if (tagInformation.getTechnologyProfileId() != NONE_TP_ID) {
+                treatmentBuilder.writeMetadata(createTechProfValueForWm(null,
+                        tagInformation.getTechnologyProfileId()), 0);
+            }
+
+
+            if (upstreamMeterId != null) {
+                treatmentBuilder.meter(upstreamMeterId);
+            }
+
+            if (!VlanId.NONE.equals(tagInformation.getPonCTag())) {
+                builder.addCondition(Criteria.matchVlanId(tagInformation.getPonCTag()));
+            }
+
+            if (tagInformation.getUsPonCTagPriority() != NO_PCP) {
+                builder.addCondition(Criteria.matchVlanPcp((byte) tagInformation.getUsPonCTagPriority()));
+            }
+        }
+
+        builder = install ? builder.permit() : builder.deny();
+
+        FilteringObjective igmp = builder
+                .withKey(Criteria.matchInPort(port))
+                .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 {} on {} {}.",
+                                devId, port, (install) ? INSTALLED : REMOVED);
+                    }
+
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.info("Igmp filter for {} on {} failed {} because {}.",
+                                devId, port, (install) ? INSTALLATION : REMOVAL,
+                                error);
+                    }
+                });
+
+        flowObjectiveService.filter(devId, igmp);
+    }
+
+    @Override
+    public void processEapolFilteringObjectives(DeviceId devId, PortNumber portNumber, String bpId,
+                                                CompletableFuture<ObjectiveError> filterFuture,
+                                                VlanId vlanId, boolean install) {
+
+        if (!enableEapol) {
+            log.debug("Eapol filtering is disabled. Completing filteringFuture immediately for the device {}", devId);
+            if (filterFuture != null) {
+                filterFuture.complete(null);
+            }
+            return;
+        }
+
+        if (!mastershipService.isLocalMaster(devId)) {
+            log.warn("The master of the device {} is another instance", devId);
+            if (filterFuture != null) {
+                filterFuture.complete(ObjectiveError.DEVICEMISSING);
+            }
+            return;
+        }
+
+        BandwidthProfileInformation bpInfo = getBandwidthProfileInformation(bpId);
+        if (bpInfo == null) {
+            log.warn("Bandwidth profile {} is not found. Authentication flow"
+                    + " will not be installed", bpId);
+            if (filterFuture != null) {
+                filterFuture.complete(ObjectiveError.BADPARAMS);
+            }
+            return;
+        }
+
+        if (install) {
+            boolean added = pendingAddEapol.add(portNumber);
+            if (!added) {
+                if (filterFuture != null) {
+                    log.warn("The eapol flow is processing for the port {}. Ignoring this request", portNumber);
+                    filterFuture.complete(null);
+                }
+                return;
+            }
+            log.info("portNumber added to pendingAddEapol map {}", portNumber);
+        }
+
+        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+        CompletableFuture<Object> meterFuture = new CompletableFuture<>();
+
+        // check if meter exists and create it only for an install
+        MeterId meterId = oltMeterService.getMeterIdFromBpMapping(devId, bpInfo.id());
+        if (meterId == null) {
+            if (install) {
+                meterId = oltMeterService.createMeter(devId, bpInfo, meterFuture);
+                treatmentBuilder.meter(meterId);
+            } 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 for {}/{}", bpInfo.id(), devId, portNumber);
+                meterFuture.complete(null);
+            }
+        } else {
+            log.debug("Meter {} was previously created for bp {}", meterId, bpInfo.id());
+            treatmentBuilder.meter(meterId);
+            meterFuture.complete(null);
+        }
+
+        final MeterId mId = meterId;
+        meterFuture.thenAcceptAsync(result -> {
+            if (result == null) {
+                log.info("Meter {} for {} on {}/{} exists. {} EAPOL trap flow",
+                        mId, bpId, devId, portNumber,
+                        (install) ? "Installing" : "Removing");
+                int techProfileId = getDefaultTechProfileId(devId, portNumber);
+
+                //Authentication trap flow uses only tech profile id as write metadata value
+                FilteringObjective eapol = (install ? builder.permit() : builder.deny())
+                        .withKey(Criteria.matchInPort(portNumber))
+                        .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
+                        .addCondition(Criteria.matchVlanId(vlanId))
+                        .withMeta(treatmentBuilder
+                                .writeMetadata(createTechProfValueForWm(vlanId, techProfileId), 0)
+                                .setOutput(PortNumber.CONTROLLER).build())
+                        .fromApp(appId)
+                        .withPriority(MAX_PRIORITY)
+                        .add(new ObjectiveContext() {
+                            @Override
+                            public void onSuccess(Objective objective) {
+                                log.info("Eapol filter for {} on {} {} with meter {}.",
+                                        devId, portNumber, (install) ? INSTALLED : REMOVED, mId);
+                                if (filterFuture != null) {
+                                    filterFuture.complete(null);
+                                }
+                                pendingAddEapol.remove(portNumber);
+                            }
+
+                            @Override
+                            public void onError(Objective objective, ObjectiveError error) {
+                                log.info("Eapol filter for {} on {} with meter {} failed {} because {}",
+                                        devId, portNumber, mId, (install) ? INSTALLATION : REMOVAL,
+                                        error);
+                                if (filterFuture != null) {
+                                    filterFuture.complete(error);
+                                }
+                                pendingAddEapol.remove(portNumber);
+                            }
+                        });
+
+                flowObjectiveService.filter(devId, eapol);
+            } else {
+                log.warn("Meter installation error while sending eapol trap flow. " +
+                        "Result {} and MeterId {}", result, mId);
+            }
+        });
+    }
+
+    /**
+     * Installs trap filtering objectives for particular traffic types on an
+     * NNI port.
+     *
+     * @param devId   device ID
+     * @param port    port number
+     * @param install true to install, false to remove
+     */
+    @Override
+    public void processNniFilteringObjectives(DeviceId devId, PortNumber port, boolean install) {
+        log.info("Sending flows for NNI port {} of the device {}", port, devId);
+        processLldpFilteringObjective(devId, port, install);
+        processDhcpFilteringObjectives(devId, port, null, null, install, false);
+        processIgmpFilteringObjectives(devId, port, null, null, install, false);
+    }
+
+
+    @Override
+    public void processLldpFilteringObjective(DeviceId devId, PortNumber port, boolean install) {
+        if (!mastershipService.isLocalMaster(devId)) {
+            return;
+        }
+        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
+
+        FilteringObjective lldp = (install ? builder.permit() : builder.deny())
+                .withKey(Criteria.matchInPort(port))
+                .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 device {} on port {} {}.",
+                                devId, port, (install) ? INSTALLED : REMOVED);
+                    }
+
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.info("LLDP filter for device {} on port {} failed {} because {}",
+                                devId, port, (install) ? INSTALLATION : REMOVAL,
+                                error);
+                    }
+                });
+
+        flowObjectiveService.filter(devId, lldp);
+    }
+
+    @Override
+    public ForwardingObjective.Builder createTransparentBuilder(PortNumber uplinkPort,
+                                                                PortNumber subscriberPort,
+                                                                MeterId meterId,
+                                                                UniTagInformation tagInfo,
+                                                                boolean upstream) {
+
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchVlanId(tagInfo.getPonSTag())
+                .matchInPort(upstream ? subscriberPort : uplinkPort)
+                .matchInnerVlanId(tagInfo.getPonCTag())
+                .build();
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        if (meterId != null) {
+            tBuilder.meter(meterId);
+        }
+
+        TrafficTreatment treatment = tBuilder
+                .setOutput(upstream ? uplinkPort : subscriberPort)
+                .writeMetadata(createMetadata(upstream ? tagInfo.getPonSTag() : tagInfo.getPonCTag(),
+                        tagInfo.getTechnologyProfileId(), upstream ? uplinkPort : subscriberPort), 0)
+                .build();
+
+        return createForwardingObjectiveBuilder(selector, treatment, MIN_PRIORITY);
+    }
+
+    @Override
+    public ForwardingObjective.Builder createUpBuilder(PortNumber uplinkPort,
+                                                       PortNumber subscriberPort,
+                                                       MeterId upstreamMeterId,
+                                                       UniTagInformation uniTagInformation) {
+
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(subscriberPort)
+                .matchVlanId(uniTagInformation.getUniTagMatch())
+                .build();
+
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder()
+                .pushVlan()
+                .setVlanId(uniTagInformation.getPonCTag());
+
+        if (uniTagInformation.getUsPonCTagPriority() != NO_PCP) {
+            treatmentBuilder.setVlanPcp((byte) uniTagInformation.getUsPonCTagPriority());
+        }
+
+        treatmentBuilder.pushVlan()
+                .setVlanId(uniTagInformation.getPonSTag());
+
+        if (uniTagInformation.getUsPonSTagPriority() != NO_PCP) {
+            treatmentBuilder.setVlanPcp((byte) uniTagInformation.getUsPonSTagPriority());
+        }
+
+        treatmentBuilder.setOutput(uplinkPort)
+                .writeMetadata(createMetadata(uniTagInformation.getPonCTag(),
+                        uniTagInformation.getTechnologyProfileId(), uplinkPort), 0L);
+
+        if (upstreamMeterId != null) {
+            treatmentBuilder.meter(upstreamMeterId);
+        }
+
+        return createForwardingObjectiveBuilder(selector, treatmentBuilder.build(), MIN_PRIORITY);
+    }
+
+    @Override
+    public ForwardingObjective.Builder createDownBuilder(PortNumber uplinkPort,
+                                                         PortNumber subscriberPort,
+                                                         MeterId downstreamMeterId,
+                                                         UniTagInformation tagInformation) {
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder()
+                .matchVlanId(tagInformation.getPonSTag())
+                .matchInPort(uplinkPort)
+                .matchInnerVlanId(tagInformation.getPonCTag())
+                .matchMetadata(tagInformation.getPonCTag().toShort());
+
+        if (tagInformation.getDsPonSTagPriority() != NO_PCP) {
+            selectorBuilder.matchVlanPcp((byte) tagInformation.getDsPonSTagPriority());
+        }
+
+        if (tagInformation.getConfiguredMacAddress() != null &&
+                !NO_MAC.equals(tagInformation.getConfiguredMacAddress())) {
+            selectorBuilder.matchEthDst(MacAddress.valueOf(tagInformation.getConfiguredMacAddress()));
+        }
+
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder()
+                .popVlan()
+                .setOutput(subscriberPort)
+                .writeMetadata(createMetadata(tagInformation.getPonCTag(), tagInformation.getTechnologyProfileId(),
+                        subscriberPort), 0);
+
+        // to remark inner vlan header
+        if (tagInformation.getUsPonCTagPriority() != NO_PCP) {
+            treatmentBuilder.setVlanPcp((byte) tagInformation.getUsPonCTagPriority());
+        }
+
+        if (!VlanId.NONE.equals(tagInformation.getUniTagMatch())) {
+            treatmentBuilder.setVlanId(tagInformation.getUniTagMatch());
+        }
+
+        if (downstreamMeterId != null) {
+            treatmentBuilder.meter(downstreamMeterId);
+        }
+
+        return createForwardingObjectiveBuilder(selectorBuilder.build(), treatmentBuilder.build(), MIN_PRIORITY);
+    }
+
+    private DefaultForwardingObjective.Builder createForwardingObjectiveBuilder(TrafficSelector selector,
+                                                                                TrafficTreatment treatment,
+                                                                                Integer priority) {
+        return DefaultForwardingObjective.builder()
+                .withFlag(ForwardingObjective.Flag.VERSATILE)
+                .withPriority(priority)
+                .makePermanent()
+                .withSelector(selector)
+                .fromApp(appId)
+                .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
+     * @return the write metadata value including tech profile reference and innerVlan
+     */
+    private Long createTechProfValueForWm(VlanId cVlan, int techProfileId) {
+        if (cVlan == null || VlanId.NONE.equals(cVlan)) {
+            return (long) techProfileId << 32;
+        }
+        return ((long) (cVlan.id()) << 48 | (long) techProfileId << 32);
+    }
+
+    private BandwidthProfileInformation getBandwidthProfileInformation(String bandwidthProfile) {
+        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 devId
+     * @param portNumber
+     * @return the default technology profile id
+     */
+    private int getDefaultTechProfileId(DeviceId devId, PortNumber portNumber) {
+        Port port = deviceService.getPort(devId, portNumber);
+        if (port != null) {
+            SubscriberAndDeviceInformation info = subsService.get(port.annotations().value(AnnotationKeys.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;
+        }
+
+        return ((long) (innerVlan.id()) << 48 | (long) techProfileId << 32) | egressPort.toLong();
+    }
+
+
+}
diff --git a/app/src/main/java/org/opencord/olt/impl/OltMeterService.java b/app/src/main/java/org/opencord/olt/impl/OltMeterService.java
new file mode 100644
index 0000000..df434eb
--- /dev/null
+++ b/app/src/main/java/org/opencord/olt/impl/OltMeterService.java
@@ -0,0 +1,306 @@
+/*
+ * 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 com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+import org.onosproject.net.meter.DefaultMeterRequest;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterContext;
+import org.onosproject.net.meter.MeterEvent;
+import org.onosproject.net.meter.MeterFailReason;
+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.net.meter.MeterService;
+import org.opencord.olt.internalapi.AccessDeviceMeterService;
+import org.opencord.sadis.BandwidthProfileInformation;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+
+import java.util.Dictionary;
+import java.util.Iterator;
+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 static org.onlab.util.Tools.groupedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+
+@Service
+@Component(immediate = true)
+public class OltMeterService implements AccessDeviceMeterService {
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MeterService meterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService componentConfigService;
+
+    @Property(name = "deleteMeters", boolValue = true,
+            label = "Deleting Meters based on flow count statistics")
+    protected boolean deleteMeters = true;
+
+    protected Map<String, Set<MeterKey>> bpInfoToMeter;
+    protected Set<MeterKey> programmedMeters;
+    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;
+
+    @Activate
+    public void activate(ComponentContext context) {
+        eventExecutor = Executors.newFixedThreadPool(5, groupedThreads("onos/olt",
+                "events-%d", log));
+        appId = coreService.registerApplication(APP_NAME);
+        bpInfoToMeter = Maps.newConcurrentMap();
+        programmedMeters = Sets.newConcurrentHashSet();
+        meterService.addListener(meterListener);
+        componentConfigService.registerProperties(getClass());
+        log.info("Olt Meter service started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        meterService.removeListener(meterListener);
+    }
+
+
+    @Modified
+    public void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
+
+        Boolean d = Tools.isPropertyEnabled(properties, "deleteMeters");
+        if (d != null) {
+            deleteMeters = d;
+        }
+    }
+
+    @Override
+    public ImmutableMap<String, Set<MeterKey>> getBpMeterMappings() {
+        return ImmutableMap.copyOf(bpInfoToMeter);
+    }
+
+    @Override
+    public void addMeterIdToBpMapping(DeviceId deviceId, MeterId meterId, String bandwidthProfile) {
+        bpInfoToMeter.compute(bandwidthProfile, (k, v) -> {
+            if (v == null) {
+                return Sets.newHashSet(MeterKey.key(deviceId, meterId));
+            } else {
+                v.add(MeterKey.key(deviceId, meterId));
+                return v;
+            }
+        });
+    }
+
+    @Override
+    public MeterId getMeterIdFromBpMapping(DeviceId deviceId, String bandwidthProfile) {
+        if (bpInfoToMeter.get(bandwidthProfile) == null) {
+            log.warn("Bandwidth Profile '{}' is not currently mapped to a meter",
+                    bandwidthProfile);
+            return null;
+        }
+
+        Optional<MeterKey> meterKeyForDevice = bpInfoToMeter.get(bandwidthProfile)
+                .stream()
+                .filter(meterKey -> meterKey.deviceId().equals(deviceId))
+                .findFirst();
+        if (meterKeyForDevice.isPresent()) {
+            log.debug("Found meter {} for bandwidth profile {}",
+                    meterKeyForDevice.get().meterId(), bandwidthProfile);
+            return meterKeyForDevice.get().meterId();
+        } else {
+            log.warn("Bandwidth profile '{}' is not currently mapped to a meter",
+                    bandwidthProfile);
+            return null;
+        }
+    }
+
+    @Override
+    public ImmutableSet<MeterKey> getProgMeters() {
+        return ImmutableSet.copyOf(programmedMeters);
+    }
+
+    @Override
+    public MeterId createMeter(DeviceId deviceId, BandwidthProfileInformation bpInfo,
+                               CompletableFuture<Object> meterFuture) {
+        if (bpInfo == null) {
+            log.warn("Requested bandwidth profile information is NULL");
+            meterFuture.complete(ObjectiveError.BADPARAMS);
+            return null;
+        }
+
+        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;
+        }
+
+        List<Band> meterBands = createMeterBands(bpInfo);
+
+        final AtomicReference<MeterId> meterIdRef = new AtomicReference<>();
+        MeterRequest meterRequest = DefaultMeterRequest.builder()
+                .withBands(meterBands)
+                .withUnit(Meter.Unit.KB_PER_SEC)
+                .withContext(new MeterContext() {
+                    @Override
+                    public void onSuccess(MeterRequest op) {
+                        meterFuture.complete(null);
+                    }
+
+                    @Override
+                    public void onError(MeterRequest op, MeterFailReason reason) {
+                        bpInfoToMeter.remove(MeterKey.key(deviceId, meterIdRef.get()));
+                        meterFuture.complete(reason);
+                    }
+                })
+                .forDevice(deviceId)
+                .fromApp(appId)
+                .burst()
+                .add();
+
+        Meter meter = meterService.submit(meterRequest);
+        meterIdRef.set(meter.id());
+        addMeterIdToBpMapping(deviceId, meterIdRef.get(), bpInfo.id());
+        programmedMeters.add(MeterKey.key(deviceId, meter.id()));
+        log.info("Meter is created. Meter Id {}", meter.id());
+        return meter.id();
+    }
+
+    private List<Band> createMeterBands(BandwidthProfileInformation bpInfo) {
+        List<Band> meterBands = new ArrayList<>();
+
+        meterBands.add(createMeterBand(bpInfo.committedInformationRate(), bpInfo.committedBurstSize()));
+        meterBands.add(createMeterBand(bpInfo.exceededInformationRate(), bpInfo.exceededBurstSize()));
+        meterBands.add(createMeterBand(bpInfo.assuredInformationRate(), 0L));
+
+        return meterBands;
+    }
+
+    private Band createMeterBand(long rate, Long burst) {
+        return DefaultBand.builder()
+                .withRate(rate) //already Kbps
+                .burstSize(burst) // already Kbits
+                .ofType(Band.Type.DROP) // no matter
+                .build();
+    }
+
+    private class InternalMeterListener implements MeterListener {
+
+        Map<MeterKey, AtomicInteger> pendingRemoveMeters = Maps.newConcurrentMap();
+
+        @Override
+        public void event(MeterEvent meterEvent) {
+            eventExecutor.execute(() -> {
+                Meter meter = meterEvent.subject();
+                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 {}", meter.id());
+                    incrementMeterCount(key);
+
+                    if (meter != null && appId.equals(meter.appId()) && pendingRemoveMeters.get(key).get() == 3) {
+                        log.info("Deleting unreferenced, no longer programmed Meter {}", meter.id());
+                        deleteMeter(meter.deviceId(), meter.id());
+                    }
+                }
+                if (MeterEvent.Type.METER_REMOVED.equals(meterEvent.type())) {
+                    log.info("Meter Removed Event is received for {}", meter.id());
+                    programmedMeters.remove(key);
+                    pendingRemoveMeters.remove(key);
+                    removeMeterFromBpMapping(meter);
+                }
+            });
+        }
+
+        private void incrementMeterCount(MeterKey key) {
+            if (key == null) {
+                return;
+            }
+            pendingRemoveMeters.compute(key,
+                    (k, v) -> {
+                        if (v == null) {
+                            return new AtomicInteger(1);
+                        }
+                        v.addAndGet(1);
+                        return v;
+                    });
+        }
+
+        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 removeMeterFromBpMapping(Meter meter) {
+            MeterKey meterKey = MeterKey.key(meter.deviceId(), meter.id());
+            Iterator<Map.Entry<String, Set<MeterKey>>> iterator = bpInfoToMeter.entrySet().iterator();
+            while (iterator.hasNext()) {
+                Map.Entry<String, Set<MeterKey>> entry = iterator.next();
+                if (entry.getValue().contains(meterKey)) {
+                    iterator.remove();
+                    log.info("Deleted meter for MeterKey {} - Last prog meters {}", meterKey, programmedMeters);
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/app/src/main/java/org/opencord/olt/internalapi/AccessDeviceFlowService.java b/app/src/main/java/org/opencord/olt/internalapi/AccessDeviceFlowService.java
new file mode 100644
index 0000000..362b154
--- /dev/null
+++ b/app/src/main/java/org/opencord/olt/internalapi/AccessDeviceFlowService.java
@@ -0,0 +1,148 @@
+/*
+ * 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.VlanId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.meter.MeterId;
+import org.opencord.sadis.UniTagInformation;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Olt service for flow operations.
+ */
+public interface AccessDeviceFlowService {
+
+    /**
+     * Provisions or removes trap-to-controller DHCP packets.
+     *
+     * @param devId           the target device identifier
+     * @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 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 processDhcpFilteringObjectives(DeviceId devId, PortNumber port,
+                                        MeterId upstreamMeterId,
+                                        UniTagInformation tagInformation,
+                                        boolean install,
+                                        boolean upstream);
+
+    /**
+     * Trap igmp packets to the controller.
+     *
+     * @param devId           Device identifier to send the flow
+     * @param port            Uni Port number
+     * @param upstreamMeterId upstream meter id 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(DeviceId devId, PortNumber port,
+                                        MeterId upstreamMeterId,
+                                        UniTagInformation tagInformation,
+                                        boolean install,
+                                        boolean upstream);
+
+    /**
+     * Trap eapol authentication packets to the controller.
+     *
+     * @param devId        the device identifier
+     * @param portNumber   the port for which this trap flow is designated
+     * @param bpId         bandwidth profile id 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(DeviceId devId, PortNumber portNumber, String bpId,
+                                         CompletableFuture<ObjectiveError> filterFuture,
+                                         VlanId vlanId, boolean install);
+
+    /**
+     * Trap lldp packets to the controller.
+     *
+     * @param devId   the device identifier
+     * @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(DeviceId devId, PortNumber port, boolean install);
+
+    /**
+     * Installs trap filtering objectives for particular traffic types (LLDP, IGMP and DHCP) on an
+     * NNI port.
+     *
+     * @param devId   device ID
+     * @param port    port number
+     * @param install true to install, false to remove
+     */
+    void processNniFilteringObjectives(DeviceId devId, PortNumber 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(PortNumber uplinkPort,
+                                                         PortNumber 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 uniTagInformation the uni tag information
+     * @return ForwardingObjective.Builder
+     */
+    ForwardingObjective.Builder createUpBuilder(PortNumber uplinkPort,
+                                                PortNumber subscriberPort,
+                                                MeterId upstreamMeterId,
+                                                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 tagInformation the uni tag information
+     * @return ForwardingObjective.Builder
+     */
+    ForwardingObjective.Builder createDownBuilder(PortNumber uplinkPort,
+                                                  PortNumber subscriberPort,
+                                                  MeterId downstreamMeterId,
+                                                  UniTagInformation tagInformation);
+}
diff --git a/app/src/main/java/org/opencord/olt/internalapi/AccessDeviceMeterService.java b/app/src/main/java/org/opencord/olt/internalapi/AccessDeviceMeterService.java
new file mode 100644
index 0000000..d2d51b2
--- /dev/null
+++ b/app/src/main/java/org/opencord/olt/internalapi/AccessDeviceMeterService.java
@@ -0,0 +1,81 @@
+/*
+ * 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.Set;
+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, Set<MeterKey>> getBpMeterMappings();
+
+    /**
+     * Adds a bandwidthProfile-meterKey (device / meter) mapping that have been programmed
+     * in the data plane.
+     *
+     * @param deviceId         the access device id
+     * @param meterId          the meter id that is mapped to the bandwidth profile
+     * @param bandwidthProfile the bandwidth profile id
+     */
+    void addMeterIdToBpMapping(DeviceId deviceId, MeterId meterId, String bandwidthProfile);
+
+    /**
+     * 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);
+
+
+}
diff --git a/app/src/main/java/org/opencord/olt/internalapi/package-info.java b/app/src/main/java/org/opencord/olt/internalapi/package-info.java
new file mode 100644
index 0000000..2b5d98d
--- /dev/null
+++ b/app/src/main/java/org/opencord/olt/internalapi/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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/app/src/main/java/org/opencord/olt/rest/OltWebResource.java b/app/src/main/java/org/opencord/olt/rest/OltWebResource.java
index 1631b09..54af4ac 100644
--- a/app/src/main/java/org/opencord/olt/rest/OltWebResource.java
+++ b/app/src/main/java/org/opencord/olt/rest/OltWebResource.java
@@ -24,6 +24,7 @@
 import org.opencord.olt.AccessSubscriberId;
 
 import java.util.Optional;
+import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
@@ -32,7 +33,7 @@
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
 
 /**
  * OLT REST APIs.
@@ -46,19 +47,23 @@
      *
      * @param device device id
      * @param port port number
-     * @return 200 OK
+     * @return 200 OK or 500 Internal Server Error
      */
     @POST
     @Produces(MediaType.APPLICATION_JSON)
     @Path("{device}/{port}")
     public Response provisionSubscriber(
-            @PathParam("device")String device,
-            @PathParam("port")long port) {
+            @PathParam("device") String device,
+            @PathParam("port") long port) {
         AccessDeviceService service = get(AccessDeviceService.class);
         DeviceId deviceId = DeviceId.deviceId(device);
         PortNumber portNumber = PortNumber.portNumber(port);
         ConnectPoint connectPoint = new ConnectPoint(deviceId, portNumber);
-        service.provisionSubscriber(connectPoint);
+        try {
+            service.provisionSubscriber(connectPoint);
+        } catch (Exception e) {
+            return Response.status(INTERNAL_SERVER_ERROR).build();
+        }
         return ok("").build();
     }
 
@@ -86,90 +91,102 @@
      * Provision service for a subscriber.
      *
      * @param portName Name of the port on which the subscriber is connected
-     * @return 200 OK or 404 NOT_FOUND
+     * @return 200 OK or 204 NO CONTENT
      */
     @POST
     @Produces(MediaType.APPLICATION_JSON)
     @Path("services/{portName}")
     public Response provisionServices(
-            @PathParam("portName")String portName) {
+            @PathParam("portName") String portName) {
         AccessDeviceService service = get(AccessDeviceService.class);
 
         Optional<VlanId> emptyVlan = Optional.empty();
-        if (service.provisionSubscriber(new AccessSubscriberId(portName), emptyVlan, emptyVlan)) {
+        Optional<Integer> emptyTpId = Optional.empty();
+        if (service.provisionSubscriber(new AccessSubscriberId(portName), emptyVlan, emptyVlan, emptyTpId)) {
             return ok("").build();
         }
-        return Response.status(NOT_FOUND).build();
+        return Response.noContent().build();
     }
 
     /**
      * Provision service with particular tags for a subscriber.
      *
      * @param portName Name of the port on which the subscriber is connected
-     * @param sTagVal additional outer tag on this port
-     * @param cTagVal additional innter tag on this port
-     * @return 200 OK or 404 NOT_FOUND
+     * @param sTagVal  additional outer tag on this port
+     * @param cTagVal  additional innter tag on this port
+     * @param tpIdVal  technology profile id
+     * @return 200 OK or 204 NO CONTENT
      */
     @POST
+    @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    @Path("services/{portName}/{sTag}/{cTag}")
+    @Path("services/{portName}/{sTag}/{cTag}/{tpId}")
     public Response provisionAdditionalVlans(
-            @PathParam("portName")String portName,
-            @PathParam("sTag")String sTagVal,
-            @PathParam("cTag")String cTagVal) {
+            @PathParam("portName") String portName,
+            @PathParam("sTag") String sTagVal,
+            @PathParam("cTag") String cTagVal,
+            @PathParam("tpId") String tpIdVal) {
         AccessDeviceService service = get(AccessDeviceService.class);
         VlanId cTag = VlanId.vlanId(cTagVal);
         VlanId sTag = VlanId.vlanId(sTagVal);
+        Integer tpId = Integer.valueOf(tpIdVal);
 
-        if (service.provisionSubscriber(new AccessSubscriberId(portName), Optional.of(sTag), Optional.of(cTag))) {
+        if (service.provisionSubscriber(new AccessSubscriberId(portName), Optional.of(sTag),
+                Optional.of(cTag), Optional.of(tpId))) {
             return ok("").build();
         }
-        return Response.status(NOT_FOUND).build();
+        return Response.noContent().build();
     }
 
     /**
      * Removes services for a subscriber.
      *
      * @param portName Name of the port on which the subscriber is connected
-     * @return 200 OK or 404 NOT_FOUND
+     * @return 200 OK or 204 NO CONTENT
      */
     @DELETE
     @Produces(MediaType.APPLICATION_JSON)
     @Path("services/{portName}")
     public Response deleteServices(
-            @PathParam("portName")String portName) {
+            @PathParam("portName") String portName) {
         AccessDeviceService service = get(AccessDeviceService.class);
 
         Optional<VlanId> emptyVlan = Optional.empty();
-        if (service.removeSubscriber(new AccessSubscriberId(portName), emptyVlan, emptyVlan)) {
+        Optional<Integer> emptyTpId = Optional.empty();
+        if (service.removeSubscriber(new AccessSubscriberId(portName), emptyVlan, emptyVlan, emptyTpId)) {
             return ok("").build();
         }
-        return Response.status(NOT_FOUND).build();
+        return Response.noContent().build();
     }
 
     /**
      * Removes additional vlans of a particular subscriber.
      *
      * @param portName Name of the port on which the subscriber is connected
-     * @param sTagVal additional outer tag on this port which needs to be removed
-     * @param cTagVal additional inner tag on this port which needs to be removed
-     * @return 200 OK or 404 NOT_FOUND
+     * @param sTagVal  additional outer tag on this port which needs to be removed
+     * @param cTagVal  additional inner tag on this port which needs to be removed
+     * @param tpIdVal  additional technology profile id
+     * @return 200 OK or 204 NO CONTENT
      */
     @DELETE
+    @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    @Path("services/{portName}/{sTag}/{cTag}")
+    @Path("services/{portName}/{sTag}/{cTag}/{tpId}")
     public Response removeAdditionalVlans(
-            @PathParam("portName")String portName,
-            @PathParam("sTag")String sTagVal,
-            @PathParam("cTag")String cTagVal) {
+            @PathParam("portName") String portName,
+            @PathParam("sTag") String sTagVal,
+            @PathParam("cTag") String cTagVal,
+            @PathParam("tpId") String tpIdVal) {
         AccessDeviceService service = get(AccessDeviceService.class);
         VlanId cTag = VlanId.vlanId(cTagVal);
         VlanId sTag = VlanId.vlanId(sTagVal);
+        Integer tpId = Integer.valueOf(tpIdVal);
 
-        if (service.removeSubscriber(new AccessSubscriberId(portName), Optional.of(sTag), Optional.of(cTag))) {
+        if (service.removeSubscriber(new AccessSubscriberId(portName), Optional.of(sTag),
+                Optional.of(cTag), Optional.of(tpId))) {
             return ok("").build();
         }
-        return Response.status(NOT_FOUND).build();
+        return Response.noContent().build();
     }
 
 }
diff --git a/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index f871bc9..a472391 100644
--- a/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -34,9 +34,6 @@
             <action class="org.opencord.olt.cli.ShowOltCommand"/>
         </command>
         <command>
-            <action class="org.opencord.olt.cli.ShowSubscribersCommand"/>
-        </command>
-        <command>
             <action class="org.opencord.olt.cli.ShowProgrammedSubscribersCommand"/>
         </command>
         <command>
@@ -45,6 +42,12 @@
         <command>
             <action class="org.opencord.olt.cli.ShowBpMeterMappingsCommand"/>
         </command>
+        <command>
+            <action class="org.opencord.olt.cli.UniTagAddCommand"/>
+        </command>
+        <command>
+            <action class="org.opencord.olt.cli.UniTagRemoveCommand"/>
+        </command>
     </command-bundle>
 
     <bean id="deviceIdCompleter" class="org.onosproject.cli.net.DeviceIdCompleter"/>
diff --git a/app/src/main/resources/vlan_cfg.json b/app/src/main/resources/vlan_cfg.json
index 133aed7..3bb577f 100644
--- a/app/src/main/resources/vlan_cfg.json
+++ b/app/src/main/resources/vlan_cfg.json
@@ -1,6 +1,6 @@
 {
-"apps" : {
-  "org.opencord.sadis" : {
+  "apps" : {
+    "org.opencord.sadis" : {
       "sadis" : {
         "integration" : {
           "cache" : {
@@ -11,12 +11,44 @@
         },
         "entries" : [ {
           "id" : "s1-eth1",
-          "cTag" : 2,
-          "sTag" : 4,
           "nasPortId" : "s1-eth1",
-          "technologyProfileId" : 10,
-          "upstreamBandwidthProfile" : "High-Speed-Internet",
-          "downstreamBandwidthProfile" : "User1-Specific"
+          "uniTagList": [
+            {
+              "uniTagMatch": 35,
+              "ponCTag":33,
+              "ponSTag":7,
+              "technologyProfileId": 2,
+              "upstreamBandwidthProfile":"High-Speed-Internet",
+              "downstreamBandwidthProfile":"Service1"
+            },
+            {
+              "uniTagMatch": 45,
+              "ponCTag":43,
+              "ponSTag":10,
+              "technologyProfileId": 3,
+              "upstreamBandwidthProfile":"VOIP",
+              "downstreamBandwidthProfile":"Service2",
+              "isDhcpRequired":"true"
+            },
+            {
+              "uniTagMatch": 55,
+              "ponCTag": 55,
+              "ponSTag": 550,
+              "technologyProfileId": 4,
+              "upstreamBandwidthProfile": "VOD",
+              "downstreamBandwidthProfile": "Service3",
+              "isDhcpRequired": "true",
+              "isIgmpRequired": "true"
+            },
+            {
+              "ponCTag": 55,
+              "ponSTag": 555,
+              "dsPonCTagPriority": 5,
+              "dsPonSTagPriority": 5,
+              "technologyProfileId": 4,
+              "serviceName": "MC"
+            }
+          ]
         }, {
           "id" : "1",
           "hardwareIdentifier" : "00:00:00:00:00:01",
@@ -24,39 +56,76 @@
           "uplinkPort": "2"
         } ]
       },
-         "bandwidthprofile":{
-            "integration":{
-               "cache":{
-                  "enabled":true,
-                  "maxsize":40,
-                  "ttl":"PT1m"
-               }
-            },
-            "entries":[
-               {
-                  "id":"High-Speed-Internet",
-                  "cir":200000000,
-                  "cbs":348000,
-                  "eir":10000000,
-                  "ebs":348000,
-                  "air":10000000
-               },
-               {
-                  "id":"User1-Specific",
-                  "cir":300000000,
-                  "cbs":348000,
-                  "eir":20000000,
-                  "ebs":348000
-               }
-            ]
-         }
+      "bandwidthprofile":{
+        "integration":{
+          "cache":{
+            "enabled":true,
+            "maxsize":40,
+            "ttl":"PT1m"
+          }
+        },
+        "entries":[
+          {
+            "id":"High-Speed-Internet",
+            "cir": 500000,
+            "cbs": 10000,
+            "eir": 500000,
+            "ebs": 10000,
+            "air": 100000
+          },
+          {
+            "id":"VOIP",
+            "cir": 500000,
+            "cbs": 10000,
+            "eir": 500000,
+            "ebs": 10000,
+            "air": 100000
+          },
+          {
+            "id":"Service1",
+            "cir": 600000,
+            "cbs": 10000,
+            "eir": 400000,
+            "ebs": 10000
+          },
+          {
+            "id":"Service2",
+            "cir": 600000,
+            "cbs": 10000,
+            "eir": 400000,
+            "ebs": 10000
+          },
+          {
+            "id":"VOD",
+            "cir": 600000,
+            "cbs": 10000,
+            "eir": 400000,
+            "ebs": 10000
+          },
+          {
+            "id":"Service3",
+            "cir": 600000,
+            "cbs": 10000,
+            "eir": 400000,
+            "ebs": 10000
+          },
+          {
+            "id":"Default",
+            "cir": 0,
+            "cbs": 0,
+            "eir": 512,
+            "ebs": 30,
+            "air": 0
+          }
+        ]
+      }
     }
   },
-   "devices":{
-      "of:0000000000000001":{
-         "basic":{
-            "driver":"pmc-olt"
-         }
+  "devices":{
+    "of:0000000000000001":{
+      "basic":{
+        "driver":"pmc-olt"
       }
-   }
+    }
+  }
 }
diff --git a/app/src/main/resources/vlan_cfg_with_default.json b/app/src/main/resources/vlan_cfg_with_default.json
index 7cd792a..e168283 100644
--- a/app/src/main/resources/vlan_cfg_with_default.json
+++ b/app/src/main/resources/vlan_cfg_with_default.json
@@ -11,12 +11,17 @@
         },
         "entries" : [ {
           "id" : "s1-eth1",
-          "cTag" : 2,
-          "sTag" : 4,
           "nasPortId" : "s1-eth1",
-          "technologyProfileId" : 10,
-          "upstreamBandwidthProfile" : "High-Speed-Internet",
-          "downstreamBandwidthProfile" : "User1-Specific"
+          "uniTagList": [
+            {
+              "uniTagMatch": 35,
+              "ponCTag":33,
+              "ponSTag":7,
+              "technologyProfileId": 2,
+              "upstreamBandwidthProfile":"High-Speed-Internet",
+              "downstreamBandwidthProfile":"Service1"
+            }
+          ]
         }, {
           "id" : "1",
           "hardwareIdentifier" : "00:00:00:00:00:01",
@@ -35,26 +40,55 @@
         "entries":[
           {
             "id":"High-Speed-Internet",
-            "cir":200000000,
-            "cbs":348000,
-            "eir":10000000,
-            "ebs":348000,
-            "air":10000000
+            "cir": 500000,
+            "cbs": 10000,
+            "eir": 500000,
+            "ebs": 10000,
+            "air": 100000
           },
           {
-            "id":"User1-Specific",
-            "cir":300000000,
-            "cbs":348000,
-            "eir":20000000,
-            "ebs":348000
+            "id":"VOIP",
+            "cir": 500000,
+            "cbs": 10000,
+            "eir": 500000,
+            "ebs": 10000,
+            "air": 100000
+          },
+          {
+            "id":"Service1",
+            "cir": 600000,
+            "cbs": 10000,
+            "eir": 400000,
+            "ebs": 10000
+          },
+          {
+            "id":"Service2",
+            "cir": 600000,
+            "cbs": 10000,
+            "eir": 400000,
+            "ebs": 10000
+          },
+          {
+            "id":"VOD",
+            "cir": 600000,
+            "cbs": 10000,
+            "eir": 400000,
+            "ebs": 10000
+          },
+          {
+            "id":"Service3",
+            "cir": 600000,
+            "cbs": 10000,
+            "eir": 400000,
+            "ebs": 10000
           },
           {
             "id":"Default",
-            "cir":0,
-            "cbs":0,
-            "eir":512,
-            "ebs":30,
-            "air":0
+            "cir": 0,
+            "cbs": 0,
+            "eir": 512,
+            "ebs": 30,
+            "air": 0
           }
         ]
       }
diff --git a/app/src/test/java/org/opencord/olt/impl/OltFlowTest.java b/app/src/test/java/org/opencord/olt/impl/OltFlowTest.java
new file mode 100644
index 0000000..8a80ee0
--- /dev/null
+++ b/app/src/test/java/org/opencord/olt/impl/OltFlowTest.java
@@ -0,0 +1,374 @@
+/*
+ * 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 com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ListMultimap;
+import org.apache.commons.lang3.tuple.Pair;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.EthType;
+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.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.sadis.BandwidthProfileInformation;
+import org.opencord.sadis.UniTagInformation;
+
+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;
+
+public class OltFlowTest extends TestBase {
+    private OltFlowService oltFlowService;
+
+    PortNumber uniPortNumber = PortNumber.portNumber(1);
+    PortNumber nniPortNumber = PortNumber.portNumber(65535);
+
+    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)
+            .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;
+    }
+
+    @Test
+    public void testDhcpFiltering() {
+        oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
+                true, true);
+        oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
+                false, true);
+        oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, dsMeterId, uniTagInfo,
+                true, false);
+        oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
+                false, false);
+    }
+
+    @Test
+    public void testIgmpFiltering() {
+        oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
+                true, true);
+        oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
+                false, true);
+    }
+
+    @Test
+    public void testEapolFiltering() {
+        addBandwidthProfile(uniTagInfo.getUpstreamBandwidthProfile());
+        oltFlowService.enableEapol = true;
+
+        //will install
+        oltFlowService.processEapolFilteringObjectives(DEVICE_ID_1, uniPortNumber,
+                uniTagInfo.getUpstreamBandwidthProfile(), new CompletableFuture<>(),
+                uniTagInfo.getUniTagMatch(), true);
+
+        //bp profile doesn't exist
+        oltFlowService.processEapolFilteringObjectives(DEVICE_ID_1, uniPortNumber,
+                uniTagInfo.getDownstreamBandwidthProfile(), new CompletableFuture<>(),
+                uniTagInfo.getUniTagMatch(), true);
+    }
+
+    @Test
+    public void testLldpFiltering() {
+        oltFlowService.processLldpFilteringObjective(DEVICE_ID_1, nniPortNumber, true);
+        oltFlowService.processLldpFilteringObjective(DEVICE_ID_1, nniPortNumber, false);
+    }
+
+    @Test
+    public void testNniFiltering() {
+        oltFlowService.enableDhcpOnProvisioning = true;
+        oltFlowService.enableIgmpOnProvisioning = true;
+        oltFlowService.processNniFilteringObjectives(DEVICE_ID_1, nniPortNumber, true);
+        oltFlowService.processNniFilteringObjectives(DEVICE_ID_1, nniPortNumber, false);
+    }
+
+    @Test
+    public void testUpBuilder() {
+        ForwardingObjective objective =
+                oltFlowService.createUpBuilder(nniPortNumber, uniPortNumber, usMeterId, uniTagInfo).add();
+        checkObjective(objective, true);
+    }
+
+    @Test
+    public void testDownBuilder() {
+        ForwardingObjective objective =
+                oltFlowService.createDownBuilder(nniPortNumber, uniPortNumber, dsMeterId, uniTagInfo).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;
+        }
+    }
+
+    private class MockOltMeterService implements org.opencord.olt.internalapi.AccessDeviceMeterService {
+        @Override
+        public ImmutableMap<String, Set<MeterKey>> getBpMeterMappings() {
+            return null;
+        }
+
+        @Override
+        public void addMeterIdToBpMapping(DeviceId deviceId, MeterId meterId, String bandwidthProfile) {
+
+        }
+
+        @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;
+        }
+    }
+
+    private class MockOltFlowObjectiveService implements org.onosproject.net.flowobjective.FlowObjectiveService {
+        @Override
+        public void filter(DeviceId deviceId, FilteringObjective filteringObjective) {
+
+            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();
+
+
+            if (ethType.ethType().equals(EthType.EtherType.LLDP.ethType()) ||
+                    portCriterion.port().equals(nniPortNumber)) {
+                assert meter == null;
+                assert writeMetadata == null;
+                assert vlanIdCriterion == null;
+            } else {
+                assert meter.meterId().equals(usMeterId) || meter.meterId().equals(dsMeterId);
+                assert writeMetadata != null;
+                assert vlanIdCriterion.vlanId() == uniTagInfo.getPonCTag();
+            }
+
+        }
+
+        @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 null;
+        }
+
+        @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() {
+
+        }
+
+        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/app/src/test/java/org/opencord/olt/impl/OltMeterTest.java b/app/src/test/java/org/opencord/olt/impl/OltMeterTest.java
new file mode 100644
index 0000000..7100b0f
--- /dev/null
+++ b/app/src/test/java/org/opencord/olt/impl/OltMeterTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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 com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+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.opencord.sadis.BandwidthProfileInformation;
+
+import java.util.Collection;
+import java.util.Set;
+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.bpInfoToMeter = Maps.newConcurrentMap();
+        oltMeterService.programmedMeters = Sets.newConcurrentHashSet();
+        oltMeterService.meterService = new MockMeterService();
+    }
+
+    @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, Set<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/app/src/test/java/org/opencord/olt/impl/OltTest.java b/app/src/test/java/org/opencord/olt/impl/OltTest.java
index a925aa3..c417590 100644
--- a/app/src/test/java/org/opencord/olt/impl/OltTest.java
+++ b/app/src/test/java/org/opencord/olt/impl/OltTest.java
@@ -18,14 +18,10 @@
 import static org.junit.Assert.assertEquals;
 
 import java.util.Set;
-
 import org.junit.Before;
 import org.junit.Test;
 
 import org.onlab.packet.ChassisId;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
 import org.onosproject.net.AnnotationKeys;
 import org.onosproject.net.Annotations;
 import org.onosproject.net.ConnectPoint;
@@ -38,24 +34,15 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceServiceAdapter;
 import org.onosproject.net.provider.ProviderId;
-import org.opencord.sadis.BandwidthProfileInformation;
-import org.opencord.sadis.BaseInformationService;
 import org.opencord.sadis.SubscriberAndDeviceInformation;
-import org.opencord.sadis.SadisService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class OltTest {
+public class OltTest extends TestBase {
     private final Logger log = LoggerFactory.getLogger(getClass());
     private Olt olt;
 
-    private static final VlanId CLIENT_C_TAG = VlanId.vlanId((short) 999);
-    private static final VlanId CLIENT_S_TAG = VlanId.vlanId((short) 111);
-    private static final String CLIENT_NAS_PORT_ID = "PON 1/1";
-    private static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
 
-    private static final String OLT_DEV_ID = "of:00000000000000aa";
-    private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId(OLT_DEV_ID);
     private static final String SCHEME_NAME = "olt";
     private static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
             .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
@@ -66,7 +53,6 @@
         olt.deviceService = new MockDeviceService();
         olt.sadisService = new MockSadisService();
         olt.subsService = olt.sadisService.getSubscriberInfoService();
-
     }
 
     /**
@@ -92,8 +78,6 @@
         SubscriberAndDeviceInformation s =  olt.getSubscriber(cp);
 
         assertEquals(s.circuitId(), CLIENT_CIRCUIT_ID);
-        assertEquals(s.cTag(), CLIENT_C_TAG);
-        assertEquals(s.sTag(), CLIENT_S_TAG);
         assertEquals(s.nasPortId(), CLIENT_NAS_PORT_ID);
     }
 
@@ -103,7 +87,7 @@
                           String manufacturer, String hwVersion, String swVersion,
                           String serialNumber, ChassisId chassisId, Annotations... annotations) {
             super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber,
-                  chassisId, annotations);
+                    chassisId, annotations);
         }
     }
 
@@ -111,8 +95,8 @@
 
         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);
+                "foo.inc", "0", "0", OLT_DEV_ID, new ChassisId(),
+                DEVICE_ANNOTATIONS);
 
         @Override
         public Device getDevice(DeviceId devId) {
@@ -170,53 +154,8 @@
         }
     }
 
-    private class MockSadisService implements SadisService {
 
 
-        @Override
-        public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
-            return new MockSubService();
-        }
 
-        @Override
-        public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
-            return null;
-        }
-    }
-
-    private class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
-        MockSubscriberAndDeviceInformation sub =
-                new MockSubscriberAndDeviceInformation(CLIENT_NAS_PORT_ID, CLIENT_C_TAG,
-                                                       CLIENT_S_TAG, CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null);
-        @Override
-        public SubscriberAndDeviceInformation get(String id) {
-            return  sub;
-        }
-
-        @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, VlanId ctag,
-                                           VlanId stag, String nasPortId,
-                                           String circuitId, MacAddress hardId,
-                                           Ip4Address ipAddress) {
-            this.setCTag(ctag);
-            this.setHardwareIdentifier(hardId);
-            this.setId(id);
-            this.setIPAddress(ipAddress);
-            this.setSTag(stag);
-            this.setNasPortId(nasPortId);
-            this.setCircuitId(circuitId);
-        }
-    }
 
 }
\ No newline at end of file
diff --git a/app/src/test/java/org/opencord/olt/impl/TestBase.java b/app/src/test/java/org/opencord/olt/impl/TestBase.java
new file mode 100644
index 0000000..b8447a9
--- /dev/null
+++ b/app/src/test/java/org/opencord/olt/impl/TestBase.java
@@ -0,0 +1,127 @@
+/*
+ * 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.Maps;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.MeterId;
+import org.opencord.sadis.BandwidthProfileInformation;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+
+import java.util.Map;
+
+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 String usBpId = "HSIA-US";
+    protected String dsBpId = "HSIA-DS";
+    protected DefaultApplicationId appId = new DefaultApplicationId(1, "OltServices");
+
+    Map<String, BandwidthProfileInformation> bpInformation = Maps.newConcurrentMap();
+
+    protected void addBandwidthProfile(String id) {
+        BandwidthProfileInformation bpInfo = new BandwidthProfileInformation();
+        bpInfo.setAssuredInformationRate(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 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 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);
+        }
+    }
+}
