diff --git a/app/src/main/java/org/onosproject/segmentrouting/mcast/McastCacheKey.java b/app/src/main/java/org/onosproject/segmentrouting/mcast/McastCacheKey.java
index b0875ca..930432d 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/mcast/McastCacheKey.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/mcast/McastCacheKey.java
@@ -18,6 +18,7 @@
 
 import org.onlab.packet.IpAddress;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.HostId;
 
 import java.util.Objects;
 
@@ -31,6 +32,8 @@
 class McastCacheKey {
     // The group ip
     private final IpAddress mcastIp;
+    // The sink id
+    private final HostId sinkHost;
     // The sink connect point
     private final ConnectPoint sink;
 
@@ -39,6 +42,8 @@
      *
      * @param mcastIp multicast group IP address
      * @param sink connect point of the sink
+     *
+     * @deprecated in 1.12 ("Magpie") release.
      */
     public McastCacheKey(IpAddress mcastIp, ConnectPoint sink) {
         checkNotNull(mcastIp, "mcastIp cannot be null");
@@ -46,6 +51,22 @@
         checkArgument(mcastIp.isMulticast(), "mcastIp must be a multicast address");
         this.mcastIp = mcastIp;
         this.sink = sink;
+        this.sinkHost = null;
+    }
+
+    /**
+     * Constructs a key for multicast event cache.
+     *
+     * @param mcastIp multicast group IP address
+     * @param hostId id of the sink
+     */
+    public McastCacheKey(IpAddress mcastIp, HostId hostId) {
+        checkNotNull(mcastIp, "mcastIp cannot be null");
+        checkNotNull(hostId, "sink cannot be null");
+        checkArgument(mcastIp.isMulticast(), "mcastIp must be a multicast address");
+        this.mcastIp = mcastIp;
+        this.sinkHost = hostId;
+        this.sink = null;
     }
 
     /**
@@ -61,11 +82,22 @@
      * Returns the sink of this key.
      *
      * @return connect point of the sink
+     *
+     * @deprecated in 1.12 ("Magpie") release.
      */
     public ConnectPoint sink() {
         return sink;
     }
 
+    /**
+     * Returns the sink of this key.
+     *
+     * @return host id of the sink
+     */
+    public HostId sinkHost() {
+        return sinkHost;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) {
@@ -77,7 +109,8 @@
         McastCacheKey that =
                 (McastCacheKey) o;
         return (Objects.equals(this.mcastIp, that.mcastIp) &&
-                Objects.equals(this.sink, that.sink));
+                Objects.equals(this.sink, that.sink) &&
+                Objects.equals(this.sinkHost, that.sinkHost));
     }
 
     @Override
@@ -90,6 +123,7 @@
         return toStringHelper(getClass())
                 .add("mcastIp", mcastIp)
                 .add("sink", sink)
+                .add("sinkHost", sinkHost)
                 .toString();
     }
 }
diff --git a/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java b/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
index 968ad3b..4c83a38 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
@@ -20,40 +20,27 @@
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.RemovalCause;
 import com.google.common.cache.RemovalNotification;
+import com.google.common.collect.ImmutableList;
 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 org.onlab.packet.Ethernet;
 import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 import org.onlab.util.KryoNamespace;
-import org.onosproject.cluster.NodeId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.mcast.api.McastEvent;
 import org.onosproject.mcast.api.McastRoute;
+import org.onosproject.mcast.api.McastRouteData;
 import org.onosproject.mcast.api.McastRouteUpdate;
-import org.onosproject.net.config.basics.McastConfig;
+import org.onosproject.net.HostId;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 import org.onosproject.net.PortNumber;
-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.flow.criteria.VlanIdCriterion;
-import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
-import org.onosproject.net.flowobjective.DefaultFilteringObjective;
-import org.onosproject.net.flowobjective.DefaultForwardingObjective;
-import org.onosproject.net.flowobjective.DefaultNextObjective;
 import org.onosproject.net.flowobjective.DefaultObjectiveContext;
-import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.flowobjective.NextObjective;
 import org.onosproject.net.flowobjective.ObjectiveContext;
@@ -62,14 +49,10 @@
 import org.onosproject.net.topology.TopologyService;
 import org.onosproject.segmentrouting.SRLinkWeigher;
 import org.onosproject.segmentrouting.SegmentRoutingManager;
-import org.onosproject.segmentrouting.SegmentRoutingService;
-import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
-import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
 import org.onosproject.segmentrouting.storekey.McastStoreKey;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.ConsistentMap;
 import org.onosproject.store.service.Serializer;
-import org.onosproject.store.service.StorageService;
 import org.onosproject.store.service.Versioned;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -92,9 +75,11 @@
 import static java.util.concurrent.Executors.newScheduledThreadPool;
 import static org.onlab.util.Tools.groupedThreads;
 
-import static org.onosproject.mcast.api.McastEvent.Type.*;
-import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
-import static org.onosproject.segmentrouting.SegmentRoutingManager.INTERNAL_VLAN;
+import static org.onosproject.mcast.api.McastEvent.Type.SOURCES_REMOVED;
+import static org.onosproject.mcast.api.McastEvent.Type.SOURCES_ADDED;
+import static org.onosproject.mcast.api.McastEvent.Type.SINKS_REMOVED;
+import static org.onosproject.mcast.api.McastEvent.Type.SINKS_ADDED;
+import static org.onosproject.mcast.api.McastEvent.Type.ROUTE_REMOVED;
 import static org.onosproject.segmentrouting.mcast.McastRole.EGRESS;
 import static org.onosproject.segmentrouting.mcast.McastRole.INGRESS;
 import static org.onosproject.segmentrouting.mcast.McastRole.TRANSIT;
