diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
index 88601aa..4f70a1b 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
@@ -286,7 +286,7 @@
                     Map<ConnectPoint, List<ConnectPoint>> mcastPaths = Maps.newHashMap();
                     Set<DeviceId> visited = Sets.newHashSet();
                     List<ConnectPoint> currentPath = Lists.newArrayList(source);
-                    buildMcastPaths(source.deviceId(), visited, mcastPaths,
+                    mcastUtils.buildMcastPaths(mcastNextObjStore.asJavaMap(), source.deviceId(), visited, mcastPaths,
                                     currentPath, mcastRoute.group(), source);
                     // Get all the sinks and process them
                     Set<ConnectPoint> sinks = processSinksToBeAdded(source, mcastRoute.group(),
@@ -1816,7 +1816,7 @@
      * @param mcastIp the group ip
      * @return the mapping mcastIp-device to next id
      */
-    public Map<McastStoreKey, Integer> getMcastNextIds(IpAddress mcastIp) {
+    public Map<McastStoreKey, Integer> getNextIds(IpAddress mcastIp) {
         if (mcastIp != null) {
             return mcastNextObjStore.entrySet().stream()
                     .filter(mcastEntry -> mcastIp.equals(mcastEntry.getKey().mcastIp()))
@@ -1827,6 +1827,19 @@
     }
 
     /**
+     * Removes given next ID from mcast next id store.
+     *
+     * @param nextId next id
+     */
+    public void removeNextId(int nextId) {
+        mcastNextObjStore.entrySet().forEach(e -> {
+            if (e.getValue().value().id() == nextId) {
+                mcastNextObjStore.remove(e.getKey());
+            }
+        });
+    }
+
+    /**
      * Returns the associated roles to the mcast groups or to the single
      * group if mcastIp is present.
      *
@@ -1891,7 +1904,8 @@
         if (source != null) {
             Set<DeviceId> visited = Sets.newHashSet();
             List<ConnectPoint> currentPath = Lists.newArrayList(source);
-            buildMcastPaths(source.deviceId(), visited, mcastPaths, currentPath, mcastIp, source);
+            mcastUtils.buildMcastPaths(mcastNextObjStore.asJavaMap(), source.deviceId(), visited, mcastPaths,
+                    currentPath, mcastIp, source);
         }
         return mcastPaths;
     }
@@ -1916,7 +1930,8 @@
                 Map<ConnectPoint, List<ConnectPoint>> mcastPaths = Maps.newHashMap();
                 Set<DeviceId> visited = Sets.newHashSet();
                 List<ConnectPoint> currentPath = Lists.newArrayList(source);
-                buildMcastPaths(source.deviceId(), visited, mcastPaths, currentPath, mcastIp, source);
+                mcastUtils.buildMcastPaths(mcastNextObjStore.asJavaMap(), source.deviceId(), visited, mcastPaths,
+                        currentPath, mcastIp, source);
                 mcastPaths.forEach(mcastTrees::put);
             });
         }
@@ -1924,63 +1939,6 @@
     }
 
     /**
-     * Build recursively the mcast paths.
-     *
-     * @param toVisit the node to visit
-     * @param visited the visited nodes
-     * @param mcastPaths the current mcast paths
-     * @param currentPath the current path
-     * @param mcastIp the group ip
-     * @param source the source
-     */
-    private void buildMcastPaths(DeviceId toVisit, Set<DeviceId> visited,
-                                 Map<ConnectPoint, List<ConnectPoint>> mcastPaths,
-                                 List<ConnectPoint> currentPath, IpAddress mcastIp,
-                                 ConnectPoint source) {
-        // If we have visited the node to visit there is a loop
-        if (visited.contains(toVisit)) {
-            return;
-        }
-        // Visit next-hop
-        visited.add(toVisit);
-        VlanId assignedVlan = mcastUtils.assignedVlan(toVisit.equals(source.deviceId()) ? source : null);
-        McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, toVisit, assignedVlan);
-        // Looking for next-hops
-        if (mcastNextObjStore.containsKey(mcastStoreKey)) {
-            // Build egress connect points, get ports and build relative cps
-            NextObjective nextObjective = mcastNextObjStore.get(mcastStoreKey).value();
-            Set<PortNumber> outputPorts = mcastUtils.getPorts(nextObjective.next());
-            ImmutableSet.Builder<ConnectPoint> cpBuilder = ImmutableSet.builder();
-            outputPorts.forEach(portNumber -> cpBuilder.add(new ConnectPoint(toVisit, portNumber)));
-            Set<ConnectPoint> egressPoints = cpBuilder.build();
-            Set<Link> egressLinks;
-            List<ConnectPoint> newCurrentPath;
-            Set<DeviceId> newVisited;
-            DeviceId newToVisit;
-            for (ConnectPoint egressPoint : egressPoints) {
-                egressLinks = srManager.linkService.getEgressLinks(egressPoint);
-                // If it does not have egress links, stop
-                if (egressLinks.isEmpty()) {
-                    // Add the connect points to the path
-                    newCurrentPath = Lists.newArrayList(currentPath);
-                    newCurrentPath.add(0, egressPoint);
-                    mcastPaths.put(egressPoint, newCurrentPath);
-                } else {
-                    newVisited = Sets.newHashSet(visited);
-                    // Iterate over the egress links for the next hops
-                    for (Link egressLink : egressLinks) {
-                        newToVisit = egressLink.dst().deviceId();
-                        newCurrentPath = Lists.newArrayList(currentPath);
-                        newCurrentPath.add(0, egressPoint);
-                        newCurrentPath.add(0, egressLink.dst());
-                        buildMcastPaths(newToVisit, newVisited, mcastPaths, newCurrentPath, mcastIp, source);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
      * Return the leaders of the mcast groups.
      *
      * @param mcastIp the group ip
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java
index 0793984..52232b9 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java
@@ -18,7 +18,9 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import com.google.common.hash.HashFunction;
 import com.google.common.hash.Hashing;
 import org.onlab.packet.Ethernet;
@@ -31,6 +33,7 @@
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.HostId;
+import org.onosproject.net.Link;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.config.basics.McastConfig;
 import org.onosproject.net.flow.DefaultTrafficSelector;
@@ -55,6 +58,7 @@
 import org.slf4j.Logger;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -486,4 +490,64 @@
         // Otherwise take all the groups
         return ImmutableMap.copyOf(mcastLeaderCache);
     }
+
+    /**
+     * Build recursively the mcast paths.
+     *
+     * @param mcastNextObjStore mcast next obj store
+     * @param toVisit the node to visit
+     * @param visited the visited nodes
+     * @param mcastPaths the current mcast paths
+     * @param currentPath the current path
+     * @param mcastIp the group ip
+     * @param source the source
+     */
+    void buildMcastPaths(Map<McastStoreKey, NextObjective> mcastNextObjStore,
+                                 DeviceId toVisit, Set<DeviceId> visited,
+                                 Map<ConnectPoint, List<ConnectPoint>> mcastPaths,
+                                 List<ConnectPoint> currentPath, IpAddress mcastIp,
+                                 ConnectPoint source) {
+        // If we have visited the node to visit there is a loop
+        if (visited.contains(toVisit)) {
+            return;
+        }
+        // Visit next-hop
+        visited.add(toVisit);
+        VlanId assignedVlan = assignedVlan(toVisit.equals(source.deviceId()) ? source : null);
+        McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, toVisit, assignedVlan);
+        // Looking for next-hops
+        if (mcastNextObjStore.containsKey(mcastStoreKey)) {
+            // Build egress connect points, get ports and build relative cps
+            NextObjective nextObjective = mcastNextObjStore.get(mcastStoreKey);
+            Set<PortNumber> outputPorts = getPorts(nextObjective.next());
+            ImmutableSet.Builder<ConnectPoint> cpBuilder = ImmutableSet.builder();
+            outputPorts.forEach(portNumber -> cpBuilder.add(new ConnectPoint(toVisit, portNumber)));
+            Set<ConnectPoint> egressPoints = cpBuilder.build();
+            Set<Link> egressLinks;
+            List<ConnectPoint> newCurrentPath;
+            Set<DeviceId> newVisited;
+            DeviceId newToVisit;
+            for (ConnectPoint egressPoint : egressPoints) {
+                egressLinks = srManager.linkService.getEgressLinks(egressPoint);
+                // If it does not have egress links, stop
+                if (egressLinks.isEmpty()) {
+                    // Add the connect points to the path
+                    newCurrentPath = Lists.newArrayList(currentPath);
+                    newCurrentPath.add(0, egressPoint);
+                    mcastPaths.put(egressPoint, newCurrentPath);
+                } else {
+                    newVisited = Sets.newHashSet(visited);
+                    // Iterate over the egress links for the next hops
+                    for (Link egressLink : egressLinks) {
+                        newToVisit = egressLink.dst().deviceId();
+                        newCurrentPath = Lists.newArrayList(currentPath);
+                        newCurrentPath.add(0, egressPoint);
+                        newCurrentPath.add(0, egressLink.dst());
+                        buildMcastPaths(mcastNextObjStore, newToVisit, newVisited, mcastPaths, newCurrentPath, mcastIp,
+                                source);
+                    }
+                }
+            }
+        }
+    }
 }
