diff --git a/pom.xml b/pom.xml
index e864aa0..fd7bcef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -54,6 +54,7 @@
             <artifactId>onos-api</artifactId>
             <version>${onos.version}</version>
             <scope>provided</scope>
+            <classifier>tests</classifier>
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
@@ -73,6 +74,12 @@
             <version>${onos.version}</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <version>${onos.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/src/main/java/org/opencord/cordmcast/CordMcast.java b/src/main/java/org/opencord/cordmcast/CordMcast.java
index ad3f2a7..bd10980 100644
--- a/src/main/java/org/opencord/cordmcast/CordMcast.java
+++ b/src/main/java/org/opencord/cordmcast/CordMcast.java
@@ -244,21 +244,24 @@
                 }
                 NextContent next = groups.get(groupInfo).value();
 
-                ObjectiveContext context = new DefaultObjectiveContext(
-                        (objective) -> log.debug("Successfully remove {}",
-                                                 groupInfo.group),
-                        (objective, error) -> log.warn("Failed to remove {}: {}",
-                                                       groupInfo.group, error));
-                // remove the flow rule
-                flowObjectiveService.forward(groupInfo.getDevice(), fwdObject(next.getNextId(),
-                                                                              groupInfo.group).remove(context));
-                // remove all ports from the group
-                next.getOutPorts().stream().forEach(portNumber ->
-                    flowObjectiveService.next(groupInfo.getDevice(), nextObject(next.getNextId(),
-                                                                                portNumber, NextType.RemoveFromExisting,
-                                                                                groupInfo.group))
-                );
+                if (next != null) {
+                    ObjectiveContext context = new DefaultObjectiveContext(
+                            (objective) -> log.debug("Successfully remove {}",
+                                                     groupInfo.group),
+                            (objective, error) -> log.warn("Failed to remove {}: {}",
+                                                           groupInfo.group, error));
+                    // remove the flow rule
+                    flowObjectiveService.forward(groupInfo.getDevice(), fwdObject(next.getNextId(),
+                                                                                  groupInfo.group).remove(context));
+                    // remove all ports from the group
+                    next.getOutPorts().stream().forEach(portNumber ->
+                        flowObjectiveService.next(groupInfo.getDevice(), nextObject(next.getNextId(),
+                                                                                    portNumber,
+                                                                                    NextType.RemoveFromExisting,
+                                                                                    groupInfo.group))
+                    );
 
+                }
             });
             groups.clear();
         } finally {
diff --git a/src/test/java/org/opencord/cordmcast/McastTest.java b/src/test/java/org/opencord/cordmcast/McastTest.java
new file mode 100644
index 0000000..ea4d33b
--- /dev/null
+++ b/src/test/java/org/opencord/cordmcast/McastTest.java
@@ -0,0 +1,328 @@
+/*
+ * 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.cordmcast;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.mcast.api.McastEvent;
+import org.onosproject.mcast.api.McastRouteUpdate;
+import org.onosproject.mcast.api.MulticastRouteService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.store.service.StorageServiceAdapter;
+import org.onosproject.store.service.TestConsistentMap;
+import org.osgi.service.component.ComponentContext;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+import static org.onlab.junit.TestTools.assertAfter;
+
+public class McastTest extends McastTestBase {
+
+  private CordMcast cordMcast;
+
+  private static final int WAIT_TIMEOUT = 1000;
+  private static final int WAIT = 250;
+  McastRouteUpdate previousSubject, currentSubject;
+
+  @Before
+  public void setUp() {
+      cordMcast = new CordMcast();
+
+      cordMcast.coreService = new MockCoreService();
+      cordMcast.flowObjectiveService = new MockFlowObjectiveService();
+      cordMcast.mastershipService = new TestMastershipService();
+      cordMcast.deviceService = new DeviceServiceAdapter();
+      cordMcast.networkConfig = new NetworkConfigRegistryAdapter();
+      cordMcast.cordConfigService = new MockCordConfigService();
+
+      cordMcast.storageService =
+             EasyMock.createMock(StorageServiceAdapter.class);
+      expect(cordMcast.storageService.consistentMapBuilder()).andReturn(new TestConsistentMap.Builder<>());
+      replay(cordMcast.storageService);
+
+      Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
+      cfgDict.put("vlanEnabled", false);
+      cordMcast.componentConfigService =
+             EasyMock.createNiceMock(ComponentConfigService.class);
+      replay(cordMcast.componentConfigService);
+
+      cordMcast.mcastService = EasyMock.createNiceMock(MulticastRouteService.class);
+      expect(cordMcast.mcastService.getRoutes()).andReturn(Sets.newHashSet());
+      replay(cordMcast.mcastService);
+
+      ComponentContext componentContext = EasyMock.createMock(ComponentContext.class);
+      expect(componentContext.getProperties()).andReturn(cfgDict);
+      replay(componentContext);
+
+      cordMcast.activate(componentContext);
+
+   }
+
+    @After
+    public void tearDown() {
+      cordMcast.deactivate();
+      forwardMap.clear();
+      nextMap.clear();
+    }
+
+    @Test
+    public void testAddingSinkEvent() throws InterruptedException {
+
+      Set<ConnectPoint> sinks2Cp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_B));
+      Map<HostId, Set<ConnectPoint>> sinks2 = ImmutableMap.of(HOST_ID_NONE, sinks2Cp);
+
+      //Adding the details to create different routes
+      previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+      currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks2);
+      // Creating new mcast event for adding sink
+      McastEvent event = new McastEvent(McastEvent.Type.SINKS_ADDED, previousSubject, currentSubject);
+      cordMcast.listener.event(event);
+      synchronized (forwardMap) {
+        forwardMap.wait(WAIT_TIMEOUT);
+      }
+
+      // ForwardMap will contain the operation "Add" in the flowObjective. None -> CP_B
+      assertNotNull(forwardMap.get(DEVICE_ID_OF_A));
+      assertTrue(forwardMap.get(DEVICE_ID_OF_A).op() == Objective.Operation.ADD);
+
+      // Output port number will be PORT_B i.e. 16
+      Collection<TrafficTreatment> traffictreatMentCollection =
+           nextMap.get(DEVICE_ID_OF_A).next();
+      assertTrue(1 == traffictreatMentCollection.size());
+      OutputInstruction output = null;
+      for (TrafficTreatment trafficTreatment : traffictreatMentCollection) {
+         output = outputPort(trafficTreatment);
+      }
+      assertNotNull(output);
+      assertTrue(PORT_B == output.port());
+      // Checking the group ip address
+      TrafficSelector trafficSelector = forwardMap.get(DEVICE_ID_OF_A).selector();
+      IPCriterion ipCriterion = ipAddress(trafficSelector);
+      assertNotNull(ipCriterion);
+      assertTrue(MULTICAST_IP.equals(ipCriterion.ip().address()));
+
+    }
+
+    @Test
+    public void testAddToExistingSinkEvent() throws InterruptedException {
+
+       // Adding first sink (none --> CP_B)
+       testAddingSinkEvent();
+
+       Set<ConnectPoint> sinksCp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_B));
+       Map<HostId, Set<ConnectPoint>> sinks = ImmutableMap.of(HOST_ID_NONE, sinksCp);
+       previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+       sinksCp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_B, CONNECT_POINT_C));
+       sinks = ImmutableMap.of(HOST_ID_NONE, sinksCp);
+       currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+       // Again listening the mcast event with different output port ( none --> CP_B, CP_C)
+       McastEvent event = new McastEvent(McastEvent.Type.SINKS_ADDED, previousSubject, currentSubject);
+       cordMcast.listener.event(event);
+
+       // NextMap will contain the operation "ADD_TO_EXISTING" in the DefaultNextObjective.
+       assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
+       assertTrue(nextMap.get(DEVICE_ID_OF_A).op() == Objective.Operation.ADD_TO_EXISTING));
+       // Output port number will be changed to 24 i.e. PORT_C
+       Collection<TrafficTreatment> traffictreatMentCollection = nextMap.get(DEVICE_ID_OF_A).next();
+       assertTrue(1 == traffictreatMentCollection.size());
+       OutputInstruction output = null;
+       for (TrafficTreatment trafficTreatment : traffictreatMentCollection) {
+          output = outputPort(trafficTreatment);
+       }
+       assertNotNull(output);
+       assertTrue(PORT_C == output.port());
+    }
+
+    @Test
+    public void testRemoveSinkEvent() throws InterruptedException {
+
+       testAddToExistingSinkEvent();
+       // Handling the mcast event for removing sink.
+       Set<ConnectPoint> sinksCp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_B, CONNECT_POINT_C));
+       Map<HostId, Set<ConnectPoint>> sinks = ImmutableMap.of(HOST_ID_NONE, sinksCp);
+       previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+       sinksCp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_C));
+       sinks = ImmutableMap.of(HOST_ID_NONE, sinksCp);
+       currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+       McastEvent event = new McastEvent(McastEvent.Type.SINKS_REMOVED, previousSubject, currentSubject);
+       cordMcast.listener.event(event);
+       // Operation will be REMOVE_FROM_EXISTING and nextMap will be updated. ( None --> CP_C)
+       assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
+       assertTrue(nextMap.get(DEVICE_ID_OF_A).op() == Objective.Operation.REMOVE_FROM_EXISTING));
+
+       // Output port number will be PORT_B i.e. 16
+       // Port_B is removed from the group.
+       Collection<TrafficTreatment> traffictreatMentCollection =
+            nextMap.get(DEVICE_ID_OF_A).next();
+       assertTrue(1 == traffictreatMentCollection.size());
+       OutputInstruction output = null;
+       for (TrafficTreatment trafficTreatment : traffictreatMentCollection) {
+          output = outputPort(trafficTreatment);
+       }
+       assertNotNull(output);
+       assertTrue(PORT_B == output.port());
+
+    }
+
+    @Test
+    public void testRemoveLastSinkEvent() throws InterruptedException {
+
+       testRemoveSinkEvent();
+       // Handling the mcast event for removing sink.
+       Set<ConnectPoint> sinksCp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_C));
+       Map<HostId, Set<ConnectPoint>> sinks = ImmutableMap.of(HOST_ID_NONE, sinksCp);
+       previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+       sinksCp = new HashSet<ConnectPoint>(Arrays.asList());
+       sinks = ImmutableMap.of(HOST_ID_NONE, sinksCp);
+       currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+       McastEvent event = new McastEvent(McastEvent.Type.SINKS_REMOVED, previousSubject, currentSubject);
+       cordMcast.listener.event(event);
+
+       // Operation will be REMOVE_FROM_EXISTING and nextMap will be updated.  None --> { }
+       assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
+       assertTrue(nextMap.get(DEVICE_ID_OF_A).op() == Objective.Operation.REMOVE_FROM_EXISTING));
+
+       // Output port number will be changed to 24 i.e. PORT_C
+       Collection<TrafficTreatment> traffictreatMentCollection = nextMap.get(DEVICE_ID_OF_A).next();
+       assertTrue(1 == traffictreatMentCollection.size());
+       OutputInstruction output = null;
+       for (TrafficTreatment trafficTreatment : traffictreatMentCollection) {
+          output = outputPort(trafficTreatment);
+       }
+       assertNotNull(output);
+       assertTrue(PORT_C == output.port());
+  }
+
+  @Test
+  public void testUnkownOltDevice() throws InterruptedException {
+
+       // Configuration of mcast event for unknown olt device
+       final DeviceId deviceIdOfB = DeviceId.deviceId("of:1");
+
+       ConnectPoint connectPointA = new ConnectPoint(deviceIdOfB, PORT_A);
+       ConnectPoint connectPointB = new ConnectPoint(deviceIdOfB, PORT_B);
+       Set<ConnectPoint> sourcesCp = new HashSet<ConnectPoint>(Arrays.asList(connectPointA));
+       Set<ConnectPoint> sinksCp = new HashSet<ConnectPoint>(Arrays.asList());
+       Set<ConnectPoint> sinks2Cp = new HashSet<ConnectPoint>(Arrays.asList(connectPointB));
+       Map<HostId, Set<ConnectPoint>> sources = ImmutableMap.of(HOST_ID_NONE, sourcesCp);
+
+       Map<HostId, Set<ConnectPoint>> sinks = ImmutableMap.of(HOST_ID_NONE, sinksCp);
+       Map<HostId, Set<ConnectPoint>> sinks2 = ImmutableMap.of(HOST_ID_NONE, sinks2Cp);
+       //Adding the details to create different routes
+       McastRouteUpdate previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+       McastRouteUpdate currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks2);
+       // Creating new mcast event for adding sink
+       McastEvent event = new McastEvent(McastEvent.Type.SINKS_ADDED, previousSubject, currentSubject);
+       cordMcast.listener.event(event);
+       // OltInfo flag is set to true when olt device is unkown
+       assertAfter(WAIT, WAIT * 2, () -> assertTrue(knownOltFlag));
+       assertTrue(0 == forwardMap.size());
+       assertTrue(0 == nextMap.size());
+
+  }
+
+  @Test
+  public void testRouteAddedEvent() throws InterruptedException {
+
+      //Adding the details to create different routes
+      previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, emptySource, sinks);
+      currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, emptySource, sinks);
+      // Creating new mcast event for route adding
+      McastEvent event = new McastEvent(McastEvent.Type.ROUTE_ADDED, previousSubject, currentSubject);
+      cordMcast.listener.event(event);
+      // There will be no forwarding objective
+      assertAfter(WAIT, WAIT * 2, () -> assertTrue(0 == forwardMap.size()));
+      assertTrue(0 == nextMap.size());
+
+   }
+
+
+  @Test
+  public void testRouteRemovedEvent() throws InterruptedException {
+
+      testRouteAddedEvent();
+
+      //Adding the details to create different routes
+      previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, emptySource, sinks);
+      currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, emptySource, sinks);
+      // Creating new mcast event for route removing
+      McastEvent event = new McastEvent(McastEvent.Type.ROUTE_REMOVED, previousSubject, currentSubject);
+      cordMcast.listener.event(event);
+      // There will be no forwarding objective
+      assertAfter(WAIT, WAIT * 2, () -> assertTrue(0 == forwardMap.size()));
+      assertTrue(0 == nextMap.size());
+
+   }
+
+
+  @Test
+  public void testSourceAddedEvent() throws InterruptedException {
+
+      // Adding route before adding source.
+      testRouteAddedEvent();
+
+      //Adding the details to create different routes
+      previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, emptySource, sinks);
+      currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+      // Creating new mcast event for source adding
+      McastEvent event = new McastEvent(McastEvent.Type.SOURCES_ADDED, previousSubject, currentSubject);
+      cordMcast.listener.event(event);
+      // There will be no forwarding objective
+      assertAfter(WAIT, WAIT * 2, () -> assertTrue(0 == forwardMap.size()));
+      assertTrue(0 == nextMap.size());
+
+   }
+
+  @Test
+  public void testSourcesRemovedEvent() throws InterruptedException {
+
+      testSourceAddedEvent();
+
+      //Adding the details to create different routes
+      previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+      currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, emptySource, sinks);
+      // Creating new mcast event for removing source
+      // Warning message of unknown event will be displayed.
+      McastEvent event = new McastEvent(McastEvent.Type.SOURCES_REMOVED, previousSubject, currentSubject);
+      cordMcast.listener.event(event);
+      assertAfter(WAIT, WAIT * 2, () -> assertTrue(0 == forwardMap.size()));
+      assertTrue(0 == nextMap.size());
+   }
+
+}
diff --git a/src/test/java/org/opencord/cordmcast/McastTestBase.java b/src/test/java/org/opencord/cordmcast/McastTestBase.java
new file mode 100644
index 0000000..273c862
--- /dev/null
+++ b/src/test/java/org/opencord/cordmcast/McastTestBase.java
@@ -0,0 +1,208 @@
+/*
+ * 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.cordmcast;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.mcast.api.McastRoute;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+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.IPCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
+import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.opencord.cordconfig.CordConfigListener;
+import org.opencord.cordconfig.CordConfigService;
+import org.opencord.cordconfig.access.AccessAgentData;
+import org.opencord.cordconfig.access.AccessDeviceData;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableMap;
+
+public class McastTestBase {
+
+     // Map to store the forwardingObjective in flowObjectiveService.forward()
+     Map<DeviceId, ForwardingObjective> forwardMap = new HashMap<>();
+     // Map to store the nextObjective in flowObjectiveService.next()
+     Map<DeviceId, NextObjective> nextMap = new HashMap<>();
+     // Device configuration
+     protected static final DeviceId DEVICE_ID_OF_A = DeviceId.deviceId("of:00000a0a0a0a0a00");
+     // Port number
+     protected static final PortNumber PORT_A = PortNumber.portNumber(1048576);
+     protected static final PortNumber PORT_B = PortNumber.portNumber(16);
+     protected static final PortNumber PORT_C = PortNumber.portNumber(24);
+
+     // Connect Point for creating source and sink
+     protected static final ConnectPoint CONNECT_POINT_A = new ConnectPoint(DEVICE_ID_OF_A, PORT_A);
+     protected static final ConnectPoint CONNECT_POINT_B = new ConnectPoint(DEVICE_ID_OF_A, PORT_B);
+     protected static final ConnectPoint CONNECT_POINT_C = new ConnectPoint(DEVICE_ID_OF_A, PORT_C);
+
+     //Host id configuration
+     protected static final HostId HOST_ID_NONE = HostId.NONE;
+     // Source connect point
+     protected static final  Set<ConnectPoint> SOURCES_CP = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_A));
+     Map<HostId, Set<ConnectPoint>> sources = ImmutableMap.of(HOST_ID_NONE, SOURCES_CP);
+
+     protected static final IpAddress MULTICAST_IP = IpAddress.valueOf("224.0.0.22");
+     // Creating dummy route with IGMP type.
+     McastRoute route1 = new McastRoute(null, MULTICAST_IP, McastRoute.Type.IGMP);
+
+     // Creating empty sink used in prevRoute
+     Set<ConnectPoint> sinksCp = new HashSet<ConnectPoint>(Arrays.asList());
+     Map<HostId, Set<ConnectPoint>> sinks = ImmutableMap.of(HOST_ID_NONE, sinksCp);
+
+     // Creating empty source
+     Set<ConnectPoint> sourceCp = new HashSet<ConnectPoint>(Arrays.asList());
+     Map<HostId, Set<ConnectPoint>> emptySource = ImmutableMap.of(HOST_ID_NONE, sourceCp);
+
+     // Flag to check unknown olt device
+     boolean knownOltFlag = false;
+
+     class MockCoreService extends CoreServiceAdapter {
+          @Override
+          public ApplicationId registerApplication(String name) {
+               ApplicationId testApplicationId = TestApplicationId.create("org.opencord.cordmcast");
+               return testApplicationId;
+          }
+     }
+
+     class MockFlowObjectiveService extends FlowObjectiveServiceAdapter {
+          @Override
+          public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
+              synchronized (forwardMap) {
+                forwardMap.put(deviceId, forwardingObjective);
+                forwardMap.notify();
+              }
+          }
+
+          @Override
+          public void next(DeviceId deviceId, NextObjective nextObjective) {
+             nextMap.put(deviceId, nextObjective);
+          }
+     }
+
+     class TestMastershipService extends MastershipServiceAdapter {
+          @Override
+          public boolean isLocalMaster(DeviceId deviceId) {
+               return true;
+          }
+     }
+
+     class MockCordConfigService implements CordConfigService {
+
+          @Override
+          public void addListener(CordConfigListener listener) {
+
+          }
+
+          @Override
+          public void removeListener(CordConfigListener listener) {
+
+          }
+
+          @Override
+          public Set<AccessDeviceData> getAccessDevices() {
+
+               return null;
+          }
+
+          @Override
+          public Optional<AccessDeviceData> getAccessDevice(DeviceId deviceId) {
+             if (deviceId == DEVICE_ID_OF_A) {
+               PortNumber uplink = PortNumber.portNumber(3);
+               VlanId vlan = VlanId.vlanId((short) 0);
+               ObjectMapper mapper = new ObjectMapper();
+               JsonNode defaultVlanNode = null;
+               try {
+                    defaultVlanNode =
+                    (JsonNode) mapper.readTree("{\"driver\":\"pmc-olt\" , \"type \" : \"OLT\"}");
+               } catch (IOException e) {
+                    e.printStackTrace();
+               }
+
+               Optional<VlanId> defaultVlan;
+               if (defaultVlanNode.isMissingNode()) {
+                    defaultVlan = Optional.empty();
+               } else {
+                    defaultVlan = Optional.of(VlanId.vlanId(defaultVlanNode.shortValue()));
+               }
+               Optional<AccessDeviceData> accessDeviceData = null;
+               AccessDeviceData accessDevice = new AccessDeviceData(deviceId, uplink, vlan, defaultVlan);
+               accessDeviceData = Optional.of(accessDevice);
+               return accessDeviceData;
+             } else {
+                 knownOltFlag = true;
+                 return Optional.empty();
+             }
+          }
+
+          @Override
+          public Set<AccessAgentData> getAccessAgents() {
+               return null;
+          }
+
+          @Override
+          public Optional<AccessAgentData> getAccessAgent(DeviceId deviceId) {
+               return null;
+          }
+
+     }
+
+     public OutputInstruction outputPort(TrafficTreatment trafficTreatment) {
+         List<Instruction> listOfInstructions = trafficTreatment.allInstructions();
+         OutputInstruction output = null;
+         for (Instruction intruction : listOfInstructions) {
+           output = (OutputInstruction) intruction;
+         }
+         return output;
+     }
+
+     public IPCriterion ipAddress(TrafficSelector trafficSelector) {
+       Set<Criterion> criterionSet = trafficSelector.criteria();
+       Iterator<Criterion> it = criterionSet.iterator();
+       IPCriterion ipCriterion = null;
+       while (it.hasNext()) {
+           Criterion criteria = it.next();
+           if (Criterion.Type.IPV4_DST == criteria.type()) {
+             ipCriterion = (IPCriterion) criteria;
+           }
+       }
+       return (IPCriterion) ipCriterion;
+     }
+
+}