@@ -103,17 +88,24 @@
  * Handles Multicast related events.
  */
 public class McastHandler {
+    // Logger instance
     private static final Logger log = LoggerFactory.getLogger(McastHandler.class);
+    // Reference to srManager and most used internal objects
     private final SegmentRoutingManager srManager;
-    private final ApplicationId coreAppId;
-    private final StorageService storageService;
     private final TopologyService topologyService;
+    // Internal store of the Mcast nextobjectives
     private final ConsistentMap<McastStoreKey, NextObjective> mcastNextObjStore;
-    private final KryoNamespace.Builder mcastKryo;
+    // Internal store of the Mcast roles
     private final ConsistentMap<McastStoreKey, McastRole> mcastRoleStore;
+    // McastUtils
+    private final McastUtils mcastUtils;
 
     // Wait time for the cache
     private static final int WAIT_TIME_MS = 1000;
+
+    // Wait time for the removal of the old location
+    private static final int HOST_MOVED_DELAY_MS = 1000;
+
     /**
      * The mcastEventCache is implemented to avoid race condition by giving more time to the
      * underlying subsystems to process previous calls.
@@ -123,7 +115,7 @@
             .removalListener((RemovalNotification<McastCacheKey, McastEvent> notification) -> {
                 // Get group ip, sink and related event
                 IpAddress mcastIp = notification.getKey().mcastIp();
-                ConnectPoint sink = notification.getKey().sink();
+                HostId sink = notification.getKey().sinkHost();
                 McastEvent mcastEvent = notification.getValue();
                 RemovalCause cause = notification.getCause();
                 log.debug("mcastEventCache removal event. group={}, sink={}, mcastEvent={}, cause={}",
@@ -140,50 +132,42 @@
             }).build();
 
     private void enqueueMcastEvent(McastEvent mcastEvent) {
-        log.debug("Enqueue mcastEvent {}", mcastEvent);
+        // Retrieve, currentData, prevData and the group
         final McastRouteUpdate mcastRouteUpdate = mcastEvent.subject();
-        final McastRouteUpdate prevUpdate = mcastEvent.prevSubject();
-        final IpAddress group = prevUpdate.route().group();
+        final McastRouteUpdate mcastRoutePrevUpdate = mcastEvent.prevSubject();
+        final IpAddress group = mcastRoutePrevUpdate.route().group();
         // Let's create the keys of the cache
-        ImmutableSet.Builder<ConnectPoint> sinksBuilder = ImmutableSet.builder();
-        Set<ConnectPoint> sinks;
-        // For this event we will have a set of sinks
+        ImmutableSet.Builder<HostId> sinksBuilder = ImmutableSet.builder();
         if (mcastEvent.type() == SOURCES_ADDED ||
                 mcastEvent.type() == SOURCES_REMOVED) {
             // FIXME To be addressed with multiple sources support
-            sinks = mcastRouteUpdate.sinks()
-                    .values()
-                    .stream()
-                    .flatMap(Collection::stream)
-                    .collect(Collectors.toSet());
-        } else {
-            Set<ConnectPoint> prevSinks = prevUpdate.sinks()
-                    .values()
-                    .stream()
-                    .flatMap(Collection::stream)
-                    .collect(Collectors.toSet());
-            if (mcastEvent.type() == ROUTE_REMOVED) {
-                // Get the old sinks, since current subject is null
-                sinks = prevSinks;
-            } else {
-                // Get new sinks
-                Set<ConnectPoint> newsinks = mcastRouteUpdate.sinks()
-                        .values()
-                        .stream()
-                        .flatMap(Collection::stream)
-                        .collect(Collectors.toSet());
-                // If it is a SINKS_ADDED event
-                if (mcastEvent.type() == SINKS_ADDED) {
-                    // Let's do the difference between current and prev subjects
-                    sinks = Sets.difference(newsinks, prevSinks);
-                } else {
-                    // Let's do the difference between prev and current subjects
-                    sinks = Sets.difference(prevSinks, newsinks);
+            sinksBuilder.addAll(Collections.emptySet());
+        } else if (mcastEvent.type() == SINKS_ADDED) {
+            // We need to process the host id one by one
+            mcastRouteUpdate.sinks().forEach(((hostId, connectPoints) -> {
+                // Get the previous locations and verify if there are changes
+                Set<ConnectPoint> prevConnectPoints = mcastRoutePrevUpdate.sinks().get(hostId);
+                Set<ConnectPoint> changes = Sets.difference(connectPoints, prevConnectPoints != null ?
+                        prevConnectPoints : Collections.emptySet());
+                if (!changes.isEmpty()) {
+                    sinksBuilder.add(hostId);
                 }
-            }
+            }));
+        } else if (mcastEvent.type() == SINKS_REMOVED) {
+            // We need to process the host id one by one
+            mcastRoutePrevUpdate.sinks().forEach(((hostId, connectPoints) -> {
+                // Get the current locations and verify if there are changes
+                Set<ConnectPoint> currentConnectPoints = mcastRouteUpdate.sinks().get(hostId);
+                Set<ConnectPoint> changes = Sets.difference(connectPoints, currentConnectPoints != null ?
+                        currentConnectPoints : Collections.emptySet());
+                if (!changes.isEmpty()) {
+                    sinksBuilder.add(hostId);
+                }
+            }));
+        } else if (mcastEvent.type() == ROUTE_REMOVED) {
+            // Current subject is null, just take the previous host ids
+            sinksBuilder.addAll(mcastRoutePrevUpdate.sinks().keySet());
         }
-        // Add all the sinks
-        sinksBuilder.addAll(sinks);
         // Push the elements in the cache
         sinksBuilder.build().forEach(sink -> {
             McastCacheKey cacheKey = new McastCacheKey(group, sink);
@@ -192,24 +176,22 @@
     }
 
     private void dequeueMcastEvent(McastEvent mcastEvent) {
-        log.debug("Dequeue mcastEvent {}", mcastEvent);
-        final McastRouteUpdate mcastRouteUpdate = mcastEvent.subject();
-        final McastRouteUpdate prevUpdate = mcastEvent.prevSubject();
+        // Get new and old data
+        final McastRouteUpdate mcastUpdate = mcastEvent.subject();
+        final McastRouteUpdate mcastPrevUpdate = mcastEvent.prevSubject();
         // Get source, mcast group
         // FIXME To be addressed with multiple sources support
-        ConnectPoint prevSource = prevUpdate.sources()
+        final ConnectPoint source = mcastPrevUpdate.sources()
                 .stream()
                 .findFirst()
                 .orElse(null);
-        IpAddress mcastIp = prevUpdate.route().group();
-        Set<ConnectPoint> prevSinks = prevUpdate.sinks()
+        IpAddress mcastIp = mcastPrevUpdate.route().group();
+        // Get all the previous sinks
+        Set<ConnectPoint> prevSinks = mcastPrevUpdate.sinks()
                 .values()
                 .stream()
                 .flatMap(Collection::stream)
                 .collect(Collectors.toSet());
-        Set<ConnectPoint> newSinks;
-        // Sinks to handled by SINKS_ADDED and SINKS_REMOVED procedures
-        Set<ConnectPoint> sinks;
         // According to the event type let's call the proper method
         switch (mcastEvent.type()) {
             case SOURCES_ADDED:
@@ -230,27 +212,17 @@
                 break;
             case ROUTE_REMOVED:
                 // Process the route removed, just the first cached element will be processed
-                processRouteRemovedInternal(prevSource, mcastIp);
+                processRouteRemovedInternal(source, mcastIp);
                 break;
             case SINKS_ADDED:
-                // Get the only sinks to be processed (new ones)
-                newSinks = mcastRouteUpdate.sinks()
-                        .values()
-                        .stream()
-                        .flatMap(Collection::stream)
-                        .collect(Collectors.toSet());
-                sinks = Sets.difference(newSinks, prevSinks);
-                sinks.forEach(sink -> processSinkAddedInternal(prevSource, sink, mcastIp, null));
+                // FIXME To be addressed with multiple sources support
+                processSinksAddedInternal(source, mcastIp,
+                                          mcastUpdate.sinks(), prevSinks);
                 break;
             case SINKS_REMOVED:
-                // Get the only sinks to be processed (old ones)
-                newSinks = mcastRouteUpdate.sinks()
-                        .values()
-                        .stream()
-                        .flatMap(Collection::stream)
-                        .collect(Collectors.toSet());
-                sinks = Sets.difference(prevSinks, newSinks);
-                sinks.forEach(sink -> processSinkRemovedInternal(prevSource, sink, mcastIp));
+                // FIXME To be addressed with multiple sources support
+                processSinksRemovedInternal(source, mcastIp,
+                                            mcastUpdate.sinks(), prevSinks);
                 break;
             default:
                 break;
@@ -306,28 +278,28 @@
      * @param srManager Segment Routing manager
      */
     public McastHandler(SegmentRoutingManager srManager) {
-        coreAppId = srManager.coreService.getAppId(CoreService.CORE_APP_NAME);
+        ApplicationId coreAppId = srManager.coreService.getAppId(CoreService.CORE_APP_NAME);
         this.srManager = srManager;
-        this.storageService = srManager.storageService;
         this.topologyService = srManager.topologyService;
-        mcastKryo = new KryoNamespace.Builder()
+        KryoNamespace.Builder mcastKryo = new KryoNamespace.Builder()
                 .register(KryoNamespaces.API)
                 .register(McastStoreKey.class)
                 .register(McastRole.class);
-        mcastNextObjStore = storageService
+        mcastNextObjStore = srManager.storageService
                 .<McastStoreKey, NextObjective>consistentMapBuilder()
                 .withName("onos-mcast-nextobj-store")
                 .withSerializer(Serializer.using(mcastKryo.build("McastHandler-NextObj")))
                 .build();
-        mcastRoleStore = storageService
+        mcastRoleStore = srManager.storageService
                 .<McastStoreKey, McastRole>consistentMapBuilder()
                 .withName("onos-mcast-role-store")
                 .withSerializer(Serializer.using(mcastKryo.build("McastHandler-Role")))
                 .build();
+        // Let's create McastUtils object
+        mcastUtils = new McastUtils(srManager, coreAppId, log);
         // Init the executor service and the buckets corrector
         executorService.scheduleWithFixedDelay(new McastBucketCorrector(), 10,
-                                               MCAST_VERIFY_INTERVAL,
-                                               TimeUnit.SECONDS);
+                                               MCAST_VERIFY_INTERVAL, TimeUnit.SECONDS);
         // Schedule the clean up, this will allow the processing of the expired events
         executorService.scheduleAtFixedRate(mcastEventCache::cleanUp, 0,
                                             WAIT_TIME_MS, TimeUnit.MILLISECONDS);
@@ -337,28 +309,36 @@
      * Read initial multicast from mcast store.
      */
     public void init() {
-        srManager.multicastRouteService.getRoutes().forEach(mcastRoute -> {
-            // FIXME To be addressed with multiple sources support
-            ConnectPoint source = srManager.multicastRouteService.sources(mcastRoute)
-                    .stream()
-                    .findFirst()
-                    .orElse(null);
-            Set<ConnectPoint> sinks = srManager.multicastRouteService.sinks(mcastRoute);
-            // Filter out all the working sinks, we do not want to move them
-            sinks = sinks.stream()
-                    .filter(sink -> {
-                        McastStoreKey mcastKey = new McastStoreKey(mcastRoute.group(), sink.deviceId());
-                        Versioned<NextObjective> verMcastNext = mcastNextObjStore.get(mcastKey);
-                        return verMcastNext == null ||
-                                !getPorts(verMcastNext.value().next()).contains(sink.port());
-                    })
-                    .collect(Collectors.toSet());
-            // Compute the Mcast tree
-            Map<ConnectPoint, List<Path>> mcasTree = computeSinkMcastTree(source.deviceId(), sinks);
-            // Process the given sinks using the pre-computed paths
-            mcasTree.forEach((sink, paths) -> processSinkAddedInternal(source, sink,
-                                                                       mcastRoute.group(), paths));
-        });
+        lastMcastChange = Instant.now();
+        mcastLock();
+        try {
+            srManager.multicastRouteService.getRoutes().forEach(mcastRoute -> {
+                // FIXME To be addressed with multiple sources support
+                ConnectPoint source = srManager.multicastRouteService.sources(mcastRoute)
+                        .stream()
+                        .findFirst()
+                        .orElse(null);
+                // Get all the sinks and process them
+                McastRouteData mcastRouteData = srManager.multicastRouteService.routeData(mcastRoute);
+                Set<ConnectPoint> sinks = processSinksToBeAdded(source, mcastRoute.group(), mcastRouteData.sinks());
+                // Filter out all the working sinks, we do not want to move them
+                sinks = sinks.stream()
+                        .filter(sink -> {
+                            McastStoreKey mcastKey = new McastStoreKey(mcastRoute.group(), sink.deviceId());
+                            Versioned<NextObjective> verMcastNext = mcastNextObjStore.get(mcastKey);
+                            return verMcastNext == null ||
+                                    !mcastUtils.getPorts(verMcastNext.value().next()).contains(sink.port());
+                        })
+                        .collect(Collectors.toSet());
+                // Compute the Mcast tree
+                Map<ConnectPoint, List<Path>> mcasTree = computeSinkMcastTree(source.deviceId(), sinks);
+                // Process the given sinks using the pre-computed paths
+                mcasTree.forEach((sink, paths) -> processSinkAddedInternal(source, sink,
+                                                                           mcastRoute.group(), paths));
+            });
+        } finally {
+            mcastUnlock();
+        }
     }
 
     /**
@@ -398,7 +378,7 @@
             McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, oldSource.deviceId());
 
             // Verify leadership on the operation
-            if (!isLeader(oldSource)) {
+            if (!mcastUtils.isLeader(oldSource)) {
                 log.debug("Skip {} due to lack of leadership", mcastIp);
                 return;
             }
@@ -410,18 +390,19 @@
                 return;
             }
             NextObjective nextObjective = mcastNextObjStore.get(mcastStoreKey).value();
-            Set<PortNumber> outputPorts = getPorts(nextObjective.next());
+            Set<PortNumber> outputPorts = mcastUtils.getPorts(nextObjective.next());
 
             // This an optimization to avoid unnecessary removal and add
-            if (!assignedVlanFromNext(nextObjective).equals(assignedVlan(newSource))) {
+            if (!mcastUtils.assignedVlanFromNext(nextObjective)
+                    .equals(mcastUtils.assignedVlan(newSource))) {
                 // Let's remove old flows and groups
-                removeGroupFromDevice(oldSource.deviceId(), mcastIp, assignedVlan(oldSource));
+                removeGroupFromDevice(oldSource.deviceId(), mcastIp, mcastUtils.assignedVlan(oldSource));
                 // Push new flows and group
                 outputPorts.forEach(portNumber -> addPortToDevice(newSource.deviceId(), portNumber,
-                                                                  mcastIp, assignedVlan(newSource)));
+                                                                  mcastIp, mcastUtils.assignedVlan(newSource)));
             }
-            addFilterToDevice(newSource.deviceId(), newSource.port(),
-                              assignedVlan(newSource), mcastIp, INGRESS);
+            mcastUtils.addFilterToDevice(newSource.deviceId(), newSource.port(),
+                              mcastUtils.assignedVlan(newSource), mcastIp, INGRESS);
             // Setup mcast roles
             mcastRoleStore.put(new McastStoreKey(mcastIp, newSource.deviceId()),
                                INGRESS);
@@ -448,7 +429,7 @@
             Set<DeviceId> egressDevices = getDevice(mcastIp, EGRESS);
 
             // Verify leadership on the operation
-            if (!isLeader(source)) {
+            if (!mcastUtils.isLeader(source)) {
                 log.debug("Skip {} due to lack of leadership", mcastIp);
                 return;
             }
@@ -456,24 +437,60 @@
             // If there are no egress devices, sinks could be only on the ingress
             if (!egressDevices.isEmpty()) {
                 egressDevices.forEach(
-                        deviceId -> removeGroupFromDevice(deviceId, mcastIp, assignedVlan(null))
+                        deviceId -> removeGroupFromDevice(deviceId, mcastIp, mcastUtils.assignedVlan(null))
                 );
             }
             // Transit could be empty if sinks are on the ingress
             if (!transitDevices.isEmpty()) {
                 transitDevices.forEach(
-                        deviceId -> removeGroupFromDevice(deviceId, mcastIp, assignedVlan(null))
+                        deviceId -> removeGroupFromDevice(deviceId, mcastIp, mcastUtils.assignedVlan(null))
                 );
             }
             // Ingress device should be not null
             if (ingressDevice != null) {
-                removeGroupFromDevice(ingressDevice, mcastIp, assignedVlan(source));
+                removeGroupFromDevice(ingressDevice, mcastIp, mcastUtils.assignedVlan(source));
             }
         } finally {
             mcastUnlock();
         }
     }
 
+
+    /**
+     * Process sinks to be removed.
+     *
+     * @param source the source connect point
+     * @param mcastIp the ip address of the group
+     * @param newSinks the new sinks to be processed
+     * @param allPrevSinks all previous sinks
+     */
+    private void processSinksRemovedInternal(ConnectPoint source, IpAddress mcastIp,
+                                             Map<HostId, Set<ConnectPoint>> newSinks,
+                                             Set<ConnectPoint> allPrevSinks) {
+        lastMcastChange = Instant.now();
+        mcastLock();
+        // Let's instantiate the sinks to be removed
+        Set<ConnectPoint> sinksToBeRemoved = Sets.newHashSet();
+        try {
+            // Recover the dual-homed sinks
+            Set<ConnectPoint> sinksToBeRecovered = processSinksToBeRecovered(mcastIp, newSinks);
+            sinksToBeRecovered.forEach(sink -> processSinkAddedInternal(source, sink, mcastIp, null));
+            // Get the only sinks to be processed (old ones)
+            Set<ConnectPoint> allNewSinks = newSinks.values()
+                    .stream()
+                    .flatMap(Collection::stream)
+                    .collect(Collectors.toSet());
+            // Remove the previous one
+            sinksToBeRemoved.addAll(Sets.difference(allPrevSinks, allNewSinks));
+        } finally {
+            mcastUnlock();
+            // Let's schedule the removal of the previous sinks
+            executorService.schedule(
+                    () -> sinksToBeRemoved.forEach(sink -> processSinkRemovedInternal(source, sink, mcastIp)),
+                    HOST_MOVED_DELAY_MS, TimeUnit.MILLISECONDS);
+        }
+    }
+
     /**
      * Removes a path from source to sink for given multicast group.
      *
@@ -482,17 +499,17 @@
      * @param mcastIp multicast group IP address
      */
     private void processSinkRemovedInternal(ConnectPoint source, ConnectPoint sink,
-                                          IpAddress mcastIp) {
+                                            IpAddress mcastIp) {
         lastMcastChange = Instant.now();
         mcastLock();
         try {
             // Verify leadership on the operation
-            if (!isLeader(source)) {
+            if (!mcastUtils.isLeader(source)) {
                 log.debug("Skip {} due to lack of leadership", mcastIp);
                 return;
             }
 
-            boolean isLast = false;
+            boolean isLast;
             // When source and sink are on the same device
             if (source.deviceId().equals(sink.deviceId())) {
                 // Source and sink are on even the same port. There must be something wrong.
@@ -501,7 +518,7 @@
                              mcastIp, sink, source);
                     return;
                 }
-                isLast = removePortFromDevice(sink.deviceId(), sink.port(), mcastIp, assignedVlan(source));
+                isLast = removePortFromDevice(sink.deviceId(), sink.port(), mcastIp, mcastUtils.assignedVlan(source));
                 if (isLast) {
                     mcastRoleStore.remove(new McastStoreKey(mcastIp, sink.deviceId()));
                 }
@@ -509,7 +526,7 @@
             }
 
             // Process the egress device
-            isLast = removePortFromDevice(sink.deviceId(), sink.port(), mcastIp, assignedVlan(null));
+            isLast = removePortFromDevice(sink.deviceId(), sink.port(), mcastIp, mcastUtils.assignedVlan(null));
             if (isLast) {
                 mcastRoleStore.remove(new McastStoreKey(mcastIp, sink.deviceId()));
             }
@@ -526,7 +543,8 @@
                                 link.src().deviceId(),
                                 link.src().port(),
                                 mcastIp,
-                                assignedVlan(link.src().deviceId().equals(source.deviceId()) ? source : null)
+                                mcastUtils.assignedVlan(link.src().deviceId().equals(source.deviceId()) ?
+                                                     source : null)
                         );
                         if (isLast) {
                             mcastRoleStore.remove(new McastStoreKey(mcastIp, link.src().deviceId()));
@@ -539,6 +557,31 @@
         }
     }
 
+
+    /**
+     * Process sinks to be added.
+     *
+     * @param source the source connect point
+     * @param mcastIp the group IP
+     * @param newSinks the new sinks to be processed
+     * @param allPrevSinks all previous sinks
+     */
+    private void processSinksAddedInternal(ConnectPoint source, IpAddress mcastIp,
+                                           Map<HostId, Set<ConnectPoint>> newSinks,
+                                           Set<ConnectPoint> allPrevSinks) {
+        lastMcastChange = Instant.now();
+        mcastLock();
+        try {
+            // Get the only sinks to be processed (new ones)
+            Set<ConnectPoint> sinksToBeAdded = processSinksToBeAdded(source, mcastIp, newSinks);
+            // Install new sinks
+            sinksToBeAdded = Sets.difference(sinksToBeAdded, allPrevSinks);
+            sinksToBeAdded.forEach(sink -> processSinkAddedInternal(source, sink, mcastIp, null));
+        } finally {
+            mcastUnlock();
+        }
+    }
+
     /**
      * Establishes a path from source to sink for given multicast group.
      *
@@ -547,7 +590,7 @@
      * @param mcastIp multicast group IP address
      */
     private void processSinkAddedInternal(ConnectPoint source, ConnectPoint sink,
-            IpAddress mcastIp, List<Path> allPaths) {
+                                          IpAddress mcastIp, List<Path> allPaths) {
         lastMcastChange = Instant.now();
         mcastLock();
         try {
@@ -559,8 +602,8 @@
             }
 
             // Process the ingress device
-            addFilterToDevice(source.deviceId(), source.port(),
-                              assignedVlan(source), mcastIp, INGRESS);
+            mcastUtils.addFilterToDevice(source.deviceId(), source.port(),
+                              mcastUtils.assignedVlan(source), mcastIp, INGRESS);
 
             // When source and sink are on the same device
             if (source.deviceId().equals(sink.deviceId())) {
@@ -570,7 +613,7 @@
                              mcastIp, sink, source);
                     return;
                 }
-                addPortToDevice(sink.deviceId(), sink.port(), mcastIp, assignedVlan(source));
+                addPortToDevice(sink.deviceId(), sink.port(), mcastIp, mcastUtils.assignedVlan(source));
                 mcastRoleStore.put(new McastStoreKey(mcastIp, sink.deviceId()), INGRESS);
                 return;
             }
@@ -588,9 +631,10 @@
                 // Setup properly the transit
                 links.forEach(link -> {
                     addPortToDevice(link.src().deviceId(), link.src().port(), mcastIp,
-                                    assignedVlan(link.src().deviceId().equals(source.deviceId()) ? source : null));
-                    addFilterToDevice(link.dst().deviceId(), link.dst().port(),
-                                      assignedVlan(null), mcastIp, null);
+                                    mcastUtils.assignedVlan(link.src().deviceId()
+                                                                    .equals(source.deviceId()) ? source : null));
+                    mcastUtils.addFilterToDevice(link.dst().deviceId(), link.dst().port(),
+                                      mcastUtils.assignedVlan(null), mcastIp, null);
                 });
 
                 // Setup mcast role for the transit
@@ -600,7 +644,7 @@
                                                             TRANSIT));
 
                 // Process the egress device
-                addPortToDevice(sink.deviceId(), sink.port(), mcastIp, assignedVlan(null));
+                addPortToDevice(sink.deviceId(), sink.port(), mcastIp, mcastUtils.assignedVlan(null));
                 // Setup mcast role for egress
                 mcastRoleStore.put(new McastStoreKey(mcastIp, sink.deviceId()),
                                    EGRESS);
@@ -633,7 +677,7 @@
                         .stream().findAny().orElse(null);
                 Set<DeviceId> transitDevices = getDevice(mcastIp, TRANSIT);
                 Set<DeviceId> egressDevices = getDevice(mcastIp, EGRESS);
-                ConnectPoint source = getSource(mcastIp);
+                ConnectPoint source = mcastUtils.getSource(mcastIp);
 
                 // Do not proceed if ingress device or source of this group are missing
                 // If sinks are in other leafs, we have ingress, transit, egress, and source
@@ -653,28 +697,50 @@
 
                 // Remove entire transit
                 transitDevices.forEach(transitDevice ->
-                                removeGroupFromDevice(transitDevice, mcastIp, assignedVlan(null)));
+                                removeGroupFromDevice(transitDevice, mcastIp,
+                                                      mcastUtils.assignedVlan(null)));
 
                 // Remove transit-facing ports on the ingress device
                 removeIngressTransitPorts(mcastIp, ingressDevice, source);
 
+                // TODO create a shared procedure with DEVICE_DOWN
                 // Compute mcast tree for the the egress devices
                 Map<DeviceId, List<Path>> mcastTree = computeMcastTree(ingressDevice, egressDevices);
 
-                // Construct a new path for each egress device
+                // We have to verify, if there are egresses without paths
+                Set<DeviceId> notRecovered = Sets.newHashSet();
                 mcastTree.forEach((egressDevice, paths) -> {
-                    // We try to enforce the sinks path on the mcast tree
+                    // Let's check if there is at least a path
                     Optional<Path> mcastPath = getPath(ingressDevice, egressDevice,
                                                        mcastIp, paths);
-                    // If a path is present, let's install it
-                    if (mcastPath.isPresent()) {
-                        installPath(mcastIp, source, mcastPath.get());
-                    } else {
+                    // No paths, we have to try with alternative location
+                    if (!mcastPath.isPresent()) {
+                        notRecovered.add(egressDevice);
+                        // We were not able to find an alternative path for this egress
                         log.warn("Fail to recover egress device {} from link failure {}",
                                  egressDevice, affectedLink);
-                        removeGroupFromDevice(egressDevice, mcastIp, assignedVlan(null));
+                        removeGroupFromDevice(egressDevice, mcastIp,
+                                              mcastUtils.assignedVlan(null));
                     }
                 });
+
+                // Fast path, we can recover all the locations
+                if (notRecovered.isEmpty()) {
+                    // Construct a new path for each egress device
+                    mcastTree.forEach((egressDevice, paths) -> {
+                        // We try to enforce the sinks path on the mcast tree
+                        Optional<Path> mcastPath = getPath(ingressDevice, egressDevice,
+                                                           mcastIp, paths);
+                        // If a path is present, let's install it
+                        if (mcastPath.isPresent()) {
+                            installPath(mcastIp, source, mcastPath.get());
+                        }
+                    });
+                } else {
+                    // Let's try to recover using alternate
+                    recoverSinks(egressDevices, notRecovered, mcastIp,
+                                 ingressDevice, source, true);
+                }
             });
         } finally {
             mcastUnlock();
@@ -701,7 +767,7 @@
                         .stream().findAny().orElse(null);
                 Set<DeviceId> transitDevices = getDevice(mcastIp, TRANSIT);
                 Set<DeviceId> egressDevices = getDevice(mcastIp, EGRESS);
-                ConnectPoint source = getSource(mcastIp);
+                ConnectPoint source = mcastUtils.getSource(mcastIp);
 
                 // Do not proceed if ingress device or source of this group are missing
                 // If sinks are in other leafs, we have ingress, transit, egress, and source
@@ -713,7 +779,7 @@
                 }
 
                 // Verify leadership on the operation
-                if (!isLeader(source)) {
+                if (!mcastUtils.isLeader(source)) {
                     log.debug("Skip {} due to lack of leadership", mcastIp);
                     return;
                 }
@@ -722,17 +788,19 @@
                 if (!transitDevices.isEmpty()) {
                     // Remove entire transit
                     transitDevices.forEach(transitDevice ->
-                                    removeGroupFromDevice(transitDevice, mcastIp, assignedVlan(null)));
+                                    removeGroupFromDevice(transitDevice, mcastIp,
+                                                          mcastUtils.assignedVlan(null)));
                 }
                 // If the ingress is down
                 if (ingressDevice.equals(deviceDown)) {
                     // Remove entire ingress
-                    removeGroupFromDevice(ingressDevice, mcastIp, assignedVlan(source));
+                    removeGroupFromDevice(ingressDevice, mcastIp, mcastUtils.assignedVlan(source));
                     // If other sinks different from the ingress exist
                     if (!egressDevices.isEmpty()) {
                         // Remove all the remaining egress
                         egressDevices.forEach(
-                                egressDevice -> removeGroupFromDevice(egressDevice, mcastIp, assignedVlan(null))
+                                egressDevice -> removeGroupFromDevice(egressDevice, mcastIp,
+                                                                      mcastUtils.assignedVlan(null))
                         );
                     }
                 } else {
@@ -743,7 +811,7 @@
                     // One of the egress device is down
                     if (egressDevices.contains(deviceDown)) {
                         // Remove entire device down
-                        removeGroupFromDevice(deviceDown, mcastIp, assignedVlan(null));
+                        removeGroupFromDevice(deviceDown, mcastIp, mcastUtils.assignedVlan(null));
                         // Remove the device down from egress
                         egressDevices.remove(deviceDown);
                         // If there are no more egress and ingress does not have sinks
@@ -756,21 +824,39 @@
                     // Compute mcast tree for the the egress devices
                     Map<DeviceId, List<Path>> mcastTree = computeMcastTree(ingressDevice, egressDevices);
 
-                    // Construct a new path for each egress device
+                    // We have to verify, if there are egresses without paths
+                    Set<DeviceId> notRecovered = Sets.newHashSet();
                     mcastTree.forEach((egressDevice, paths) -> {
+                        // Let's check if there is at least a path
                         Optional<Path> mcastPath = getPath(ingressDevice, egressDevice,
-                                                           mcastIp, null);
-                        // If there is a new path
-                        if (mcastPath.isPresent()) {
-                            // Let's install the new mcast path for this egress
-                            installPath(mcastIp, source, mcastPath.get());
-                        } else {
+                                                           mcastIp, paths);
+                        // No paths, we have to try with alternative location
+                        if (!mcastPath.isPresent()) {
+                            notRecovered.add(egressDevice);
                             // We were not able to find an alternative path for this egress
                             log.warn("Fail to recover egress device {} from device down {}",
                                      egressDevice, deviceDown);
-                            removeGroupFromDevice(egressDevice, mcastIp, assignedVlan(null));
+                            removeGroupFromDevice(egressDevice, mcastIp, mcastUtils.assignedVlan(null));
                         }
                     });
+
+                    // Fast path, we can recover all the locations
+                    if (notRecovered.isEmpty()) {
+                        // Construct a new path for each egress device
+                        mcastTree.forEach((egressDevice, paths) -> {
+                            // We try to enforce the sinks path on the mcast tree
+                            Optional<Path> mcastPath = getPath(ingressDevice, egressDevice,
+                                                               mcastIp, paths);
+                            // If a path is present, let's install it
+                            if (mcastPath.isPresent()) {
+                                installPath(mcastIp, source, mcastPath.get());
+                            }
+                        });
+                    } else {
+                        // Let's try to recover using alternate
+                        recoverSinks(egressDevices, notRecovered, mcastIp,
+                                     ingressDevice, source, false);
+                    }
                 }
             });
         } finally {
@@ -779,6 +865,187 @@
     }
 
     /**
+     * Try to recover sinks using alternate locations.
+     *
+     * @param egressDevices the original egress devices
+     * @param notRecovered the devices not recovered
+     * @param mcastIp the group address
+     * @param ingressDevice the ingress device
+     * @param source the source connect point
+     * @param isLinkFailure true if it is a link failure, otherwise false
+     */
+    private void recoverSinks(Set<DeviceId> egressDevices, Set<DeviceId> notRecovered,
+                              IpAddress mcastIp, DeviceId ingressDevice, ConnectPoint source,
+                              boolean isLinkFailure) {
+        // Recovered devices
+        Set<DeviceId> recovered = Sets.difference(egressDevices, notRecovered);
+        // Total affected sinks
+        Set<ConnectPoint> totalAffectedSinks = Sets.newHashSet();
+        // Total sinks
+        Set<ConnectPoint> totalSinks = Sets.newHashSet();
+        // Let's compute all the affected sinks and all the sinks
+        notRecovered.forEach(deviceId -> {
+            totalAffectedSinks.addAll(
+                    mcastUtils.getAffectedSinks(deviceId, mcastIp)
+                            .values()
+                            .stream()
+                            .flatMap(Collection::stream)
+                            .filter(connectPoint -> connectPoint.deviceId().equals(deviceId))
+                            .collect(Collectors.toSet())
+            );
+            totalSinks.addAll(
+                    mcastUtils.getAffectedSinks(deviceId, mcastIp)
+                            .values()
+                            .stream()
+                            .flatMap(Collection::stream)
+                            .collect(Collectors.toSet())
+            );
+        });
+
+        // Sinks to be added
+        Set<ConnectPoint> sinksToBeAdded = Sets.difference(totalSinks, totalAffectedSinks);
+        // New egress devices, filtering out the source
+        Set<DeviceId> newEgressDevice = sinksToBeAdded.stream()
+                .map(ConnectPoint::deviceId)
+                .collect(Collectors.toSet());
+        // Let's add the devices recovered from the previous round
+        newEgressDevice.addAll(recovered);
+        // Let's do a copy of the new egresses and filter out the source
+        Set<DeviceId> copyNewEgressDevice = ImmutableSet.copyOf(newEgressDevice);
+        newEgressDevice = newEgressDevice.stream()
+                .filter(deviceId -> !deviceId.equals(ingressDevice))
+                .collect(Collectors.toSet());
+
+        // Re-compute mcast tree for the the egress devices
+        Map<DeviceId, List<Path>> mcastTree = computeMcastTree(ingressDevice, newEgressDevice);
+        // if the source was originally in the new locations, add new sinks
+        if (copyNewEgressDevice.contains(ingressDevice)) {
+            sinksToBeAdded.stream()
+                    .filter(connectPoint -> connectPoint.deviceId().equals(ingressDevice))
+                    .forEach(sink -> processSinkAddedInternal(source, sink, mcastIp, ImmutableList.of()));
+        }
+
+        // Construct a new path for each egress device
+        mcastTree.forEach((egressDevice, paths) -> {
+            // We try to enforce the sinks path on the mcast tree
+            Optional<Path> mcastPath = getPath(ingressDevice, egressDevice,
+                                               mcastIp, paths);
+            // If a path is present, let's install it
+            if (mcastPath.isPresent()) {
+                // Using recovery procedure
+                if (recovered.contains(egressDevice)) {
+                    installPath(mcastIp, source, mcastPath.get());
+                } else {
+                    // otherwise we need to threat as new sink
+                    sinksToBeAdded.stream()
+                            .filter(connectPoint -> connectPoint.deviceId().equals(egressDevice))
+                            .forEach(sink -> processSinkAddedInternal(source, sink, mcastIp, paths));
+                }
+            } else {
+                // We were not able to find an alternative path for this egress
+                log.warn("Fail to recover egress device {} from {} failure",
+                         egressDevice, isLinkFailure ? "Link" : "Device");
+                removeGroupFromDevice(egressDevice, mcastIp, mcastUtils.assignedVlan(null));
+            }
+        });
+
+    }
+
+    /**
+     * Process new locations and return the set of sinks to be added
+     * in the context of the recovery.
+     *
+     * @param sinks the remaining locations
+     * @return the set of the sinks to be processed
+     */
+    private Set<ConnectPoint> processSinksToBeRecovered(IpAddress mcastIp,
+                                                        Map<HostId, Set<ConnectPoint>> sinks) {
+        // Iterate over the sinks in order to build the set
+        // of the connect points to be served by this group
+        final Set<ConnectPoint> sinksToBeProcessed = Sets.newHashSet();
+        sinks.forEach((hostId, connectPoints) -> {
+            // If it has more than 1 locations
+            if (connectPoints.size() > 1 || connectPoints.size() == 0) {
+                log.debug("Skip {} since sink {} has {} locations",
+                         mcastIp, hostId, connectPoints.size());
+                return;
+            }
+            sinksToBeProcessed.add(connectPoints.stream()
+                                           .findFirst().orElseGet(null));
+        });
+        return sinksToBeProcessed;
+    }
+
+    /**
+     * Process all the sinks related to a mcast group and return
+     * the ones to be processed.
+     *
+     * @param source the source connect point
+     * @param mcastIp the group address
+     * @param sinks the sinks to be evaluated
+     * @return the set of the sinks to be processed
+     */
+    private Set<ConnectPoint> processSinksToBeAdded(ConnectPoint source, IpAddress mcastIp,
+                                                    Map<HostId, Set<ConnectPoint>> sinks) {
+        // Iterate over the sinks in order to build the set
+        // of the connect points to be served by this group
+        final Set<ConnectPoint> sinksToBeProcessed = Sets.newHashSet();
+        sinks.forEach(((hostId, connectPoints) -> {
+            // If it has more than 2 locations
+            if (connectPoints.size() > 2 || connectPoints.size() == 0) {
+                log.debug("Skip {} since sink {} has {} locations",
+                         mcastIp, hostId, connectPoints.size());
+                return;
+            }
+            // If it has one location, just use it
+            if (connectPoints.size() == 1) {
+                sinksToBeProcessed.add(connectPoints.stream()
+                                               .findFirst().orElseGet(null));
+                return;
+            }
+            // We prefer to reuse existing flows
+            ConnectPoint sinkToBeProcessed = connectPoints.stream()
+                    .filter(connectPoint -> {
+                        // Let's check if we are already serving that location
+                        McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, connectPoint.deviceId());
+                        if (!mcastNextObjStore.containsKey(mcastStoreKey)) {
+                            return false;
+                        }
+                        // Get next and check with the port
+                        NextObjective mcastNext = mcastNextObjStore.get(mcastStoreKey).value();
+                        return mcastUtils.getPorts(mcastNext.next()).contains(connectPoint.port());
+                    })
+                    .findFirst().orElse(null);
+            if (sinkToBeProcessed != null) {
+                sinksToBeProcessed.add(sinkToBeProcessed);
+                return;
+            }
+            // Otherwise we prefer to reuse existing egresses
+            Set<DeviceId> egresses = getDevice(mcastIp, EGRESS);
+            sinkToBeProcessed = connectPoints.stream()
+                    .filter(egresses::contains)
+                    .findFirst().orElse(null);
+            if (sinkToBeProcessed != null) {
+                sinksToBeProcessed.add(sinkToBeProcessed);
+                return;
+            }
+            // Otherwise we prefer a location co-located with the source (if it exists)
+            sinkToBeProcessed = connectPoints.stream()
+                    .filter(connectPoint -> connectPoint.deviceId().equals(source.deviceId()))
+                    .findFirst().orElse(null);
+            if (sinkToBeProcessed != null) {
+                sinksToBeProcessed.add(sinkToBeProcessed);
+                return;
+            }
+            // Finally, we randomly pick a new location
+            sinksToBeProcessed.add(connectPoints.stream()
+                                           .findFirst().orElseGet(null));
+        }));
+        // We have done, return the set
+        return sinksToBeProcessed;
+    }
+
+    /**
      * Utility method to remove all the ingress transit ports.
      *
      * @param mcastIp the group ip
@@ -791,7 +1058,7 @@
         ingressTransitPorts.forEach(ingressTransitPort -> {
             if (ingressTransitPort != null) {
                 boolean isLast = removePortFromDevice(ingressDevice, ingressTransitPort,
-                                                      mcastIp, assignedVlan(source));
+                                                      mcastIp, mcastUtils.assignedVlan(source));
                 if (isLast) {
                     mcastRoleStore.remove(new McastStoreKey(mcastIp, ingressDevice));
                 }
@@ -800,43 +1067,6 @@
     }
 
     /**
-     * Adds filtering objective for given device and port.
-     *
-     * @param deviceId device ID
-     * @param port ingress port number
-     * @param assignedVlan assigned VLAN ID
-     */
-    private void addFilterToDevice(DeviceId deviceId, PortNumber port,
-                                   VlanId assignedVlan, IpAddress mcastIp, McastRole mcastRole) {
-        // Do nothing if the port is configured as suppressed
-        ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
-        SegmentRoutingAppConfig appConfig = srManager.cfgService
-                .getConfig(srManager.appId(), SegmentRoutingAppConfig.class);
-        if (appConfig != null && appConfig.suppressSubnet().contains(connectPoint)) {
-            log.info("Ignore suppressed port {}", connectPoint);
-            return;
-        }
-
-        MacAddress routerMac;
-        try {
-            routerMac = srManager.deviceConfiguration().getDeviceMac(deviceId);
-        } catch (DeviceConfigNotFoundException dcnfe) {
-            log.warn("Fail to push filtering objective since device is not configured. Abort");
-            return;
-        }
-
-        FilteringObjective.Builder filtObjBuilder =
-                filterObjBuilder(port, assignedVlan, mcastIp, routerMac, mcastRole);
-        ObjectiveContext context = new DefaultObjectiveContext(
-                (objective) -> log.debug("Successfully add filter on {}/{}, vlan {}",
-                        deviceId, port.toLong(), assignedVlan),
-                (objective, error) ->
-                        log.warn("Failed to add filter on {}/{}, vlan {}: {}",
-                                deviceId, port.toLong(), assignedVlan, error));
-        srManager.flowObjectiveService.filter(deviceId, filtObjBuilder.add(context));
-    }
-
-    /**
      * Adds a port to given multicast group on given device. This involves the
      * update of L3 multicast group and multicast routing table entry.
      *
@@ -846,7 +1076,7 @@
      * @param assignedVlan assigned VLAN ID
      */
     private void addPortToDevice(DeviceId deviceId, PortNumber port,
-            IpAddress mcastIp, VlanId assignedVlan) {
+                                 IpAddress mcastIp, VlanId assignedVlan) {
         McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, deviceId);
         ImmutableSet.Builder<PortNumber> portBuilder = ImmutableSet.builder();
         NextObjective newNextObj;
@@ -854,7 +1084,7 @@
             // First time someone request this mcast group via this device
             portBuilder.add(port);
             // New nextObj
-            newNextObj = nextObjBuilder(mcastIp, assignedVlan,
+            newNextObj = mcastUtils.nextObjBuilder(mcastIp, assignedVlan,
                                         portBuilder.build(), null).add();
             // Store the new port
             mcastNextObjStore.put(mcastStoreKey, newNextObj);
@@ -862,7 +1092,7 @@
             // This device already serves some subscribers of this mcast group
             NextObjective nextObj = mcastNextObjStore.get(mcastStoreKey).value();
             // Stop if the port is already in the nextobj
-            Set<PortNumber> existingPorts = getPorts(nextObj.next());
+            Set<PortNumber> existingPorts = mcastUtils.getPorts(nextObj.next());
             if (existingPorts.contains(port)) {
                 log.info("NextObj for {}/{} already exists. Abort", deviceId, port);
                 return;
@@ -870,14 +1100,14 @@
             // Let's add the port and reuse the previous one
             portBuilder.addAll(existingPorts).add(port);
             // Reuse previous nextObj
-            newNextObj = nextObjBuilder(mcastIp, assignedVlan,
+            newNextObj = mcastUtils.nextObjBuilder(mcastIp, assignedVlan,
                                         portBuilder.build(), nextObj.id()).addToExisting();
             // Store the final next objective and send only the difference to the driver
             mcastNextObjStore.put(mcastStoreKey, newNextObj);
             // Add just the new port
             portBuilder = ImmutableSet.builder();
             portBuilder.add(port);
-            newNextObj = nextObjBuilder(mcastIp, assignedVlan,
+            newNextObj = mcastUtils.nextObjBuilder(mcastIp, assignedVlan,
                                         portBuilder.build(), nextObj.id()).addToExisting();
         }
         // Create, store and apply the new nextObj and fwdObj
@@ -887,8 +1117,8 @@
                 (objective, error) ->
                         log.warn("Failed to add {} on {}/{}, vlan {}: {}",
                                 mcastIp, deviceId, port.toLong(), assignedVlan, error));
-        ForwardingObjective fwdObj =
-                fwdObjBuilder(mcastIp, assignedVlan, newNextObj.id()).add(context);
+        ForwardingObjective fwdObj = mcastUtils.fwdObjBuilder(mcastIp, assignedVlan,
+                                                              newNextObj.id()).add(context);
         srManager.flowObjectiveService.next(deviceId, newNextObj);
         srManager.flowObjectiveService.forward(deviceId, fwdObj);
     }
@@ -905,7 +1135,7 @@
      * @return true if this is the last sink on this device
      */
     private boolean removePortFromDevice(DeviceId deviceId, PortNumber port,
-            IpAddress mcastIp, VlanId assignedVlan) {
+                                         IpAddress mcastIp, VlanId assignedVlan) {
         McastStoreKey mcastStoreKey =
                 new McastStoreKey(mcastIp, deviceId);
         // This device is not serving this multicast group
@@ -915,7 +1145,7 @@
         }
         NextObjective nextObj = mcastNextObjStore.get(mcastStoreKey).value();
 
-        Set<PortNumber> existingPorts = getPorts(nextObj.next());
+        Set<PortNumber> existingPorts = mcastUtils.getPorts(nextObj.next());
         // This port does not serve this multicast group
         if (!existingPorts.contains(port)) {
             log.warn("{} is not serving {} on port {}. Abort.", deviceId, mcastIp, port);
@@ -939,7 +1169,7 @@
                     (objective, error) ->
                             log.warn("Failed to remove {} on {}/{}, vlan {}: {}",
                                     mcastIp, deviceId, port.toLong(), assignedVlan, error));
-            fwdObj = fwdObjBuilder(mcastIp, assignedVlan, nextObj.id()).remove(context);
+            fwdObj = mcastUtils.fwdObjBuilder(mcastIp, assignedVlan, nextObj.id()).remove(context);
             mcastNextObjStore.remove(mcastStoreKey);
         } else {
             // If this is not the last sink, update flows and groups
@@ -950,13 +1180,13 @@
                             log.warn("Failed to update {} on {}/{}, vlan {}: {}",
                                     mcastIp, deviceId, port.toLong(), assignedVlan, error));
             // Here we store the next objective with the remaining port
-            newNextObj = nextObjBuilder(mcastIp, assignedVlan,
+            newNextObj = mcastUtils.nextObjBuilder(mcastIp, assignedVlan,
                                         existingPorts, nextObj.id()).removeFromExisting();
-            fwdObj = fwdObjBuilder(mcastIp, assignedVlan, newNextObj.id()).add(context);
+            fwdObj = mcastUtils.fwdObjBuilder(mcastIp, assignedVlan, newNextObj.id()).add(context);
             mcastNextObjStore.put(mcastStoreKey, newNextObj);
         }
         // Let's modify the next objective removing the bucket
-        newNextObj = nextObjBuilder(mcastIp, assignedVlan,
+        newNextObj = mcastUtils.nextObjBuilder(mcastIp, assignedVlan,
                                     ImmutableSet.of(port), nextObj.id()).removeFromExisting();
         srManager.flowObjectiveService.next(deviceId, newNextObj);
         srManager.flowObjectiveService.forward(deviceId, fwdObj);
@@ -971,7 +1201,7 @@
      * @param assignedVlan assigned VLAN ID
      */
     private void removeGroupFromDevice(DeviceId deviceId, IpAddress mcastIp,
-            VlanId assignedVlan) {
+                                       VlanId assignedVlan) {
         McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, deviceId);
         // This device is not serving this multicast group
         if (!mcastNextObjStore.containsKey(mcastStoreKey)) {
@@ -988,7 +1218,7 @@
                 (objective, error) ->
                         log.warn("Failed to remove {} on {}, vlan {}: {}",
                                 mcastIp, deviceId, assignedVlan, error));
-        ForwardingObjective fwdObj = fwdObjBuilder(mcastIp, assignedVlan, nextObj.id()).remove(context);
+        ForwardingObjective fwdObj = mcastUtils.fwdObjBuilder(mcastIp, assignedVlan, nextObj.id()).remove(context);
         srManager.flowObjectiveService.forward(deviceId, fwdObj);
         mcastNextObjStore.remove(mcastStoreKey);
         mcastRoleStore.remove(mcastStoreKey);
@@ -1006,9 +1236,9 @@
         // and a new filter objective on the destination port
         links.forEach(link -> {
             addPortToDevice(link.src().deviceId(), link.src().port(), mcastIp,
-                            assignedVlan(link.src().deviceId().equals(source.deviceId()) ? source : null));
-            addFilterToDevice(link.dst().deviceId(), link.dst().port(),
-                              assignedVlan(null), mcastIp, null);
+                            mcastUtils.assignedVlan(link.src().deviceId().equals(source.deviceId()) ? source : null));
+            mcastUtils.addFilterToDevice(link.dst().deviceId(), link.dst().port(),
+                              mcastUtils.assignedVlan(null), mcastIp, null);
         });
 
         // Setup mcast role for the transit
@@ -1019,137 +1249,6 @@
     }
 
     /**
-     * Creates a next objective builder for multicast.
-     *
-     * @param mcastIp multicast group
-     * @param assignedVlan assigned VLAN ID
-     * @param outPorts set of output port numbers
-     * @return next objective builder
-     */
-    private NextObjective.Builder nextObjBuilder(IpAddress mcastIp,
-            VlanId assignedVlan, Set<PortNumber> outPorts, Integer nextId) {
-        // If nextId is null allocate a new one
-        if (nextId == null) {
-            nextId = srManager.flowObjectiveService.allocateNextId();
-        }
-
-        TrafficSelector metadata =
-                DefaultTrafficSelector.builder()
-                        .matchVlanId(assignedVlan)
-                        .matchIPDst(mcastIp.toIpPrefix())
-                        .build();
-
-        NextObjective.Builder nextObjBuilder = DefaultNextObjective
-                .builder().withId(nextId)
-                .withType(NextObjective.Type.BROADCAST).fromApp(srManager.appId())
-                .withMeta(metadata);
-
-        outPorts.forEach(port -> {
-            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-            if (egressVlan().equals(VlanId.NONE)) {
-                tBuilder.popVlan();
-            }
-            tBuilder.setOutput(port);
-            nextObjBuilder.addTreatment(tBuilder.build());
-        });
-
-        return nextObjBuilder;
-    }
-
-    /**
-     * Creates a forwarding objective builder for multicast.
-     *
-     * @param mcastIp multicast group
-     * @param assignedVlan assigned VLAN ID
-     * @param nextId next ID of the L3 multicast group
-     * @return forwarding objective builder
-     */
-    private ForwardingObjective.Builder fwdObjBuilder(IpAddress mcastIp,
-            VlanId assignedVlan, int nextId) {
-        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
-        IpPrefix mcastPrefix = mcastIp.toIpPrefix();
-
-        if (mcastIp.isIp4()) {
-            sbuilder.matchEthType(Ethernet.TYPE_IPV4);
-            sbuilder.matchIPDst(mcastPrefix);
-        } else {
-            sbuilder.matchEthType(Ethernet.TYPE_IPV6);
-            sbuilder.matchIPv6Dst(mcastPrefix);
-        }
-
-
-        TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
-        metabuilder.matchVlanId(assignedVlan);
-
-        ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder();
-        fwdBuilder.withSelector(sbuilder.build())
-                .withMeta(metabuilder.build())
-                .nextStep(nextId)
-                .withFlag(ForwardingObjective.Flag.SPECIFIC)
-                .fromApp(srManager.appId())
-                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
-        return fwdBuilder;
-    }
-
-    /**
-     * Creates a filtering objective builder for multicast.
-     *
-     * @param ingressPort ingress port of the multicast stream
-     * @param assignedVlan assigned VLAN ID
-     * @param routerMac router MAC. This is carried in metadata and used from some switches that
-     *                  need to put unicast entry before multicast entry in TMAC table.
-     * @return filtering objective builder
-     */
-    private FilteringObjective.Builder filterObjBuilder(PortNumber ingressPort,
-            VlanId assignedVlan, IpAddress mcastIp, MacAddress routerMac, McastRole mcastRole) {
-        FilteringObjective.Builder filtBuilder = DefaultFilteringObjective.builder();
-        // Let's add the in port matching and the priority
-        filtBuilder.withKey(Criteria.matchInPort(ingressPort))
-                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
-        // According to the mcast role we match on the proper vlan
-        // If the role is null we are on the transit or on the egress
-        if (mcastRole == null) {
-            filtBuilder.addCondition(Criteria.matchVlanId(egressVlan()));
-        } else {
-            filtBuilder.addCondition(Criteria.matchVlanId(ingressVlan()));
-        }
-        // According to the IP type we set the proper match on the mac address
-        if (mcastIp.isIp4()) {
-            filtBuilder.addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST,
-                    MacAddress.IPV4_MULTICAST_MASK));
-        } else {
-            filtBuilder.addCondition(Criteria.matchEthDstMasked(MacAddress.IPV6_MULTICAST,
-                     MacAddress.IPV6_MULTICAST_MASK));
-        }
-        // We finally build the meta treatment
-        TrafficTreatment tt = DefaultTrafficTreatment.builder()
-                .pushVlan().setVlanId(assignedVlan)
-                .setEthDst(routerMac)
-                .build();
-        filtBuilder.withMeta(tt);
-        // Done, we return a permit filtering objective
-        return filtBuilder.permit().fromApp(srManager.appId());
-    }
-
-    /**
-     * Gets output ports information from treatments.
-     *
-     * @param treatments collection of traffic treatments
-     * @return set of output port numbers
-     */
-    private Set<PortNumber> getPorts(Collection<TrafficTreatment> treatments) {
-        ImmutableSet.Builder<PortNumber> builder = ImmutableSet.builder();
-        treatments.forEach(treatment -> {
-            treatment.allInstructions().stream()
-                    .filter(instr -> instr instanceof OutputInstruction)
-                    .forEach(instr -> {
-                        builder.add(((OutputInstruction) instr).port());
-                    });
-        });
-        return builder.build();
-    }
-
-    /**
      * Go through all the paths, looking for shared links to be used
      * in the final path computation.
      *
@@ -1167,13 +1266,13 @@
         // Verify the source can still reach all the egresses
         for (DeviceId egress : egresses) {
             // From the source we cannot reach all the sinks
-            // just continue and let's figured out after
+            // just continue and let's figure out after
             currentPaths = availablePaths.get(egress);
             if (currentPaths.isEmpty()) {
                 continue;
             }
             // Get the length of the first one available,
-            // update the min length and save the paths
+            // update the min length
             length = currentPaths.get(0).links().size();
             if (length < minLength) {
                 minLength = length;
@@ -1189,7 +1288,7 @@
         Set<Link> sharedLinks = Sets.newHashSet();
         Set<Link> currentSharedLinks;
         Set<Link> currentLinks;
-        DeviceId deviceToRemove = null;
+        DeviceId egressToRemove = null;
         // Let's find out the shared links
         while (index < minLength) {
             // Initialize the intersection with the paths related to the first egress
@@ -1215,7 +1314,7 @@
                 // If there are no shared paths exit and record the device to remove
                 // we have to retry with a subset of sinks
                 if (currentSharedLinks.isEmpty()) {
-                    deviceToRemove = egress;
+                    egressToRemove = egress;
                     index = minLength;
                     break;
                 }
@@ -1226,8 +1325,8 @@
         // If the shared links is empty and there are egress
         // let's retry another time with less sinks, we can
         // still build optimal subtrees
-        if (sharedLinks.isEmpty() && egresses.size() > 1 && deviceToRemove != null) {
-            egresses.remove(deviceToRemove);
+        if (sharedLinks.isEmpty() && egresses.size() > 1 && egressToRemove != null) {
+            egresses.remove(egressToRemove);
             sharedLinks = exploreMcastTree(egresses, availablePaths);
         }
         return sharedLinks;
@@ -1241,18 +1340,20 @@
      * @return the computed Mcast tree
      */
     private Map<ConnectPoint, List<Path>> computeSinkMcastTree(DeviceId source,
-                                                                Set<ConnectPoint> sinks) {
+                                                               Set<ConnectPoint> sinks) {
         // Get the egress devices, remove source from the egress if present
         Set<DeviceId> egresses = sinks.stream()
                 .map(ConnectPoint::deviceId)
                 .filter(deviceId -> !deviceId.equals(source))
                 .collect(Collectors.toSet());
         Map<DeviceId, List<Path>> mcastTree = computeMcastTree(source, egresses);
-        // Build final tree nad return it as it is
+        // Build final tree and return it as it is
         final Map<ConnectPoint, List<Path>> finalTree = Maps.newHashMap();
-        mcastTree.forEach((egress, paths) ->
-            sinks.stream().filter(sink -> sink.deviceId().equals(egress))
-                    .forEach(sink -> finalTree.put(sink, mcastTree.get(sink.deviceId()))));
+        // We need to put back the source if it was originally present
+        sinks.forEach(sink -> {
+            List<Path> sinkPaths = mcastTree.get(sink.deviceId());
+            finalTree.put(sink, sinkPaths != null ? sinkPaths : ImmutableList.of());
+        });
         return finalTree;
     }
 
@@ -1356,7 +1457,7 @@
                 }
                 // Get the output ports on the next
                 nextObj = mcastNextObjStore.get(mcastStoreKey).value();
-                existingPorts = getPorts(nextObj.next());
+                existingPorts = mcastUtils.getPorts(nextObj.next());
                 // And the src port on the link
                 srcPort = hop.src().port();
                 // the src port is not used as output, exit
@@ -1412,37 +1513,6 @@
     }
 
     /**
-     * Gets source connect point of given multicast group.
-     *
-     * @param mcastIp multicast IP
-     * @return source connect point or null if not found
-     */
-    // FIXME To be addressed with multiple sources support
-    private ConnectPoint getSource(IpAddress mcastIp) {
-        // FIXME we should support different types of routes
-        McastRoute mcastRoute = srManager.multicastRouteService.getRoutes().stream()
-                .filter(mcastRouteInternal -> mcastRouteInternal.group().equals(mcastIp))
-                .findFirst().orElse(null);
-        return mcastRoute == null ? null : srManager.multicastRouteService.sources(mcastRoute)
-                .stream()
-                .findFirst().orElse(null);
-    }
-    /**
-     * Gets sinks of given multicast group.
-     *
-     * @param mcastIp multicast IP
-     * @return set of sinks or empty set if not found
-     */
-    private Set<ConnectPoint> getSinks(IpAddress mcastIp) {
-        // FIXME we should support different types of routes
-        McastRoute mcastRoute = srManager.multicastRouteService.getRoutes().stream()
-                .filter(mcastRouteInternal -> mcastRouteInternal.group().equals(mcastIp))
-                .findFirst().orElse(null);
-        return mcastRoute == null ?
-                Collections.emptySet() : srManager.multicastRouteService.sinks(mcastRoute);
-    }
-
-    /**
      * Gets groups which is affected by the link down event.
      *
      * @param link link going down
@@ -1453,7 +1523,7 @@
         PortNumber port = link.src().port();
         return mcastNextObjStore.entrySet().stream()
                 .filter(entry -> entry.getKey().deviceId().equals(deviceId) &&
-                        getPorts(entry.getValue().value().next()).contains(port))
+                        mcastUtils.getPorts(entry.getValue().value().next()).contains(port))
                 .map(Entry::getKey).map(McastStoreKey::mcastIp)
                 .collect(Collectors.toSet());
     }
@@ -1472,59 +1542,6 @@
     }
 
     /**
-     * Gets ingress VLAN from McastConfig.
-     *
-     * @return ingress VLAN or VlanId.NONE if not configured
-     */
-    private VlanId ingressVlan() {
-        McastConfig mcastConfig =
-                srManager.cfgService.getConfig(coreAppId, McastConfig.class);
-        return (mcastConfig != null) ? mcastConfig.ingressVlan() : VlanId.NONE;
-    }
-
-    /**
-     * Gets egress VLAN from McastConfig.
-     *
-     * @return egress VLAN or VlanId.NONE if not configured
-     */
-    private VlanId egressVlan() {
-        McastConfig mcastConfig =
-                srManager.cfgService.getConfig(coreAppId, McastConfig.class);
-        return (mcastConfig != null) ? mcastConfig.egressVlan() : VlanId.NONE;
-    }
-
-    /**
-     * Gets assigned VLAN according to the value of egress VLAN.
-     * If connect point is specified, try to reuse the assigned VLAN on the connect point.
-     *
-     * @param cp connect point; Can be null if not specified
-     * @return assigned VLAN ID
-     */
-    private VlanId assignedVlan(ConnectPoint cp) {
-        // Use the egressVlan if it is tagged
-        if (!egressVlan().equals(VlanId.NONE)) {
-            return egressVlan();
-        }
-        // Reuse unicast VLAN if the port has subnet configured
-        if (cp != null) {
-            VlanId untaggedVlan = srManager.getInternalVlanId(cp);
-            return (untaggedVlan != null) ? untaggedVlan : INTERNAL_VLAN;
-        }
-        // Use DEFAULT_VLAN if none of the above matches
-        return SegmentRoutingManager.INTERNAL_VLAN;
-    }
-
-    /**
-     * Gets assigned VLAN according to the value in the meta.
-     *
-     * @param nextObjective nextObjective to analyze
-     * @return assigned VLAN ID
-     */
-    private VlanId assignedVlanFromNext(NextObjective nextObjective) {
-        return ((VlanIdCriterion) nextObjective.meta().getCriterion(VLAN_VID)).vlanId();
-    }
-
-    /**
      * Gets the spine-facing port on ingress device of given multicast group.
      *
      * @param mcastIp multicast IP
@@ -1537,7 +1554,7 @@
         if (ingressDevice != null) {
             NextObjective nextObj = mcastNextObjStore
                     .get(new McastStoreKey(mcastIp, ingressDevice)).value();
-            Set<PortNumber> ports = getPorts(nextObj.next());
+            Set<PortNumber> ports = mcastUtils.getPorts(nextObj.next());
             // Let's find out all the ingress-transit ports
             for (PortNumber port : ports) {
                 // Spine-facing port should have no subnet and no xconnect
@@ -1570,7 +1587,7 @@
             if (versionedNextObj != null) {
                 NextObjective nextObj = versionedNextObj.value();
                 // Retrieves all the output ports
-                Set<PortNumber> ports = getPorts(nextObj.next());
+                Set<PortNumber> ports = mcastUtils.getPorts(nextObj.next());
                 // Tries to find at least one port that is not spine-facing
                 for (PortNumber port : ports) {
                     // Spine-facing port should have no subnet and no xconnect
@@ -1586,44 +1603,6 @@
     }
 
     /**
-     * Removes filtering objective for given device and port.
-     *
-     * @param deviceId device ID
-     * @param port ingress port number
-     * @param assignedVlan assigned VLAN ID
-     * @param mcastIp multicast IP address
-     */
-    private void removeFilterToDevice(DeviceId deviceId, PortNumber port,
-                                      VlanId assignedVlan, IpAddress mcastIp, McastRole mcastRole) {
-        // Do nothing if the port is configured as suppressed
-        ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
-        SegmentRoutingAppConfig appConfig = srManager.cfgService
-                .getConfig(srManager.appId(), SegmentRoutingAppConfig.class);
-        if (appConfig != null && appConfig.suppressSubnet().contains(connectPoint)) {
-            log.info("Ignore suppressed port {}", connectPoint);
-            return;
-        }
-
-        MacAddress routerMac;
-        try {
-            routerMac = srManager.deviceConfiguration().getDeviceMac(deviceId);
-        } catch (DeviceConfigNotFoundException dcnfe) {
-            log.warn("Fail to push filtering objective since device is not configured. Abort");
-            return;
-        }
-
-        FilteringObjective.Builder filtObjBuilder =
-                filterObjBuilder(port, assignedVlan, mcastIp, routerMac, mcastRole);
-        ObjectiveContext context = new DefaultObjectiveContext(
-                (objective) -> log.debug("Successfully removed filter on {}/{}, vlan {}",
-                                         deviceId, port.toLong(), assignedVlan),
-                (objective, error) ->
-                        log.warn("Failed to remove filter on {}/{}, vlan {}: {}",
-                                 deviceId, port.toLong(), assignedVlan, error));
-        srManager.flowObjectiveService.filter(deviceId, filtObjBuilder.remove(context));
-    }
-
-    /**
      * Updates filtering objective for given device and port.
      * It is called in general when the mcast config has been
      * changed.
@@ -1647,9 +1626,9 @@
                         .findFirst().orElse(null);
                 if (source.deviceId().equals(deviceId) && source.port().equals(portNum)) {
                     if (install) {
-                        addFilterToDevice(deviceId, portNum, vlanId, mcastRoute.group(), INGRESS);
+                        mcastUtils.addFilterToDevice(deviceId, portNum, vlanId, mcastRoute.group(), INGRESS);
                     } else {
-                        removeFilterToDevice(deviceId, portNum, vlanId, mcastRoute.group(), null);
+                        mcastUtils.removeFilterToDevice(deviceId, portNum, vlanId, mcastRoute.group(), null);
                     }
                 }
             });
@@ -1658,26 +1637,6 @@
         }
     }
 
-    private boolean isLeader(ConnectPoint source) {
-        // Continue only when we have the mastership on the operation
-        if (!srManager.mastershipService.isLocalMaster(source.deviceId())) {
-            // When the source is available we just check the mastership
-            if (srManager.deviceService.isAvailable(source.deviceId())) {
-                return false;
-            }
-            // Fallback with Leadership service
-            // source id is used a topic
-            NodeId leader = srManager.leadershipService.runForLeadership(
-                    source.deviceId().toString()).leaderNodeId();
-            // Verify if this node is the leader
-            if (!srManager.clusterService.getLocalNode().id().equals(leader)) {
-                return false;
-            }
-        }
-        // Done
-        return true;
-    }
-
     /**
      * Performs bucket verification operation for all mcast groups in the devices.
      * Firstly, it verifies that mcast is stable before trying verification operation.
@@ -1710,8 +1669,10 @@
                         Set<DeviceId> transitDevices = getDevice(mcastIp, TRANSIT);
                         Set<DeviceId> egressDevices = getDevice(mcastIp, EGRESS);
                         // Get source and sinks from Mcast Route Service and warn about errors
-                        ConnectPoint source = getSource(mcastIp);
-                        Set<ConnectPoint> sinks = getSinks(mcastIp);
+                        ConnectPoint source = mcastUtils.getSource(mcastIp);
+                        Set<ConnectPoint> sinks = mcastUtils.getSinks(mcastIp).values().stream()
+                                .flatMap(Collection::stream)
+                                .collect(Collectors.toSet());
 
                         // Do not proceed if ingress device or source of this group are missing
                         if (ingressDevice == null || source == null) {
@@ -1750,11 +1711,12 @@
                             if (mcastNextObjStore.containsKey(currentKey)) {
                                 NextObjective currentNext = mcastNextObjStore.get(currentKey).value();
                                 // Get current ports
-                                Set<PortNumber> currentPorts = getPorts(currentNext.next());
+                                Set<PortNumber> currentPorts = mcastUtils.getPorts(currentNext.next());
                                 // Rebuild the next objective
-                                currentNext = nextObjBuilder(
+                                currentNext = mcastUtils.nextObjBuilder(
                                         mcastIp,
-                                        assignedVlan(deviceId.equals(source.deviceId()) ? source : null),
+                                        mcastUtils.assignedVlan(deviceId.equals(source.deviceId()) ?
+                                                                        source : null),
                                         currentPorts,
                                         currentNext.id()
                                 ).verify();
@@ -1807,7 +1769,7 @@
     public Map<ConnectPoint, List<ConnectPoint>> getMcastPaths(IpAddress mcastIp) {
         Map<ConnectPoint, List<ConnectPoint>> mcastPaths = Maps.newHashMap();
         // Get the source
-        ConnectPoint source = getSource(mcastIp);
+        ConnectPoint source = mcastUtils.getSource(mcastIp);
         // Source cannot be null, we don't know the starting point
         if (source != null) {
             // Init steps
@@ -1837,7 +1799,7 @@
             // Build egress connectpoints
             NextObjective nextObjective = mcastNextObjStore.get(mcastStoreKey).value();
             // Get Ports
-            Set<PortNumber> outputPorts = getPorts(nextObjective.next());
+            Set<PortNumber> outputPorts = mcastUtils.getPorts(nextObjective.next());
             // Build relative cps
             ImmutableSet.Builder<ConnectPoint> cpBuilder = ImmutableSet.builder();
             outputPorts.forEach(portNumber -> cpBuilder.add(new ConnectPoint(toVisit, portNumber)));
diff --git a/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java b/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java
new file mode 100644
index 0000000..37f273b
--- /dev/null
+++ b/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java
@@ -0,0 +1,428 @@
+/*
+ * Copyright 2018-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.onosproject.segmentrouting.mcast;
+
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+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.config.basics.McastConfig;
+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.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.DefaultObjectiveContext;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
+import static org.onosproject.segmentrouting.SegmentRoutingManager.INTERNAL_VLAN;
+
+/**
+ * Utility class for Multicast Handler.
+ */
+class McastUtils {
+
+    // Internal reference to the log
+    private final Logger log;
+    // Internal reference to SR Manager
+    private SegmentRoutingManager srManager;
+    // Internal reference to the app id
+    private ApplicationId coreAppId;
+
+    /**
+     * Builds a new McastUtils object.
+     *
+     * @param srManager the SR manager
+     * @param coreAppId the core application id
+     * @param log log reference of the McastHandler
+     */
+    McastUtils(SegmentRoutingManager srManager, ApplicationId coreAppId, Logger log) {
+        this.srManager = srManager;
+        this.coreAppId = coreAppId;
+        this.log = log;
+    }
+
+    /**
+     * Given a connect point define a leader for it.
+     *
+     * @param source the source connect point
+     * @return true if this instance is the leader, otherwise false
+     */
+    boolean isLeader(ConnectPoint source) {
+        // Continue only when we have the mastership on the operation
+        if (!srManager.mastershipService.isLocalMaster(source.deviceId())) {
+            // When the source is available we just check the mastership
+            if (srManager.deviceService.isAvailable(source.deviceId())) {
+                return false;
+            }
+            // Fallback with Leadership service
+            // source id is used a topic
+            NodeId leader = srManager.leadershipService.runForLeadership(
+                    source.deviceId().toString()).leaderNodeId();
+            // Verify if this node is the leader
+            if (!srManager.clusterService.getLocalNode().id().equals(leader)) {
+                return false;
+            }
+        }
+        // Done
+        return true;
+    }
+
+    /**
+     * Get router mac using application config and the connect point.
+     *
+     * @param deviceId the device id
+     * @param port the port number
+     * @return the router mac if the port is configured, otherwise null
+     */
+    private MacAddress getRouterMac(DeviceId deviceId, PortNumber port) {
+        // Do nothing if the port is configured as suppressed
+        ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
+        SegmentRoutingAppConfig appConfig = srManager.cfgService
+                .getConfig(srManager.appId(), SegmentRoutingAppConfig.class);
+        if (appConfig != null && appConfig.suppressSubnet().contains(connectPoint)) {
+            log.info("Ignore suppressed port {}", connectPoint);
+            return MacAddress.NONE;
+        }
+        // Get the router mac using the device configuration
+        MacAddress routerMac;
+        try {
+            routerMac = srManager.deviceConfiguration().getDeviceMac(deviceId);
+        } catch (DeviceConfigNotFoundException dcnfe) {
+            log.warn("Fail to push filtering objective since device is not configured. Abort");
+            return MacAddress.NONE;
+        }
+        return routerMac;
+    }
+
+    /**
+     * Adds filtering objective for given device and port.
+     *
+     * @param deviceId device ID
+     * @param port ingress port number
+     * @param assignedVlan assigned VLAN ID
+     * @param mcastIp the group address
+     * @param mcastRole the role of the device
+     */
+    void addFilterToDevice(DeviceId deviceId, PortNumber port, VlanId assignedVlan,
+                           IpAddress mcastIp, McastRole mcastRole) {
+
+        MacAddress routerMac = getRouterMac(deviceId, port);
+        if (routerMac.equals(MacAddress.NONE)) {
+            return;
+        }
+
+        FilteringObjective.Builder filtObjBuilder = filterObjBuilder(port, assignedVlan, mcastIp,
+                                                                     routerMac, mcastRole);
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("Successfully add filter on {}/{}, vlan {}",
+                                         deviceId, port.toLong(), assignedVlan),
+                (objective, error) ->
+                        log.warn("Failed to add filter on {}/{}, vlan {}: {}",
+                                 deviceId, port.toLong(), assignedVlan, error));
+        srManager.flowObjectiveService.filter(deviceId, filtObjBuilder.add(context));
+    }
+
+    /**
+     * Removes filtering objective for given device and port.
+     *
+     * @param deviceId device ID
+     * @param port ingress port number
+     * @param assignedVlan assigned VLAN ID
+     * @param mcastIp multicast IP address
+     * @param mcastRole the multicast role of the device
+     */
+    void removeFilterToDevice(DeviceId deviceId, PortNumber port, VlanId assignedVlan,
+                              IpAddress mcastIp, McastRole mcastRole) {
+
+        MacAddress routerMac = getRouterMac(deviceId, port);
+        if (routerMac.equals(MacAddress.NONE)) {
+            return;
+        }
+
+        FilteringObjective.Builder filtObjBuilder =
+                filterObjBuilder(port, assignedVlan, mcastIp, routerMac, mcastRole);
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("Successfully removed filter on {}/{}, vlan {}",
+                                         deviceId, port.toLong(), assignedVlan),
+                (objective, error) ->
+                        log.warn("Failed to remove filter on {}/{}, vlan {}: {}",
+                                 deviceId, port.toLong(), assignedVlan, error));
+        srManager.flowObjectiveService.filter(deviceId, filtObjBuilder.remove(context));
+    }
+
+    /**
+     * Gets assigned VLAN according to the value in the meta.
+     *
+     * @param nextObjective nextObjective to analyze
+     * @return assigned VLAN ID
+     */
+    VlanId assignedVlanFromNext(NextObjective nextObjective) {
+        return ((VlanIdCriterion) nextObjective.meta().getCriterion(VLAN_VID)).vlanId();
+    }
+
+    /**
+     * Gets ingress VLAN from McastConfig.
+     *
+     * @return ingress VLAN or VlanId.NONE if not configured
+     */
+    private VlanId ingressVlan() {
+        McastConfig mcastConfig =
+                srManager.cfgService.getConfig(coreAppId, McastConfig.class);
+        return (mcastConfig != null) ? mcastConfig.ingressVlan() : VlanId.NONE;
+    }
+
+    /**
+     * Gets egress VLAN from McastConfig.
+     *
+     * @return egress VLAN or VlanId.NONE if not configured
+     */
+    private VlanId egressVlan() {
+        McastConfig mcastConfig =
+                srManager.cfgService.getConfig(coreAppId, McastConfig.class);
+        return (mcastConfig != null) ? mcastConfig.egressVlan() : VlanId.NONE;
+    }
+
+    /**
+     * Gets assigned VLAN according to the value of egress VLAN.
+     * If connect point is specified, try to reuse the assigned VLAN on the connect point.
+     *
+     * @param cp connect point; Can be null if not specified
+     * @return assigned VLAN ID
+     */
+    VlanId assignedVlan(ConnectPoint cp) {
+        // Use the egressVlan if it is tagged
+        if (!egressVlan().equals(VlanId.NONE)) {
+            return egressVlan();
+        }
+        // Reuse unicast VLAN if the port has subnet configured
+        if (cp != null) {
+            VlanId untaggedVlan = srManager.getInternalVlanId(cp);
+            return (untaggedVlan != null) ? untaggedVlan : INTERNAL_VLAN;
+        }
+        // Use DEFAULT_VLAN if none of the above matches
+        return SegmentRoutingManager.INTERNAL_VLAN;
+    }
+
+    /**
+     * Gets source connect point of given multicast group.
+     *
+     * @param mcastIp multicast IP
+     * @return source connect point or null if not found
+     */
+    // FIXME To be addressed with multiple sources support
+    ConnectPoint getSource(IpAddress mcastIp) {
+        // FIXME we should support different types of routes
+        McastRoute mcastRoute = srManager.multicastRouteService.getRoutes().stream()
+                .filter(mcastRouteInternal -> mcastRouteInternal.group().equals(mcastIp))
+                .findFirst().orElse(null);
+        return mcastRoute == null ? null : srManager.multicastRouteService.sources(mcastRoute)
+                .stream()
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Gets sinks of given multicast group.
+     *
+     * @param mcastIp multicast IP
+     * @return map of sinks or empty map if not found
+     */
+    Map<HostId, Set<ConnectPoint>> getSinks(IpAddress mcastIp) {
+        // FIXME we should support different types of routes
+        McastRoute mcastRoute = srManager.multicastRouteService.getRoutes().stream()
+                .filter(mcastRouteInternal -> mcastRouteInternal.group().equals(mcastIp))
+                .findFirst().orElse(null);
+        return mcastRoute == null ?
+                Collections.emptyMap() :
+                srManager.multicastRouteService.routeData(mcastRoute).sinks();
+    }
+
+    /**
+     * Get sinks affected by this egress device.
+     *
+     * @param egressDevice the egress device
+     * @param mcastIp the mcast ip address
+     * @return the map of the sinks affected
+     */
+    Map<HostId, Set<ConnectPoint>> getAffectedSinks(DeviceId egressDevice,
+                                                            IpAddress mcastIp) {
+        return getSinks(mcastIp).entrySet()
+                .stream()
+                .filter(hostIdSetEntry -> hostIdSetEntry.getValue().stream()
+                        .map(ConnectPoint::deviceId)
+                        .anyMatch(deviceId -> deviceId.equals(egressDevice))
+                ).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+    }
+
+    /**
+     * Creates a next objective builder for multicast.
+     *
+     * @param mcastIp multicast group
+     * @param assignedVlan assigned VLAN ID
+     * @param outPorts set of output port numbers
+     * @param nextId the next id
+     * @return next objective builder
+     */
+    NextObjective.Builder nextObjBuilder(IpAddress mcastIp, VlanId assignedVlan,
+                                         Set<PortNumber> outPorts, Integer nextId) {
+        // If nextId is null allocate a new one
+        if (nextId == null) {
+            nextId = srManager.flowObjectiveService.allocateNextId();
+        }
+        // Build the meta selector with the fwd objective info
+        TrafficSelector metadata =
+                DefaultTrafficSelector.builder()
+                        .matchVlanId(assignedVlan)
+                        .matchIPDst(mcastIp.toIpPrefix())
+                        .build();
+        // Define the nextobjective type
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder().withId(nextId)
+                .withType(NextObjective.Type.BROADCAST)
+                .fromApp(srManager.appId())
+                .withMeta(metadata);
+        // Add the output ports
+        outPorts.forEach(port -> {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            if (egressVlan().equals(VlanId.NONE)) {
+                tBuilder.popVlan();
+            }
+            tBuilder.setOutput(port);
+            nextObjBuilder.addTreatment(tBuilder.build());
+        });
+        // Done return the complete builder
+        return nextObjBuilder;
+    }
+
+    /**
+     * Creates a forwarding objective builder for multicast.
+     *
+     * @param mcastIp multicast group
+     * @param assignedVlan assigned VLAN ID
+     * @param nextId next ID of the L3 multicast group
+     * @return forwarding objective builder
+     */
+    ForwardingObjective.Builder fwdObjBuilder(IpAddress mcastIp,
+                                                      VlanId assignedVlan, int nextId) {
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        // Let's the matching on the group address
+        // TODO SSM support in future
+        if (mcastIp.isIp6()) {
+            sbuilder.matchEthType(Ethernet.TYPE_IPV6);
+            sbuilder.matchIPv6Dst(mcastIp.toIpPrefix());
+        } else {
+            sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+            sbuilder.matchIPDst(mcastIp.toIpPrefix());
+        }
+        // Then build the meta selector
+        TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
+        metabuilder.matchVlanId(assignedVlan);
+        // Finally return the completed builder
+        ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder();
+        fwdBuilder.withSelector(sbuilder.build())
+                .withMeta(metabuilder.build())
+                .nextStep(nextId)
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .fromApp(srManager.appId())
+                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+        return fwdBuilder;
+    }
+
+    /**
+     * Creates a filtering objective builder for multicast.
+     *
+     * @param ingressPort ingress port of the multicast stream
+     * @param assignedVlan assigned VLAN ID
+     * @param mcastIp the group address
+     * @param routerMac router MAC. This is carried in metadata and used from some switches that
+     *                  need to put unicast entry before multicast entry in TMAC table.
+     * @param mcastRole the Multicast role
+     * @return filtering objective builder
+     */
+    private FilteringObjective.Builder filterObjBuilder(PortNumber ingressPort, VlanId assignedVlan,
+                                                IpAddress mcastIp, MacAddress routerMac, McastRole mcastRole) {
+        FilteringObjective.Builder filtBuilder = DefaultFilteringObjective.builder();
+        // Let's add the in port matching and the priority
+        filtBuilder.withKey(Criteria.matchInPort(ingressPort))
+                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+        // According to the mcast role we match on the proper vlan
+        // If the role is null we are on the transit or on the egress
+        if (mcastRole == null) {
+            filtBuilder.addCondition(Criteria.matchVlanId(egressVlan()));
+        } else {
+            filtBuilder.addCondition(Criteria.matchVlanId(ingressVlan()));
+        }
+        // According to the IP type we set the proper match on the mac address
+        if (mcastIp.isIp4()) {
+            filtBuilder.addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST,
+                                                                MacAddress.IPV4_MULTICAST_MASK));
+        } else {
+            filtBuilder.addCondition(Criteria.matchEthDstMasked(MacAddress.IPV6_MULTICAST,
+                                                                MacAddress.IPV6_MULTICAST_MASK));
+        }
+        // We finally build the meta treatment
+        TrafficTreatment tt = DefaultTrafficTreatment.builder()
+                .pushVlan().setVlanId(assignedVlan)
+                .setEthDst(routerMac)
+                .build();
+        filtBuilder.withMeta(tt);
+        // Done, we return a permit filtering objective
+        return filtBuilder.permit().fromApp(srManager.appId());
+    }
+
+    /**
+     * Gets output ports information from treatments.
+     *
+     * @param treatments collection of traffic treatments
+     * @return set of output port numbers
+     */
+    Set<PortNumber> getPorts(Collection<TrafficTreatment> treatments) {
+        ImmutableSet.Builder<PortNumber> builder = ImmutableSet.builder();
+        treatments.forEach(treatment -> treatment.allInstructions().stream()
+                    .filter(instr -> instr instanceof Instructions.OutputInstruction)
+                    .forEach(instr -> builder.add(((Instructions.OutputInstruction) instr).port())));
+        return builder.build();
+    }
+}
