diff --git a/apps/segmentrouting/app/BUCK b/apps/segmentrouting/app/BUCK
new file mode 100644
index 0000000..9674f76
--- /dev/null
+++ b/apps/segmentrouting/app/BUCK
@@ -0,0 +1,22 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:JACKSON',
+    '//lib:KRYO',
+    '//lib:org.apache.karaf.shell.console',
+    '//cli:onos-cli',
+    '//core/common:onos-core-common',
+    '//core/store/serializers:onos-core-serializers',
+    '//incubator/api:onos-incubator-api',
+    '//apps/route-service/api:onos-apps-route-service-api',
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+    '//incubator/api:onos-incubator-api-tests',
+    '//apps/route-service/api:onos-apps-route-service-api-tests',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+)
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/AppConfigHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/AppConfigHandler.java
new file mode 100644
index 0000000..f54ee9e
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/AppConfigHandler.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.segmentrouting;
+
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultObjectiveContext;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Handles Segment Routing app config events.
+ */
+public class AppConfigHandler {
+    private static final Logger log = LoggerFactory.getLogger(AppConfigHandler.class);
+    private final SegmentRoutingManager srManager;
+    private final DeviceService deviceService;
+
+    /**
+     * Constructs Segment Routing App Config Handler.
+     *
+     * @param srManager instance of {@link SegmentRoutingManager}
+     */
+    public AppConfigHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.deviceService = srManager.deviceService;
+    }
+
+    /**
+     * Processes Segment Routing App Config added event.
+     *
+     * @param event network config added event
+     */
+    protected void processAppConfigAdded(NetworkConfigEvent event) {
+        log.info("Processing AppConfig CONFIG_ADDED");
+        SegmentRoutingAppConfig config = (SegmentRoutingAppConfig) event.config().get();
+        deviceService.getAvailableDevices().forEach(device -> {
+            populateVRouter(device.id(), getMacAddresses(config));
+        });
+    }
+
+    /**
+     * Processes Segment Routing App Config updated event.
+     *
+     * @param event network config updated event
+     */
+    protected void processAppConfigUpdated(NetworkConfigEvent event) {
+        log.info("Processing AppConfig CONFIG_UPDATED");
+        SegmentRoutingAppConfig config = (SegmentRoutingAppConfig) event.config().get();
+        SegmentRoutingAppConfig prevConfig = (SegmentRoutingAppConfig) event.prevConfig().get();
+        deviceService.getAvailableDevices().forEach(device -> {
+            Set<MacAddress> macAddresses = new HashSet<>(getMacAddresses(config));
+            Set<MacAddress> prevMacAddresses = new HashSet<>(getMacAddresses(prevConfig));
+            // Avoid removing and re-adding unchanged MAC addresses since
+            // FlowObjective does not guarantee the execution order.
+            Set<MacAddress> sameMacAddresses = new HashSet<>(macAddresses);
+            sameMacAddresses.retainAll(prevMacAddresses);
+            macAddresses.removeAll(sameMacAddresses);
+            prevMacAddresses.removeAll(sameMacAddresses);
+
+            revokeVRouter(device.id(), prevMacAddresses);
+            populateVRouter(device.id(), macAddresses);
+        });
+
+    }
+
+    /**
+     * Processes Segment Routing App Config removed event.
+     *
+     * @param event network config removed event
+     */
+    protected void processAppConfigRemoved(NetworkConfigEvent event) {
+        log.info("Processing AppConfig CONFIG_REMOVED");
+        SegmentRoutingAppConfig prevConfig = (SegmentRoutingAppConfig) event.prevConfig().get();
+        deviceService.getAvailableDevices().forEach(device -> {
+            revokeVRouter(device.id(), getMacAddresses(prevConfig));
+        });
+    }
+
+    /**
+     * Populates initial vRouter rules.
+     *
+     * @param deviceId device ID
+     */
+    public void init(DeviceId deviceId) {
+        SegmentRoutingAppConfig config =
+                srManager.cfgService.getConfig(srManager.appId, SegmentRoutingAppConfig.class);
+        populateVRouter(deviceId, getMacAddresses(config));
+    }
+
+    private void populateVRouter(DeviceId deviceId, Set<MacAddress> pendingAdd) {
+        if (!isEdge(deviceId)) {
+            return;
+        }
+        getVRouterFlowObjBuilders(pendingAdd).forEach(foBuilder -> {
+            ObjectiveContext context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("vRouterMac filter for {} populated", pendingAdd),
+                    (objective, error) ->
+                            log.warn("Failed to populate vRouterMac filter for {}: {}", pendingAdd, error));
+            srManager.flowObjectiveService.filter(deviceId, foBuilder.add(context));
+        });
+    }
+
+    private void revokeVRouter(DeviceId deviceId, Set<MacAddress> pendingRemove) {
+        if (!isEdge(deviceId)) {
+            return;
+        }
+        getVRouterFlowObjBuilders(pendingRemove).forEach(foBuilder -> {
+            ObjectiveContext context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("vRouterMac filter for {} revoked", pendingRemove),
+                    (objective, error) ->
+                            log.warn("Failed to revoke vRouterMac filter for {}: {}", pendingRemove, error));
+            srManager.flowObjectiveService.filter(deviceId, foBuilder.remove(context));
+        });
+    }
+
+    private Set<FilteringObjective.Builder> getVRouterFlowObjBuilders(Set<MacAddress> macAddresses) {
+        ImmutableSet.Builder<FilteringObjective.Builder> setBuilder = ImmutableSet.builder();
+        macAddresses.forEach(macAddress -> {
+            FilteringObjective.Builder fobuilder = DefaultFilteringObjective.builder();
+            fobuilder.withKey(Criteria.matchInPort(PortNumber.ANY))
+                    .addCondition(Criteria.matchEthDst(macAddress))
+                    .permit()
+                    .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
+                    .fromApp(srManager.appId);
+            setBuilder.add(fobuilder);
+        });
+        return setBuilder.build();
+    }
+
+    private Set<MacAddress> getMacAddresses(SegmentRoutingAppConfig config) {
+        if (config == null) {
+            return ImmutableSet.of();
+        }
+        return ImmutableSet.copyOf(config.vRouterMacs());
+    }
+
+    private boolean isEdge(DeviceId deviceId) {
+        try {
+            if (srManager.deviceConfiguration.isEdgeDevice(deviceId)) {
+                return true;
+            }
+        } catch (DeviceConfigNotFoundException e) { }
+        return false;
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/ArpHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
new file mode 100644
index 0000000..b3a0aca
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2015-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;
+
+import org.onlab.packet.ARP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.neighbour.NeighbourMessageContext;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.host.HostService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.neighbour.NeighbourMessageType.REQUEST;
+
+/**
+ * Handler of ARP packets that responses or forwards ARP packets that
+ * are sent to the controller.
+ */
+public class ArpHandler extends SegmentRoutingNeighbourHandler {
+
+    private static Logger log = LoggerFactory.getLogger(ArpHandler.class);
+
+    /**
+     * Creates an ArpHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public ArpHandler(SegmentRoutingManager srManager) {
+        super(srManager);
+    }
+
+    /**
+     * Processes incoming ARP packets.
+     *
+     * If it is an ARP request to router itself or known hosts,
+     * then it sends ARP response.
+     * If it is an ARP request to unknown hosts in its own subnet,
+     * then it flood the ARP request to the ports.
+     * If it is an ARP response, then set a flow rule for the host
+     * and forward any IP packets to the host in the packet buffer to the host.
+     * <p>
+     * Note: We handles all ARP packet in, even for those ARP packets between
+     * hosts in the same subnet.
+     * For an ARP packet with broadcast destination MAC,
+     * some switches pipelines will send it to the controller due to table miss,
+     * other switches will flood the packets directly in the data plane without
+     * packet in.
+     * We can deal with both cases.
+     *
+     * @param pkt incoming ARP packet and context information
+     * @param hostService the host service
+     */
+    public void processPacketIn(NeighbourMessageContext pkt, HostService hostService) {
+
+        SegmentRoutingAppConfig appConfig = srManager.cfgService
+                .getConfig(srManager.appId, SegmentRoutingAppConfig.class);
+        if (appConfig != null && appConfig.suppressSubnet().contains(pkt.inPort())) {
+            // Ignore ARP packets come from suppressed ports
+            pkt.drop();
+            return;
+        }
+
+        if (!validateArpSpa(pkt)) {
+            log.debug("Ignore ARP packet discovered on {} with unexpected src protocol address {}.",
+                    pkt.inPort(), pkt.sender().getIp4Address());
+            pkt.drop();
+            return;
+        }
+
+        if (pkt.type() == REQUEST) {
+            handleArpRequest(pkt, hostService);
+        } else {
+            handleArpReply(pkt, hostService);
+        }
+    }
+
+    private void handleArpRequest(NeighbourMessageContext pkt, HostService hostService) {
+        // ARP request for router. Send ARP reply.
+        if (isArpForRouter(pkt)) {
+            MacAddress targetMac = config.getRouterMacForAGatewayIp(pkt.target().getIp4Address());
+            sendResponse(pkt, targetMac, hostService);
+        } else {
+            // NOTE: Ignore ARP packets except those target for the router
+            //       We will reconsider enabling this when we have host learning support
+            /*
+            Set<Host> hosts = hostService.getHostsByIp(pkt.target());
+            if (hosts.size() > 1) {
+                log.warn("More than one host with the same ip {}", pkt.target());
+            }
+            Host targetHost = hosts.stream().findFirst().orElse(null);
+            // ARP request for known hosts. Send proxy ARP reply on behalf of the target.
+            if (targetHost != null) {
+                pkt.forward(targetHost.location());
+            // ARP request for unknown host in the subnet. Flood in the subnet.
+            } else {
+                flood(pkt);
+            }
+            */
+        }
+    }
+
+    private void handleArpReply(NeighbourMessageContext pkt, HostService hostService) {
+        // ARP reply for router. Process all pending IP packets.
+        if (isArpForRouter(pkt)) {
+            Ip4Address hostIpAddress = pkt.sender().getIp4Address();
+            srManager.ipHandler.forwardPackets(pkt.inPort().deviceId(), hostIpAddress);
+        } else {
+            // NOTE: Ignore ARP packets except those target for the router
+            //       We will reconsider enabling this when we have host learning support
+            /*
+            HostId targetHostId = HostId.hostId(pkt.dstMac(), pkt.vlan());
+            Host targetHost = hostService.getHost(targetHostId);
+            // ARP reply for known hosts. Forward to the host.
+            if (targetHost != null) {
+                pkt.forward(targetHost.location());
+            // ARP reply for unknown host, Flood in the subnet.
+            } else {
+                // Don't flood to non-edge ports
+                if (pkt.vlan().equals(SegmentRoutingManager.INTERNAL_VLAN)) {
+                    return;
+                }
+                flood(pkt);
+            }
+            */
+        }
+    }
+
+    /**
+     * Check if the source protocol address of an ARP packet belongs to the same
+     * subnet configured on the port it is seen.
+     *
+     * @param pkt ARP packet and context information
+     * @return true if the source protocol address belongs to the configured subnet
+     */
+    private boolean validateArpSpa(NeighbourMessageContext pkt) {
+        Ip4Address spa = pkt.sender().getIp4Address();
+        Set<IpPrefix> subnet = config.getPortSubnets(pkt.inPort().deviceId(), pkt.inPort().port())
+                .stream()
+                .filter(ipPrefix -> ipPrefix.isIp4() && ipPrefix.contains(spa))
+                .collect(Collectors.toSet());
+        return !subnet.isEmpty();
+    }
+
+
+    private boolean isArpForRouter(NeighbourMessageContext pkt) {
+        Ip4Address targetProtocolAddress = pkt.target().getIp4Address();
+        Set<IpAddress> gatewayIpAddresses = null;
+        try {
+            if (targetProtocolAddress.equals(config.getRouterIpv4(pkt.inPort().deviceId()))) {
+                return true;
+            }
+            gatewayIpAddresses = config.getPortIPs(pkt.inPort().deviceId());
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting check for router IP in processing arp");
+        }
+        if (gatewayIpAddresses != null &&
+                gatewayIpAddresses.contains(targetProtocolAddress)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sends an APR request for the target IP address to all ports except in-port.
+     *
+     * @param deviceId Switch device ID
+     * @param targetAddress target IP address for ARP
+     * @param inPort in-port
+     */
+    public void sendArpRequest(DeviceId deviceId, IpAddress targetAddress, ConnectPoint inPort) {
+        byte[] senderMacAddress = new byte[MacAddress.MAC_ADDRESS_LENGTH];
+        byte[] senderIpAddress = new byte[Ip4Address.BYTE_LENGTH];
+        /*
+         * Retrieves device info.
+         */
+        if (!getSenderInfo(senderMacAddress, senderIpAddress, deviceId, targetAddress)) {
+            log.warn("Aborting sendArpRequest, we cannot get all the information needed");
+            return;
+        }
+        /*
+         * Creates the request.
+         */
+        Ethernet arpRequest = ARP.buildArpRequest(
+                senderMacAddress,
+                senderIpAddress,
+                targetAddress.toOctets(),
+                VlanId.NO_VID
+        );
+        flood(arpRequest, inPort, targetAddress);
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
new file mode 100644
index 0000000..5baa6a9
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
@@ -0,0 +1,1612 @@
+/*
+ * Copyright 2015-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;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+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.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newScheduledThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Default routing handler that is responsible for route computing and
+ * routing rule population.
+ */
+public class DefaultRoutingHandler {
+    private static final int MAX_CONSTANT_RETRY_ATTEMPTS = 5;
+    private static final long RETRY_INTERVAL_MS = 250L;
+    private static final int RETRY_INTERVAL_SCALE = 1;
+    private static final long STABLITY_THRESHOLD = 10; //secs
+    private static Logger log = LoggerFactory.getLogger(DefaultRoutingHandler.class);
+
+    private SegmentRoutingManager srManager;
+    private RoutingRulePopulator rulePopulator;
+    private HashMap<DeviceId, EcmpShortestPathGraph> currentEcmpSpgMap;
+    private HashMap<DeviceId, EcmpShortestPathGraph> updatedEcmpSpgMap;
+    private DeviceConfiguration config;
+    private final Lock statusLock = new ReentrantLock();
+    private volatile Status populationStatus;
+    private ScheduledExecutorService executorService
+        = newScheduledThreadPool(1, groupedThreads("retryftr", "retry-%d", log));
+    private Instant lastRoutingChange;
+
+    /**
+     * Represents the default routing population status.
+     */
+    public enum Status {
+        // population process is not started yet.
+        IDLE,
+
+        // population process started.
+        STARTED,
+
+        // population process was aborted due to errors, mostly for groups not
+        // found.
+        ABORTED,
+
+        // population process was finished successfully.
+        SUCCEEDED
+    }
+
+    /**
+     * Creates a DefaultRoutingHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public DefaultRoutingHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.rulePopulator = checkNotNull(srManager.routingRulePopulator);
+        this.config = checkNotNull(srManager.deviceConfiguration);
+        this.populationStatus = Status.IDLE;
+        this.currentEcmpSpgMap = Maps.newHashMap();
+    }
+
+    /**
+     * Returns an immutable copy of the current ECMP shortest-path graph as
+     * computed by this controller instance.
+     *
+     * @return immutable copy of the current ECMP graph
+     */
+    public ImmutableMap<DeviceId, EcmpShortestPathGraph> getCurrentEmcpSpgMap() {
+        Builder<DeviceId, EcmpShortestPathGraph> builder = ImmutableMap.builder();
+        currentEcmpSpgMap.entrySet().forEach(entry -> {
+            if (entry.getValue() != null) {
+                builder.put(entry.getKey(), entry.getValue());
+            }
+        });
+        return builder.build();
+    }
+
+    /**
+     * Acquires the lock used when making routing changes.
+     */
+    public void acquireRoutingLock() {
+        statusLock.lock();
+    }
+
+    /**
+     * Releases the lock used when making routing changes.
+     */
+    public void releaseRoutingLock() {
+        statusLock.unlock();
+    }
+
+    /**
+    * Determines if routing in the network has been stable in the last
+    * STABLITY_THRESHOLD seconds, by comparing the current time to the last
+    * routing change timestamp.
+    *
+    * @return true if stable
+    */
+   public boolean isRoutingStable() {
+       long last = (long) (lastRoutingChange.toEpochMilli() / 1000.0);
+       long now = (long) (Instant.now().toEpochMilli() / 1000.0);
+       log.trace("Routing stable since {}s", now - last);
+       return (now - last) > STABLITY_THRESHOLD;
+   }
+
+
+    //////////////////////////////////////
+    //  Route path handling
+    //////////////////////////////////////
+
+    /* The following three methods represent the three major ways in which
+     * route-path handling is triggered in the network
+     *      a) due to configuration change
+     *      b) due to route-added event
+     *      c) due to change in the topology
+     */
+
+    /**
+     * Populates all routing rules to all switches. Typically triggered at
+     * startup or after a configuration event.
+     */
+    public void populateAllRoutingRules() {
+        lastRoutingChange = Instant.now();
+        statusLock.lock();
+        try {
+            if (populationStatus == Status.STARTED) {
+                log.warn("Previous rule population is not finished. Cannot"
+                        + " proceed with populateAllRoutingRules");
+                return;
+            }
+
+            populationStatus = Status.STARTED;
+            rulePopulator.resetCounter();
+            log.info("Starting to populate all routing rules");
+            log.debug("populateAllRoutingRules: populationStatus is STARTED");
+
+            // take a snapshot of the topology
+            updatedEcmpSpgMap = new HashMap<>();
+            Set<EdgePair> edgePairs = new HashSet<>();
+            Set<ArrayList<DeviceId>> routeChanges = new HashSet<>();
+            for (DeviceId dstSw : srManager.deviceConfiguration.getRouters()) {
+                EcmpShortestPathGraph ecmpSpgUpdated =
+                        new EcmpShortestPathGraph(dstSw, srManager);
+                updatedEcmpSpgMap.put(dstSw, ecmpSpgUpdated);
+                DeviceId pairDev = getPairDev(dstSw);
+                if (pairDev != null) {
+                    // pairDev may not be available yet, but we still need to add
+                    ecmpSpgUpdated = new EcmpShortestPathGraph(pairDev, srManager);
+                    updatedEcmpSpgMap.put(pairDev, ecmpSpgUpdated);
+                    edgePairs.add(new EdgePair(dstSw, pairDev));
+                }
+                DeviceId ret = shouldHandleRouting(dstSw);
+                if (ret == null) {
+                    continue;
+                }
+                Set<DeviceId> devsToProcess = Sets.newHashSet(dstSw, ret);
+                // To do a full reroute, assume all routes have changed
+                for (DeviceId dev : devsToProcess) {
+                    for (DeviceId targetSw : srManager.deviceConfiguration.getRouters()) {
+                        if (targetSw.equals(dev)) {
+                            continue;
+                        }
+                        routeChanges.add(Lists.newArrayList(targetSw, dev));
+                    }
+                }
+            }
+
+            if (!redoRouting(routeChanges, edgePairs, null)) {
+                log.debug("populateAllRoutingRules: populationStatus is ABORTED");
+                populationStatus = Status.ABORTED;
+                log.warn("Failed to repopulate all routing rules.");
+                return;
+            }
+
+            log.debug("populateAllRoutingRules: populationStatus is SUCCEEDED");
+            populationStatus = Status.SUCCEEDED;
+            log.info("Completed all routing rule population. Total # of rules pushed : {}",
+                    rulePopulator.getCounter());
+            return;
+        } finally {
+            statusLock.unlock();
+        }
+    }
+
+    /**
+     * Populate rules from all other edge devices to the connect-point(s)
+     * specified for the given subnets.
+     *
+     * @param cpts connect point(s) of the subnets being added
+     * @param subnets subnets being added
+     */
+    // XXX refactor
+    protected void populateSubnet(Set<ConnectPoint> cpts, Set<IpPrefix> subnets) {
+        if (cpts == null || cpts.size() < 1 || cpts.size() > 2) {
+            log.warn("Skipping populateSubnet due to illegal size of connect points. {}", cpts);
+            return;
+        }
+
+        lastRoutingChange = Instant.now();
+        statusLock.lock();
+        try {
+           if (populationStatus == Status.STARTED) {
+                log.warn("Previous rule population is not finished. Cannot"
+                        + " proceed with routing rules for added routes");
+                return;
+            }
+            populationStatus = Status.STARTED;
+            rulePopulator.resetCounter();
+            log.info("Starting to populate routing rules for added routes, subnets={}, cpts={}",
+                    subnets, cpts);
+            // In principle an update to a subnet/prefix should not require a
+            // new ECMPspg calculation as it is not a topology event. As a
+            // result, we use the current/existing ECMPspg in the updated map
+            // used by the redoRouting method.
+            if (updatedEcmpSpgMap == null) {
+                updatedEcmpSpgMap = new HashMap<>();
+            }
+            currentEcmpSpgMap.entrySet().forEach(entry -> {
+                updatedEcmpSpgMap.put(entry.getKey(), entry.getValue());
+                if (log.isTraceEnabled()) {
+                    log.trace("Root switch: {}", entry.getKey());
+                    log.trace("  Current/Existing SPG: {}", entry.getValue());
+                }
+            });
+            Set<EdgePair> edgePairs = new HashSet<>();
+            Set<ArrayList<DeviceId>> routeChanges = new HashSet<>();
+            boolean handleRouting = false;
+
+            if (cpts.size() == 2) {
+                // ensure connect points are edge-pairs
+                Iterator<ConnectPoint> iter = cpts.iterator();
+                DeviceId dev1 = iter.next().deviceId();
+                DeviceId pairDev = getPairDev(dev1);
+                if (iter.next().deviceId().equals(pairDev)) {
+                    edgePairs.add(new EdgePair(dev1, pairDev));
+                } else {
+                    log.warn("Connectpoints {} for subnets {} not on "
+                            + "pair-devices.. aborting populateSubnet", cpts, subnets);
+                    populationStatus = Status.ABORTED;
+                    return;
+                }
+                for (ConnectPoint cp : cpts) {
+                    if (updatedEcmpSpgMap.get(cp.deviceId()) == null) {
+                        EcmpShortestPathGraph ecmpSpgUpdated =
+                            new EcmpShortestPathGraph(cp.deviceId(), srManager);
+                        updatedEcmpSpgMap.put(cp.deviceId(), ecmpSpgUpdated);
+                        log.warn("populateSubnet: no updated graph for dev:{}"
+                                + " ... creating", cp.deviceId());
+                    }
+                    DeviceId retId = shouldHandleRouting(cp.deviceId());
+                    if (retId == null) {
+                        continue;
+                    }
+                    handleRouting = true;
+                }
+            } else {
+                // single connect point
+                DeviceId dstSw = cpts.iterator().next().deviceId();
+                if (updatedEcmpSpgMap.get(dstSw) == null) {
+                    EcmpShortestPathGraph ecmpSpgUpdated =
+                        new EcmpShortestPathGraph(dstSw, srManager);
+                    updatedEcmpSpgMap.put(dstSw, ecmpSpgUpdated);
+                    log.warn("populateSubnet: no updated graph for dev:{}"
+                            + " ... creating", dstSw);
+                }
+                if (srManager.mastershipService.isLocalMaster(dstSw)) {
+                    handleRouting = true;
+                }
+            }
+
+            if (!handleRouting) {
+                log.debug("This instance is not handling ecmp routing to the "
+                        + "connectPoint(s) {}", cpts);
+                populationStatus = Status.ABORTED;
+                return;
+            }
+
+            // if it gets here, this instance should handle routing for the
+            // connectpoint(s). Assume all route-paths have to be updated to
+            // the connectpoint(s) with the following exceptions
+            // 1. if target is non-edge no need for routing rules
+            // 2. if target is one of the connectpoints
+            for (ConnectPoint cp : cpts) {
+                DeviceId dstSw = cp.deviceId();
+                for (Device targetSw : srManager.deviceService.getDevices()) {
+                    boolean isEdge = false;
+                    try {
+                        isEdge = config.isEdgeDevice(targetSw.id());
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage() + "aborting populateSubnet on targetSw {}", targetSw.id());
+                        continue;
+                    }
+                    if (dstSw.equals(targetSw.id()) || !isEdge ||
+                            (cpts.size() == 2 &&
+                                targetSw.id().equals(getPairDev(dstSw)))) {
+                        continue;
+                    }
+                    routeChanges.add(Lists.newArrayList(targetSw.id(), dstSw));
+                }
+            }
+
+            if (!redoRouting(routeChanges, edgePairs, subnets)) {
+                log.debug("populateSubnet: populationStatus is ABORTED");
+                populationStatus = Status.ABORTED;
+                log.warn("Failed to repopulate the rules for subnet.");
+                return;
+            }
+
+            log.debug("populateSubnet: populationStatus is SUCCEEDED");
+            populationStatus = Status.SUCCEEDED;
+            log.info("Completed subnet population. Total # of rules pushed : {}",
+                    rulePopulator.getCounter());
+            return;
+
+        } finally {
+            statusLock.unlock();
+        }
+    }
+
+    /**
+     * Populates the routing rules or makes hash group changes according to the
+     * route-path changes due to link failure, switch failure or link up. This
+     * method should only be called for one of these three possible event-types.
+     * Note that when a switch goes away, all of its links fail as well,
+     * but this is handled as a single switch removal event.
+     *
+     * @param linkDown the single failed link, or null for other conditions
+     *                  such as link-up or a removed switch
+     * @param linkUp the single link up, or null for other conditions such as
+     *                  link-down or a removed switch
+     * @param switchDown the removed switch, or null for other conditions such as
+     *                  link-down or link-up
+     */ // refactor
+    public void populateRoutingRulesForLinkStatusChange(Link linkDown,
+                                                           Link linkUp,
+                                                           DeviceId switchDown) {
+        if ((linkDown != null && (linkUp != null || switchDown != null)) ||
+                (linkUp != null && (linkDown != null || switchDown != null)) ||
+                (switchDown != null && (linkUp != null || linkDown != null))) {
+            log.warn("Only one event can be handled for link status change .. aborting");
+            return;
+        }
+        lastRoutingChange = Instant.now();
+        statusLock.lock();
+        try {
+
+            if (populationStatus == Status.STARTED) {
+                log.warn("Previous rule population is not finished. Cannot"
+                        + " proceeed with routingRules for Topology change");
+                return;
+            }
+
+            // Take snapshots of the topology
+            updatedEcmpSpgMap = new HashMap<>();
+            Set<EdgePair> edgePairs = new HashSet<>();
+            for (Device sw : srManager.deviceService.getDevices()) {
+                EcmpShortestPathGraph ecmpSpgUpdated =
+                        new EcmpShortestPathGraph(sw.id(), srManager);
+                updatedEcmpSpgMap.put(sw.id(), ecmpSpgUpdated);
+                DeviceId pairDev = getPairDev(sw.id());
+                if (pairDev != null) {
+                    // pairDev may not be available yet, but we still need to add
+                    ecmpSpgUpdated = new EcmpShortestPathGraph(pairDev, srManager);
+                    updatedEcmpSpgMap.put(pairDev, ecmpSpgUpdated);
+                    edgePairs.add(new EdgePair(sw.id(), pairDev));
+                }
+            }
+
+            log.info("Starting to populate routing rules from Topology change");
+
+            Set<ArrayList<DeviceId>> routeChanges;
+            log.debug("populateRoutingRulesForLinkStatusChange: "
+                    + "populationStatus is STARTED");
+            populationStatus = Status.STARTED;
+            rulePopulator.resetCounter(); //XXX maybe useful to have a rehash ctr
+            boolean hashGroupsChanged = false;
+            // try optimized re-routing
+            if (linkDown == null) {
+                // either a linkUp or a switchDown - compute all route changes by
+                // comparing all routes of existing ECMP SPG to new ECMP SPG
+                routeChanges = computeRouteChange();
+
+                // deal with linkUp of a seen-before link
+                if (linkUp != null && srManager.linkHandler.isSeenLink(linkUp)) {
+                    if (!srManager.linkHandler.isBidirectional(linkUp)) {
+                        log.warn("Not a bidirectional link yet .. not "
+                                + "processing link {}", linkUp);
+                        srManager.linkHandler.updateSeenLink(linkUp, true);
+                        populationStatus = Status.ABORTED;
+                        return;
+                    }
+                    // link previously seen before
+                    // do hash-bucket changes instead of a re-route
+                    processHashGroupChange(routeChanges, false, null);
+                    // clear out routesChanges so a re-route is not attempted
+                    routeChanges = ImmutableSet.of();
+                    hashGroupsChanged = true;
+                }
+                // for a linkUp of a never-seen-before link
+                // let it fall through to a reroute of the routeChanges
+
+                // now that we are past the check for a previously seen link
+                // it is safe to update the store for the linkUp
+                if (linkUp != null) {
+                    srManager.linkHandler.updateSeenLink(linkUp, true);
+                }
+
+                //deal with switchDown
+                if (switchDown != null) {
+                    processHashGroupChange(routeChanges, true, switchDown);
+                    // clear out routesChanges so a re-route is not attempted
+                    routeChanges = ImmutableSet.of();
+                    hashGroupsChanged = true;
+                }
+            } else {
+                // link has gone down
+                // Compare existing ECMP SPG only with the link that went down
+                routeChanges = computeDamagedRoutes(linkDown);
+                if (routeChanges != null) {
+                    processHashGroupChange(routeChanges, true, null);
+                    // clear out routesChanges so a re-route is not attempted
+                    routeChanges = ImmutableSet.of();
+                    hashGroupsChanged = true;
+                }
+            }
+
+            // do full re-routing if optimized routing returns null routeChanges
+            if (routeChanges == null) {
+                log.warn("Optimized routing failed... opting for full reroute");
+                populationStatus = Status.ABORTED;
+                populateAllRoutingRules();
+                return;
+            }
+
+            if (routeChanges.isEmpty()) {
+                if (hashGroupsChanged) {
+                    log.info("Hash-groups changed for link status change");
+                } else {
+                    log.info("No re-route or re-hash attempted for the link"
+                            + " status change");
+                    updatedEcmpSpgMap.keySet().forEach(devId -> {
+                        currentEcmpSpgMap.put(devId, updatedEcmpSpgMap.get(devId));
+                        log.debug("Updating ECMPspg for remaining dev:{}", devId);
+                    });
+                }
+                log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is SUCCEEDED");
+                populationStatus = Status.SUCCEEDED;
+                return;
+            }
+
+            // reroute of routeChanges
+            if (redoRouting(routeChanges, edgePairs, null)) {
+                log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is SUCCEEDED");
+                populationStatus = Status.SUCCEEDED;
+                log.info("Completed repopulation of rules for link-status change."
+                        + " # of rules populated : {}", rulePopulator.getCounter());
+                return;
+            } else {
+                log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is ABORTED");
+                populationStatus = Status.ABORTED;
+                log.warn("Failed to repopulate the rules for link status change.");
+                return;
+            }
+        } finally {
+            statusLock.unlock();
+        }
+    }
+
+    /**
+     * Processes a set a route-path changes by reprogramming routing rules and
+     * creating new hash-groups or editing them if necessary. This method also
+     * determines the next-hops for the route-path from the src-switch (target)
+     * of the path towards the dst-switch of the path.
+     *
+     * @param routeChanges a set of route-path changes, where each route-path is
+     *                     a list with its first element the src-switch (target)
+     *                     of the path, and the second element the dst-switch of
+     *                     the path.
+     * @param edgePairs a set of edge-switches that are paired by configuration
+     * @param subnets  a set of prefixes that need to be populated in the routing
+     *                 table of the target switch in the route-path. Can be null,
+     *                 in which case all the prefixes belonging to the dst-switch
+     *                 will be populated in the target switch
+     * @return true if successful in repopulating all routes
+     */
+    private boolean redoRouting(Set<ArrayList<DeviceId>> routeChanges,
+                                Set<EdgePair> edgePairs, Set<IpPrefix> subnets) {
+        // first make every entry two-elements
+        Set<ArrayList<DeviceId>> changedRoutes = new HashSet<>();
+        for (ArrayList<DeviceId> route : routeChanges) {
+            if (route.size() == 1) {
+                DeviceId dstSw = route.get(0);
+                EcmpShortestPathGraph ec = updatedEcmpSpgMap.get(dstSw);
+                if (ec == null) {
+                    log.warn("No graph found for {} .. aborting redoRouting", dstSw);
+                    return false;
+                }
+                ec.getAllLearnedSwitchesAndVia().keySet().forEach(key -> {
+                    ec.getAllLearnedSwitchesAndVia().get(key).keySet().forEach(target -> {
+                        changedRoutes.add(Lists.newArrayList(target, dstSw));
+                    });
+                });
+            } else {
+                DeviceId targetSw = route.get(0);
+                DeviceId dstSw = route.get(1);
+                changedRoutes.add(Lists.newArrayList(targetSw, dstSw));
+            }
+        }
+
+        // now process changedRoutes according to edgePairs
+        if (!redoRoutingEdgePairs(edgePairs, subnets, changedRoutes)) {
+            return false; //abort routing and fail fast
+        }
+
+        // whatever is left in changedRoutes is now processed for individual dsts.
+        Set<DeviceId> updatedDevices = Sets.newHashSet();
+        if (!redoRoutingIndividualDests(subnets, changedRoutes,
+                                        updatedDevices)) {
+            return false; //abort routing and fail fast
+        }
+
+        // update ecmpSPG for all edge-pairs
+        for (EdgePair ep : edgePairs) {
+            currentEcmpSpgMap.put(ep.dev1, updatedEcmpSpgMap.get(ep.dev1));
+            currentEcmpSpgMap.put(ep.dev2, updatedEcmpSpgMap.get(ep.dev2));
+            log.debug("Updating ECMPspg for edge-pair:{}-{}", ep.dev1, ep.dev2);
+        }
+
+        // here is where we update all devices not touched by this instance
+        updatedEcmpSpgMap.keySet().stream()
+            .filter(devId -> !edgePairs.stream().anyMatch(ep -> ep.includes(devId)))
+            .filter(devId -> !updatedDevices.contains(devId))
+            .forEach(devId -> {
+                currentEcmpSpgMap.put(devId, updatedEcmpSpgMap.get(devId));
+                log.debug("Updating ECMPspg for remaining dev:{}", devId);
+            });
+        return true;
+    }
+
+    /**
+     * Programs targetSw in the changedRoutes for given prefixes reachable by
+     * an edgePair. If no prefixes are given, the method will use configured
+     * subnets/prefixes. If some configured subnets belong only to a specific
+     * destination in the edgePair, then the target switch will be programmed
+     * only to that destination.
+     *
+     * @param edgePairs set of edge-pairs for which target will be programmed
+     * @param subnets a set of prefixes that need to be populated in the routing
+     *                 table of the target switch in the changedRoutes. Can be null,
+     *                 in which case all the configured prefixes belonging to the
+     *                 paired switches will be populated in the target switch
+     * @param changedRoutes a set of route-path changes, where each route-path is
+     *                     a list with its first element the src-switch (target)
+     *                     of the path, and the second element the dst-switch of
+     *                     the path.
+     * @return true if successful
+     */
+    private boolean redoRoutingEdgePairs(Set<EdgePair> edgePairs,
+                                      Set<IpPrefix> subnets,
+                                      Set<ArrayList<DeviceId>> changedRoutes) {
+        for (EdgePair ep : edgePairs) {
+            // temp store for a target's changedRoutes to this edge-pair
+            Map<DeviceId, Set<ArrayList<DeviceId>>> targetRoutes = new HashMap<>();
+            Iterator<ArrayList<DeviceId>> i = changedRoutes.iterator();
+            while (i.hasNext()) {
+                ArrayList<DeviceId> route = i.next();
+                DeviceId dstSw = route.get(1);
+                if (ep.includes(dstSw)) {
+                    // routeChange for edge pair found
+                    // sort by target iff target is edge and remove from changedRoutes
+                    DeviceId targetSw = route.get(0);
+                    try {
+                        if (!srManager.deviceConfiguration.isEdgeDevice(targetSw)) {
+                            continue;
+                        }
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage() + "aborting redoRouting");
+                        return false;
+                    }
+                    // route is from another edge to this edge-pair
+                    if (targetRoutes.containsKey(targetSw)) {
+                        targetRoutes.get(targetSw).add(route);
+                    } else {
+                        Set<ArrayList<DeviceId>> temp = new HashSet<>();
+                        temp.add(route);
+                        targetRoutes.put(targetSw, temp);
+                    }
+                    i.remove();
+                }
+            }
+            // so now for this edgepair we have a per target set of routechanges
+            // process target->edgePair route
+            for (Map.Entry<DeviceId, Set<ArrayList<DeviceId>>> entry :
+                            targetRoutes.entrySet()) {
+                log.debug("* redoRoutingDstPair Target:{} -> edge-pair {}",
+                          entry.getKey(), ep);
+                DeviceId targetSw = entry.getKey();
+                Map<DeviceId, Set<DeviceId>> perDstNextHops = new HashMap<>();
+                entry.getValue().forEach(route -> {
+                    Set<DeviceId> nhops = getNextHops(route.get(0), route.get(1));
+                    log.debug("route: target {} -> dst {} found with next-hops {}",
+                              route.get(0), route.get(1), nhops);
+                    perDstNextHops.put(route.get(1), nhops);
+                });
+                Set<IpPrefix> ipDev1 = (subnets == null) ? config.getSubnets(ep.dev1)
+                                                         : subnets;
+                Set<IpPrefix> ipDev2 = (subnets == null) ? config.getSubnets(ep.dev2)
+                                                         : subnets;
+                ipDev1 = (ipDev1 == null) ? Sets.newHashSet() : ipDev1;
+                ipDev2 = (ipDev2 == null) ? Sets.newHashSet() : ipDev2;
+                Set<DeviceId> nhDev1 = perDstNextHops.get(ep.dev1);
+                Set<DeviceId> nhDev2 = perDstNextHops.get(ep.dev2);
+                // handle routing to subnets common to edge-pair
+                // only if the targetSw is not part of the edge-pair and there
+                // exists a next hop to at least one of the devices in the edge-pair
+                if (!ep.includes(targetSw)
+                        && ((nhDev1 != null && !nhDev1.isEmpty())
+                                || (nhDev2 != null && !nhDev2.isEmpty()))) {
+                    if (!populateEcmpRoutingRulePartial(
+                             targetSw,
+                             ep.dev1, ep.dev2,
+                             perDstNextHops,
+                             Sets.intersection(ipDev1, ipDev2))) {
+                        return false; // abort everything and fail fast
+                    }
+                }
+                // handle routing to subnets that only belong to dev1 only if
+                // a next-hop exists from the target to dev1
+                Set<IpPrefix> onlyDev1Subnets = Sets.difference(ipDev1, ipDev2);
+                if (!onlyDev1Subnets.isEmpty()
+                        && nhDev1 != null  && !nhDev1.isEmpty()) {
+                    Map<DeviceId, Set<DeviceId>> onlyDev1NextHops = new HashMap<>();
+                    onlyDev1NextHops.put(ep.dev1, nhDev1);
+                    if (!populateEcmpRoutingRulePartial(
+                            targetSw,
+                            ep.dev1, null,
+                            onlyDev1NextHops,
+                            onlyDev1Subnets)) {
+                        return false; // abort everything and fail fast
+                    }
+                }
+                // handle routing to subnets that only belong to dev2 only if
+                // a next-hop exists from the target to dev2
+                Set<IpPrefix> onlyDev2Subnets = Sets.difference(ipDev2, ipDev1);
+                if (!onlyDev2Subnets.isEmpty()
+                        && nhDev2 != null && !nhDev2.isEmpty()) {
+                    Map<DeviceId, Set<DeviceId>> onlyDev2NextHops = new HashMap<>();
+                    onlyDev2NextHops.put(ep.dev2, nhDev2);
+                    if (!populateEcmpRoutingRulePartial(
+                            targetSw,
+                            ep.dev2, null,
+                            onlyDev2NextHops,
+                            onlyDev2Subnets)) {
+                        return false; // abort everything and fail fast
+                    }
+                }
+            }
+            // if it gets here it has succeeded for all targets to this edge-pair
+        }
+        return true;
+    }
+
+    /**
+     * Programs targetSw in the changedRoutes for given prefixes reachable by
+     * a destination switch that is not part of an edge-pair.
+     * If no prefixes are given, the method will use configured subnets/prefixes.
+     *
+     * @param subnets a set of prefixes that need to be populated in the routing
+     *                 table of the target switch in the changedRoutes. Can be null,
+     *                 in which case all the configured prefixes belonging to the
+     *                 paired switches will be populated in the target switch
+     * @param changedRoutes a set of route-path changes, where each route-path is
+     *                     a list with its first element the src-switch (target)
+     *                     of the path, and the second element the dst-switch of
+     *                     the path.
+     * @return true if successful
+     */
+    private boolean redoRoutingIndividualDests(Set<IpPrefix> subnets,
+                                               Set<ArrayList<DeviceId>> changedRoutes,
+                                               Set<DeviceId> updatedDevices) {
+        // aggregate route-path changes for each dst device
+        HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> routesBydevice =
+                new HashMap<>();
+        for (ArrayList<DeviceId> route: changedRoutes) {
+            DeviceId dstSw = route.get(1);
+            ArrayList<ArrayList<DeviceId>> deviceRoutes =
+                    routesBydevice.get(dstSw);
+            if (deviceRoutes == null) {
+                deviceRoutes = new ArrayList<>();
+                routesBydevice.put(dstSw, deviceRoutes);
+            }
+            deviceRoutes.add(route);
+        }
+        for (DeviceId impactedDstDevice : routesBydevice.keySet()) {
+            ArrayList<ArrayList<DeviceId>> deviceRoutes =
+                    routesBydevice.get(impactedDstDevice);
+            for (ArrayList<DeviceId> route: deviceRoutes) {
+                log.debug("* redoRoutingIndiDst Target: {} -> dst: {}",
+                          route.get(0), route.get(1));
+                DeviceId targetSw = route.get(0);
+                DeviceId dstSw = route.get(1); // same as impactedDstDevice
+                Set<DeviceId> nextHops = getNextHops(targetSw, dstSw);
+                if (nextHops.isEmpty()) {
+                    log.warn("Could not find next hop from target:{} --> dst {} "
+                            + "skipping this route", targetSw, dstSw);
+                    continue;
+                }
+                Map<DeviceId, Set<DeviceId>> nhops = new HashMap<>();
+                nhops.put(dstSw, nextHops);
+                if (!populateEcmpRoutingRulePartial(targetSw, dstSw, null, nhops,
+                         (subnets == null) ? Sets.newHashSet() : subnets)) {
+                    return false; // abort routing and fail fast
+                }
+                log.debug("Populating flow rules from target: {} to dst: {}"
+                        + " is successful", targetSw, dstSw);
+            }
+            //Only if all the flows for all impacted routes to a
+            //specific target are pushed successfully, update the
+            //ECMP graph for that target. Or else the next event
+            //would not see any changes in the ECMP graphs.
+            //In another case, the target switch has gone away, so
+            //routes can't be installed. In that case, the current map
+            //is updated here, without any flows being pushed.
+            currentEcmpSpgMap.put(impactedDstDevice,
+                                  updatedEcmpSpgMap.get(impactedDstDevice));
+            updatedDevices.add(impactedDstDevice);
+            log.debug("Updating ECMPspg for impacted dev:{}", impactedDstDevice);
+        }
+        return true;
+    }
+
+    /**
+     * Populate ECMP rules for subnets from target to destination via nexthops.
+     *
+     * @param targetSw Device ID of target switch in which rules will be programmed
+     * @param destSw1 Device ID of final destination switch to which the rules will forward
+     * @param destSw2 Device ID of paired destination switch to which the rules will forward
+     *                A null deviceId indicates packets should only be sent to destSw1
+     * @param nextHops Map indication a list of next hops per destSw
+     * @param subnets Subnets to be populated. If empty, populate all configured subnets.
+     * @return true if it succeeds in populating rules
+     */ // refactor
+    private boolean populateEcmpRoutingRulePartial(DeviceId targetSw,
+                                                   DeviceId destSw1,
+                                                   DeviceId destSw2,
+                                                   Map<DeviceId, Set<DeviceId>> nextHops,
+                                                   Set<IpPrefix> subnets) {
+        boolean result;
+        // If both target switch and dest switch are edge routers, then set IP
+        // rule for both subnet and router IP.
+        boolean targetIsEdge;
+        boolean dest1IsEdge;
+        Ip4Address dest1RouterIpv4, dest2RouterIpv4 = null;
+        Ip6Address dest1RouterIpv6, dest2RouterIpv6 = null;
+
+        try {
+            targetIsEdge = config.isEdgeDevice(targetSw);
+            dest1IsEdge = config.isEdgeDevice(destSw1);
+            dest1RouterIpv4 = config.getRouterIpv4(destSw1);
+            dest1RouterIpv6 = config.getRouterIpv6(destSw1);
+            if (destSw2 != null) {
+                dest2RouterIpv4 = config.getRouterIpv4(destSw2);
+                dest2RouterIpv6 = config.getRouterIpv6(destSw2);
+            }
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateEcmpRoutingRulePartial.");
+            return false;
+        }
+
+        if (targetIsEdge && dest1IsEdge) {
+            subnets = (subnets != null && !subnets.isEmpty())
+                            ? Sets.newHashSet(subnets)
+                            : Sets.newHashSet(config.getSubnets(destSw1));
+            // XXX -  Rethink this
+            /*subnets.add(dest1RouterIpv4.toIpPrefix());
+            if (dest1RouterIpv6 != null) {
+                subnets.add(dest1RouterIpv6.toIpPrefix());
+            }
+            if (destSw2 != null && dest2RouterIpv4 != null) {
+                subnets.add(dest2RouterIpv4.toIpPrefix());
+                if (dest2RouterIpv6 != null) {
+                    subnets.add(dest2RouterIpv6.toIpPrefix());
+                }
+            }*/
+            log.debug(". populateEcmpRoutingRulePartial in device {} towards {} {} "
+                    + "for subnets {}", targetSw, destSw1,
+                                        (destSw2 != null) ? ("& " + destSw2) : "",
+                                        subnets);
+            result = rulePopulator.populateIpRuleForSubnet(targetSw, subnets,
+                                                           destSw1, destSw2,
+                                                           nextHops);
+            if (!result) {
+                return false;
+            }
+            /* XXX rethink this
+            IpPrefix routerIpPrefix = destRouterIpv4.toIpPrefix();
+            log.debug("* populateEcmpRoutingRulePartial in device {} towards {} "
+                    + "for router IP {}", targetSw, destSw, routerIpPrefix);
+            result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix,
+                                                           destSw, nextHops);
+            if (!result) {
+                return false;
+            }
+            // If present we deal with IPv6 loopback.
+            if (destRouterIpv6 != null) {
+                routerIpPrefix = destRouterIpv6.toIpPrefix();
+                log.debug("* populateEcmpRoutingRulePartial in device {} towards {}"
+                        + " for v6 router IP {}", targetSw, destSw, routerIpPrefix);
+                result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix,
+                                                               destSw, nextHops);
+                if (!result) {
+                    return false;
+                }
+            }*/
+        }
+
+        if (!targetIsEdge && dest1IsEdge) {
+            // MPLS rules in all non-edge target devices. These rules are for
+            // individual destinations, even if the dsts are part of edge-pairs.
+            log.debug(". populateEcmpRoutingRulePartial in device{} towards {} for "
+                    + "all MPLS rules", targetSw, destSw1);
+            result = rulePopulator.populateMplsRule(targetSw, destSw1,
+                                                    nextHops.get(destSw1),
+                                                    dest1RouterIpv4);
+            if (!result) {
+                return false;
+            }
+            if (dest1RouterIpv6 != null) {
+                result = rulePopulator.populateMplsRule(targetSw, destSw1,
+                                                        nextHops.get(destSw1),
+                                                        dest1RouterIpv6);
+                if (!result) {
+                    return false;
+                }
+            }
+        }
+
+        // To save on ECMP groups
+        // avoid MPLS rules in non-edge-devices to non-edge-devices
+        // avoid MPLS transit rules in edge-devices
+        // avoid loopback IP rules in edge-devices to non-edge-devices
+        return true;
+    }
+
+    /**
+     * Processes a set a route-path changes by editing hash groups.
+     *
+     * @param routeChanges a set of route-path changes, where each route-path is
+     *                     a list with its first element the src-switch of the path
+     *                     and the second element the dst-switch of the path.
+     * @param linkOrSwitchFailed true if the route changes are for a failed
+     *                           switch or linkDown event
+     * @param failedSwitch the switchId if the route changes are for a failed switch,
+     *                     otherwise null
+     */
+    private void processHashGroupChange(Set<ArrayList<DeviceId>> routeChanges,
+                                        boolean linkOrSwitchFailed,
+                                        DeviceId failedSwitch) {
+        Set<ArrayList<DeviceId>> changedRoutes = new HashSet<>();
+        // first, ensure each routeChanges entry has two elements
+        for (ArrayList<DeviceId> route : routeChanges) {
+            if (route.size() == 1) {
+                // route-path changes are from everyone else to this switch
+                DeviceId dstSw = route.get(0);
+                srManager.deviceService.getAvailableDevices().forEach(sw -> {
+                    if (!sw.id().equals(dstSw)) {
+                        changedRoutes.add(Lists.newArrayList(sw.id(), dstSw));
+                    }
+                });
+            } else {
+                changedRoutes.add(route);
+            }
+        }
+        boolean someFailed = false;
+        Set<DeviceId> updatedDevices = Sets.newHashSet();
+        for (ArrayList<DeviceId> route : changedRoutes) {
+            DeviceId targetSw = route.get(0);
+            DeviceId dstSw = route.get(1);
+            if (linkOrSwitchFailed) {
+                boolean success = fixHashGroupsForRoute(route, true);
+                // it's possible that we cannot fix hash groups for a route
+                // if the target switch has failed. Nevertheless the ecmp graph
+                // for the impacted switch must still be updated.
+                if (!success && failedSwitch != null && targetSw.equals(failedSwitch)) {
+                    currentEcmpSpgMap.put(dstSw, updatedEcmpSpgMap.get(dstSw));
+                    currentEcmpSpgMap.remove(targetSw);
+                    log.debug("Updating ECMPspg for dst:{} removing failed switch "
+                            + "target:{}", dstSw, targetSw);
+                    updatedDevices.add(targetSw);
+                    updatedDevices.add(dstSw);
+                    continue;
+                }
+                //linkfailed - update both sides
+                if (success) {
+                    currentEcmpSpgMap.put(targetSw, updatedEcmpSpgMap.get(targetSw));
+                    currentEcmpSpgMap.put(dstSw, updatedEcmpSpgMap.get(dstSw));
+                    log.debug("Updating ECMPspg for dst:{} and target:{} for linkdown"
+                            + " or switchdown", dstSw, targetSw);
+                    updatedDevices.add(targetSw);
+                    updatedDevices.add(dstSw);
+                } else {
+                    someFailed = true;
+                }
+            } else {
+                //linkup of seen before link
+                boolean success = fixHashGroupsForRoute(route, false);
+                if (success) {
+                    currentEcmpSpgMap.put(targetSw, updatedEcmpSpgMap.get(targetSw));
+                    currentEcmpSpgMap.put(dstSw, updatedEcmpSpgMap.get(dstSw));
+                    log.debug("Updating ECMPspg for target:{} and dst:{} for linkup",
+                              targetSw, dstSw);
+                    updatedDevices.add(targetSw);
+                    updatedDevices.add(dstSw);
+                } else {
+                    someFailed = true;
+                }
+            }
+        }
+        if (!someFailed) {
+            // here is where we update all devices not touched by this instance
+            updatedEcmpSpgMap.keySet().stream()
+                .filter(devId -> !updatedDevices.contains(devId))
+                .forEach(devId -> {
+                    currentEcmpSpgMap.put(devId, updatedEcmpSpgMap.get(devId));
+                    log.debug("Updating ECMPspg for remaining dev:{}", devId);
+            });
+        }
+    }
+
+    /**
+     * Edits hash groups in the src-switch (targetSw) of a route-path by
+     * calling the groupHandler to either add or remove buckets in an existing
+     * hash group.
+     *
+     * @param route a single list representing a route-path where the first element
+     *                  is the src-switch (targetSw) of the route-path and the
+     *                  second element is the dst-switch
+     * @param revoke true if buckets in the hash-groups need to be removed;
+     *              false if buckets in the hash-groups need to be added
+     * @return true if the hash group editing is successful
+     */
+    private boolean fixHashGroupsForRoute(ArrayList<DeviceId> route,
+                                          boolean revoke) {
+        DeviceId targetSw = route.get(0);
+        if (route.size() < 2) {
+            log.warn("Cannot fixHashGroupsForRoute - no dstSw in route {}", route);
+            return false;
+        }
+        DeviceId destSw = route.get(1);
+        log.debug("* processing fixHashGroupsForRoute: Target {} -> Dest {}",
+                  targetSw, destSw);
+        // figure out the new next hops at the targetSw towards the destSw
+        Set<DeviceId> nextHops = getNextHops(targetSw, destSw);
+        // call group handler to change hash group at targetSw
+        DefaultGroupHandler grpHandler = srManager.getGroupHandler(targetSw);
+        if (grpHandler == null) {
+            log.warn("Cannot find grouphandler for dev:{} .. aborting"
+                    + " {} hash group buckets for route:{} ", targetSw,
+                    (revoke) ? "revoke" : "repopulate", route);
+            return false;
+        }
+        log.debug("{} hash-groups buckets For Route {} -> {} to next-hops {}",
+                  (revoke) ? "revoke" : "repopulating",
+                  targetSw, destSw, nextHops);
+        return (revoke) ? grpHandler.fixHashGroups(targetSw, nextHops,
+                                                       destSw, true)
+                            : grpHandler.fixHashGroups(targetSw, nextHops,
+                                                       destSw, false);
+    }
+
+    /**
+     * Start the flow rule population process if it was never started. The
+     * process finishes successfully when all flow rules are set and stops with
+     * ABORTED status when any groups required for flows is not set yet.
+     */
+    public void startPopulationProcess() {
+        statusLock.lock();
+        try {
+            if (populationStatus == Status.IDLE
+                    || populationStatus == Status.SUCCEEDED
+                    || populationStatus == Status.ABORTED) {
+                populateAllRoutingRules();
+            } else {
+                log.warn("Not initiating startPopulationProcess as populationStatus is {}",
+                         populationStatus);
+            }
+        } finally {
+            statusLock.unlock();
+        }
+    }
+
+    /**
+     * Revoke rules of given subnet in all edge switches.
+     *
+     * @param subnets subnet being removed
+     * @return true if succeed
+     */
+    protected boolean revokeSubnet(Set<IpPrefix> subnets) {
+        statusLock.lock();
+        try {
+            return srManager.routingRulePopulator.revokeIpRuleForSubnet(subnets);
+        } finally {
+            statusLock.unlock();
+        }
+    }
+
+    /**
+     * Populates IP rules for a route that has direct connection to the switch
+     * if the current instance is the master of the switch.
+     *
+     * @param deviceId device ID of the device that next hop attaches to
+     * @param prefix IP prefix of the route
+     * @param hostMac MAC address of the next hop
+     * @param hostVlanId Vlan ID of the nexthop
+     * @param outPort port where the next hop attaches to
+     */
+    void populateRoute(DeviceId deviceId, IpPrefix prefix,
+                       MacAddress hostMac, VlanId hostVlanId, PortNumber outPort) {
+        if (srManager.mastershipService.isLocalMaster(deviceId)) {
+            srManager.routingRulePopulator.populateRoute(deviceId, prefix, hostMac, hostVlanId, outPort);
+        }
+    }
+
+    /**
+     * Removes IP rules for a route when the next hop is gone.
+     * if the current instance is the master of the switch.
+     *
+     * @param deviceId device ID of the device that next hop attaches to
+     * @param prefix IP prefix of the route
+     * @param hostMac MAC address of the next hop
+     * @param hostVlanId Vlan ID of the nexthop
+     * @param outPort port that next hop attaches to
+     */
+    void revokeRoute(DeviceId deviceId, IpPrefix prefix,
+                     MacAddress hostMac, VlanId hostVlanId, PortNumber outPort) {
+        if (srManager.mastershipService.isLocalMaster(deviceId)) {
+            srManager.routingRulePopulator.revokeRoute(deviceId, prefix, hostMac, hostVlanId, outPort);
+        }
+    }
+
+    /**
+     * Remove ECMP graph entry for the given device. Typically called when
+     * device is no longer available.
+     *
+     * @param deviceId the device for which graphs need to be purged
+     */
+    protected void purgeEcmpGraph(DeviceId deviceId) {
+        statusLock.lock();
+        try {
+
+            if (populationStatus == Status.STARTED) {
+                log.warn("Previous rule population is not finished. Cannot"
+                        + " proceeed with purgeEcmpGraph for {}", deviceId);
+                return;
+            }
+            log.debug("Updating ECMPspg for unavailable dev:{}", deviceId);
+            currentEcmpSpgMap.remove(deviceId);
+            if (updatedEcmpSpgMap != null) {
+                updatedEcmpSpgMap.remove(deviceId);
+            }
+        } finally {
+            statusLock.unlock();
+        }
+    }
+
+    //////////////////////////////////////
+    //  Routing helper methods and classes
+    //////////////////////////////////////
+
+    /**
+     * Computes set of affected routes due to failed link. Assumes
+     * previous ecmp shortest-path graph exists for a switch in order to compute
+     * affected routes. If such a graph does not exist, the method returns null.
+     *
+     * @param linkFail the failed link
+     * @return the set of affected routes which may be empty if no routes were
+     *         affected, or null if no previous ecmp spg was found for comparison
+     */
+    private Set<ArrayList<DeviceId>> computeDamagedRoutes(Link linkFail) {
+        Set<ArrayList<DeviceId>> routes = new HashSet<>();
+
+        for (Device sw : srManager.deviceService.getDevices()) {
+            log.debug("Computing the impacted routes for device {} due to link fail",
+                      sw.id());
+            DeviceId retId = shouldHandleRouting(sw.id());
+            if (retId == null) {
+                continue;
+            }
+            Set<DeviceId> devicesToProcess = Sets.newHashSet(retId, sw.id());
+            for (DeviceId rootSw : devicesToProcess) {
+                EcmpShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(rootSw);
+                if (ecmpSpg == null) {
+                    log.warn("No existing ECMP graph for switch {}. Aborting optimized"
+                            + " rerouting and opting for full-reroute", rootSw);
+                    return null;
+                }
+                if (log.isDebugEnabled()) {
+                    log.debug("Root switch: {}", rootSw);
+                    log.debug("  Current/Existing SPG: {}", ecmpSpg);
+                    log.debug("       New/Updated SPG: {}", updatedEcmpSpgMap.get(rootSw));
+                }
+                HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>>
+                    switchVia = ecmpSpg.getAllLearnedSwitchesAndVia();
+                // figure out if the broken link affected any route-paths in this graph
+                for (Integer itrIdx : switchVia.keySet()) {
+                    log.trace("Current/Exiting SPG Iterindex# {}", itrIdx);
+                    HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap =
+                            switchVia.get(itrIdx);
+                    for (DeviceId targetSw : swViaMap.keySet()) {
+                        log.trace("TargetSwitch {} --> RootSwitch {}",
+                                  targetSw, rootSw);
+                        for (ArrayList<DeviceId> via : swViaMap.get(targetSw)) {
+                            log.trace(" Via:");
+                            via.forEach(e -> log.trace("  {}", e));
+                        }
+                        Set<ArrayList<DeviceId>> subLinks =
+                                computeLinks(targetSw, rootSw, swViaMap);
+                        for (ArrayList<DeviceId> alink: subLinks) {
+                            if ((alink.get(0).equals(linkFail.src().deviceId()) &&
+                                    alink.get(1).equals(linkFail.dst().deviceId()))
+                                    ||
+                                    (alink.get(0).equals(linkFail.dst().deviceId()) &&
+                                         alink.get(1).equals(linkFail.src().deviceId()))) {
+                                log.debug("Impacted route:{}->{}", targetSw, rootSw);
+                                ArrayList<DeviceId> aRoute = new ArrayList<>();
+                                aRoute.add(targetSw); // switch with rules to populate
+                                aRoute.add(rootSw); // towards this destination
+                                routes.add(aRoute);
+                                break;
+                            }
+                        }
+                    }
+                }
+
+            }
+
+        }
+        return routes;
+    }
+
+    /**
+     * Computes set of affected routes due to new links or failed switches.
+     *
+     * @return the set of affected routes which may be empty if no routes were
+     *         affected
+     */
+    private Set<ArrayList<DeviceId>> computeRouteChange() {
+        ImmutableSet.Builder<ArrayList<DeviceId>> changedRtBldr =
+                ImmutableSet.builder();
+
+        for (Device sw : srManager.deviceService.getDevices()) {
+            log.debug("Computing the impacted routes for device {}", sw.id());
+            DeviceId retId = shouldHandleRouting(sw.id());
+            if (retId == null) {
+                continue;
+            }
+            Set<DeviceId> devicesToProcess = Sets.newHashSet(retId, sw.id());
+            for (DeviceId rootSw : devicesToProcess) {
+                if (log.isTraceEnabled()) {
+                    log.trace("Device links for dev: {}", rootSw);
+                    for (Link link: srManager.linkService.getDeviceLinks(rootSw)) {
+                        log.trace("{} -> {} ", link.src().deviceId(),
+                                  link.dst().deviceId());
+                    }
+                }
+                EcmpShortestPathGraph currEcmpSpg = currentEcmpSpgMap.get(rootSw);
+                if (currEcmpSpg == null) {
+                    log.debug("No existing ECMP graph for device {}.. adding self as "
+                            + "changed route", rootSw);
+                    changedRtBldr.add(Lists.newArrayList(rootSw));
+                    continue;
+                }
+                EcmpShortestPathGraph newEcmpSpg = updatedEcmpSpgMap.get(rootSw);
+                if (log.isDebugEnabled()) {
+                    log.debug("Root switch: {}", rootSw);
+                    log.debug("  Current/Existing SPG: {}", currEcmpSpg);
+                    log.debug("       New/Updated SPG: {}", newEcmpSpg);
+                }
+                // first use the updated/new map to compare to current/existing map
+                // as new links may have come up
+                changedRtBldr.addAll(compareGraphs(newEcmpSpg, currEcmpSpg, rootSw));
+                // then use the current/existing map to compare to updated/new map
+                // as switch may have been removed
+                changedRtBldr.addAll(compareGraphs(currEcmpSpg, newEcmpSpg, rootSw));
+            }
+        }
+
+        Set<ArrayList<DeviceId>> changedRoutes = changedRtBldr.build();
+        for (ArrayList<DeviceId> route: changedRoutes) {
+            log.debug("Route changes Target -> Root");
+            if (route.size() == 1) {
+                log.debug(" : all -> {}", route.get(0));
+            } else {
+                log.debug(" : {} -> {}", route.get(0), route.get(1));
+            }
+        }
+        return changedRoutes;
+    }
+
+    /**
+     * For the root switch, searches all the target nodes reachable in the base
+     * graph, and compares paths to the ones in the comp graph.
+     *
+     * @param base the graph that is indexed for all reachable target nodes
+     *             from the root node
+     * @param comp the graph that the base graph is compared to
+     * @param rootSw  both ecmp graphs are calculated for the root node
+     * @return all the routes that have changed in the base graph
+     */
+    private Set<ArrayList<DeviceId>> compareGraphs(EcmpShortestPathGraph base,
+                                                   EcmpShortestPathGraph comp,
+                                                   DeviceId rootSw) {
+        ImmutableSet.Builder<ArrayList<DeviceId>> changedRoutesBuilder =
+                ImmutableSet.builder();
+        HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> baseMap =
+                base.getAllLearnedSwitchesAndVia();
+        HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> compMap =
+                comp.getAllLearnedSwitchesAndVia();
+        for (Integer itrIdx : baseMap.keySet()) {
+            HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> baseViaMap =
+                    baseMap.get(itrIdx);
+            for (DeviceId targetSw : baseViaMap.keySet()) {
+                ArrayList<ArrayList<DeviceId>> basePath = baseViaMap.get(targetSw);
+                ArrayList<ArrayList<DeviceId>> compPath = getVia(compMap, targetSw);
+                if ((compPath == null) || !basePath.equals(compPath)) {
+                    log.trace("Impacted route:{} -> {}", targetSw, rootSw);
+                    ArrayList<DeviceId> route = new ArrayList<>();
+                    route.add(targetSw); // switch with rules to populate
+                    route.add(rootSw); // towards this destination
+                    changedRoutesBuilder.add(route);
+                }
+            }
+        }
+        return changedRoutesBuilder.build();
+    }
+
+    /**
+     * Returns the ECMP paths traversed to reach the target switch.
+     *
+     * @param switchVia a per-iteration view of the ECMP graph for a root switch
+     * @param targetSw the switch to reach from the root switch
+     * @return the nodes traversed on ECMP paths to the target switch
+     */
+    private ArrayList<ArrayList<DeviceId>> getVia(HashMap<Integer, HashMap<DeviceId,
+            ArrayList<ArrayList<DeviceId>>>> switchVia, DeviceId targetSw) {
+        for (Integer itrIdx : switchVia.keySet()) {
+            HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap =
+                    switchVia.get(itrIdx);
+            if (swViaMap.get(targetSw) == null) {
+                continue;
+            } else {
+                return swViaMap.get(targetSw);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Utility method to break down a path from src to dst device into a collection
+     * of links.
+     *
+     * @param src src device of the path
+     * @param dst dst device of the path
+     * @param viaMap path taken from src to dst device
+     * @return collection of links in the path
+     */
+    private Set<ArrayList<DeviceId>> computeLinks(DeviceId src,
+                                                  DeviceId dst,
+                       HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> viaMap) {
+        Set<ArrayList<DeviceId>> subLinks = Sets.newHashSet();
+        for (ArrayList<DeviceId> via : viaMap.get(src)) {
+            DeviceId linkSrc = src;
+            DeviceId linkDst = dst;
+            for (DeviceId viaDevice: via) {
+                ArrayList<DeviceId> link = new ArrayList<>();
+                linkDst = viaDevice;
+                link.add(linkSrc);
+                link.add(linkDst);
+                subLinks.add(link);
+                linkSrc = viaDevice;
+            }
+            ArrayList<DeviceId> link = new ArrayList<>();
+            link.add(linkSrc);
+            link.add(dst);
+            subLinks.add(link);
+        }
+
+        return subLinks;
+    }
+
+    /**
+     * Determines whether this controller instance should handle routing for the
+     * given {@code deviceId}, based on mastership and pairDeviceId if one exists.
+     * Returns null if this instance should not handle routing for given {@code deviceId}.
+     * Otherwise the returned value could be the given deviceId itself, or the
+     * deviceId for the paired edge device. In the latter case, this instance
+     * should handle routing for both the given device and the paired device.
+     *
+     * @param deviceId device identifier to consider for routing
+     * @return null or deviceId which could be the same as the given deviceId
+     *          or the deviceId of a paired edge device
+     */
+    private DeviceId shouldHandleRouting(DeviceId deviceId) {
+        if (!srManager.mastershipService.isLocalMaster(deviceId)) {
+            log.debug("Not master for dev:{} .. skipping routing, may get handled "
+                    + "elsewhere as part of paired devices", deviceId);
+            return null;
+        }
+        NodeId myNode = srManager.mastershipService.getMasterFor(deviceId);
+        DeviceId pairDev = getPairDev(deviceId);
+
+        if (pairDev != null) {
+            if (!srManager.deviceService.isAvailable(pairDev)) {
+                log.warn("pairedDev {} not available .. routing this dev:{} "
+                        + "without mastership check",
+                          pairDev, deviceId);
+                return pairDev; // handle both temporarily
+            }
+            NodeId pairMasterNode = srManager.mastershipService.getMasterFor(pairDev);
+            if (myNode.compareTo(pairMasterNode) <= 0) {
+                log.debug("Handling routing for both dev:{} pair-dev:{}; myNode: {}"
+                        + " pairMaster:{} compare:{}", deviceId, pairDev,
+                        myNode, pairMasterNode,
+                        myNode.compareTo(pairMasterNode));
+                return pairDev; // handle both
+            } else {
+                log.debug("PairDev node: {} should handle routing for dev:{} and "
+                        + "pair-dev:{}", pairMasterNode, deviceId, pairDev);
+                return null; // handle neither
+            }
+        }
+        return deviceId; // not paired, just handle given device
+    }
+
+    /**
+     * Returns the configured paired DeviceId for the given Device, or null
+     * if no such paired device has been configured.
+     *
+     * @param deviceId
+     * @return configured pair deviceId or null
+     */
+    private DeviceId getPairDev(DeviceId deviceId) {
+        DeviceId pairDev;
+        try {
+            pairDev = srManager.deviceConfiguration.getPairDeviceId(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " .. cannot continue routing for dev: {}");
+            return null;
+        }
+        return pairDev;
+    }
+
+    /**
+     * Returns the set of deviceIds which are the next hops from the targetSw
+     * to the dstSw according to the latest ECMP spg.
+     *
+     * @param targetSw the switch for which the next-hops are desired
+     * @param dstSw the switch to which the next-hops lead to from the targetSw
+     * @return set of next hop deviceIds, could be empty if no next hops are found
+     */
+    private Set<DeviceId> getNextHops(DeviceId targetSw, DeviceId dstSw) {
+        boolean targetIsEdge = false;
+        try {
+            targetIsEdge = srManager.deviceConfiguration.isEdgeDevice(targetSw);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + "Cannot determine if targetIsEdge {}.. "
+                    + "continuing to getNextHops", targetSw);
+        }
+
+        EcmpShortestPathGraph ecmpSpg = updatedEcmpSpgMap.get(dstSw);
+        if (ecmpSpg == null) {
+            log.debug("No ecmpSpg found for dstSw: {}", dstSw);
+            return ImmutableSet.of();
+        }
+        HashMap<Integer,
+            HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia =
+                ecmpSpg.getAllLearnedSwitchesAndVia();
+        for (Integer itrIdx : switchVia.keySet()) {
+            HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap =
+                    switchVia.get(itrIdx);
+            for (DeviceId target : swViaMap.keySet()) {
+                if (!target.equals(targetSw)) {
+                    continue;
+                }
+                if (!targetIsEdge && itrIdx > 1) {
+                    // optimization for spines to not use other leaves to get
+                    // to a leaf to avoid loops
+                    log.debug("Avoiding {} hop path for non-edge targetSw:{}"
+                            + " --> dstSw:{}", itrIdx, targetSw, dstSw);
+                    break;
+                }
+                Set<DeviceId> nextHops = new HashSet<>();
+                for (ArrayList<DeviceId> via : swViaMap.get(targetSw)) {
+                    if (via.isEmpty()) {
+                        // the dstSw is the next-hop from the targetSw
+                        nextHops.add(dstSw);
+                    } else {
+                        // first elem is next-hop in each ECMP path
+                        nextHops.add(via.get(0));
+                    }
+                }
+                return nextHops;
+            }
+        }
+        return ImmutableSet.of(); //no next-hops found
+    }
+
+    /**
+     * Represents two devices that are paired by configuration. An EdgePair for
+     * (dev1, dev2) is the same as as EdgePair for (dev2, dev1)
+     */
+    protected final class EdgePair {
+        DeviceId dev1;
+        DeviceId dev2;
+
+        EdgePair(DeviceId dev1, DeviceId dev2) {
+            this.dev1 = dev1;
+            this.dev2 = dev2;
+        }
+
+        boolean includes(DeviceId dev) {
+            return dev1.equals(dev) || dev2.equals(dev);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof EdgePair)) {
+                return false;
+            }
+            EdgePair that = (EdgePair) o;
+            return ((this.dev1.equals(that.dev1) && this.dev2.equals(that.dev2)) ||
+                    (this.dev1.equals(that.dev2) && this.dev2.equals(that.dev1)));
+        }
+
+        @Override
+        public int hashCode() {
+            if (dev1.toString().compareTo(dev2.toString()) <= 0) {
+                return Objects.hash(dev1, dev2);
+            } else {
+                return Objects.hash(dev2, dev1);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return toStringHelper(this)
+                    .add("Dev1", dev1)
+                    .add("Dev2", dev2)
+                    .toString();
+        }
+    }
+
+    //////////////////////////////////////
+    //  Filtering rule creation
+    //////////////////////////////////////
+
+    /**
+     * Populates filtering rules for port, and punting rules
+     * for gateway IPs, loopback IPs and arp/ndp traffic.
+     * Should only be called by the master instance for this device/port.
+     *
+     * @param deviceId Switch ID to set the rules
+     */
+    public void populatePortAddressingRules(DeviceId deviceId) {
+        // Although device is added, sometimes device store does not have the
+        // ports for this device yet. It results in missing filtering rules in the
+        // switch. We will attempt it a few times. If it still does not work,
+        // user can manually repopulate using CLI command sr-reroute-network
+        PortFilterInfo firstRun = rulePopulator.populateVlanMacFilters(deviceId);
+        if (firstRun == null) {
+            firstRun = new PortFilterInfo(0, 0, 0);
+        }
+        executorService.schedule(new RetryFilters(deviceId, firstRun),
+                                 RETRY_INTERVAL_MS, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Utility class used to temporarily store information about the ports on a
+     * device processed for filtering objectives.
+     */
+    public final class PortFilterInfo {
+        int disabledPorts = 0, errorPorts = 0, filteredPorts = 0;
+
+        public PortFilterInfo(int disabledPorts, int errorPorts,
+                           int filteredPorts) {
+            this.disabledPorts = disabledPorts;
+            this.filteredPorts = filteredPorts;
+            this.errorPorts = errorPorts;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(disabledPorts, filteredPorts, errorPorts);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if ((obj == null) || (!(obj instanceof PortFilterInfo))) {
+                return false;
+            }
+            PortFilterInfo other = (PortFilterInfo) obj;
+            return ((disabledPorts == other.disabledPorts) &&
+                    (filteredPorts == other.filteredPorts) &&
+                    (errorPorts == other.errorPorts));
+        }
+
+        @Override
+        public String toString() {
+            MoreObjects.ToStringHelper helper = toStringHelper(this)
+                    .add("disabledPorts", disabledPorts)
+                    .add("errorPorts", errorPorts)
+                    .add("filteredPorts", filteredPorts);
+            return helper.toString();
+        }
+    }
+
+    /**
+     * RetryFilters populates filtering objectives for a device and keeps retrying
+     * till the number of ports filtered are constant for a predefined number
+     * of attempts.
+     */
+    protected final class RetryFilters implements Runnable {
+        int constantAttempts = MAX_CONSTANT_RETRY_ATTEMPTS;
+        DeviceId devId;
+        int counter;
+        PortFilterInfo prevRun;
+
+        private RetryFilters(DeviceId deviceId, PortFilterInfo previousRun) {
+            devId = deviceId;
+            prevRun = previousRun;
+            counter = 0;
+        }
+
+        @Override
+        public void run() {
+            log.debug("RETRY FILTER ATTEMPT {} ** dev:{}", ++counter, devId);
+            PortFilterInfo thisRun = rulePopulator.populateVlanMacFilters(devId);
+            boolean sameResult = prevRun.equals(thisRun);
+            log.debug("dev:{} prevRun:{} thisRun:{} sameResult:{}", devId, prevRun,
+                      thisRun, sameResult);
+            if (thisRun == null || !sameResult || (sameResult && --constantAttempts > 0)) {
+                // exponentially increasing intervals for retries
+                executorService.schedule(this,
+                    RETRY_INTERVAL_MS * (int) Math.pow(counter, RETRY_INTERVAL_SCALE),
+                    TimeUnit.MILLISECONDS);
+                if (!sameResult) {
+                    constantAttempts = MAX_CONSTANT_RETRY_ATTEMPTS; //reset
+                }
+            }
+            prevRun = (thisRun == null) ? prevRun : thisRun;
+        }
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/DefaultTunnel.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/DefaultTunnel.java
new file mode 100644
index 0000000..0fd7c077
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/DefaultTunnel.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2015-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;
+
+import java.util.List;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Default Tunnel class.
+ */
+public class DefaultTunnel implements Tunnel {
+
+    private final String id;
+    private final List<Integer> labelIds;
+
+    private int groupId;
+    private boolean allowedToRemoveGroup;
+
+    /**
+     * Creates a Tunnel reference.
+     *
+     * @param tid  Tunnel ID
+     * @param labelIds Label stack of the tunnel
+     */
+    public DefaultTunnel(String tid, List<Integer> labelIds) {
+        this.id = checkNotNull(tid);
+        this.labelIds = labelIds;
+        //TODO: need to register the class in Kryo for this
+        //this.labelIds = Collections.unmodifiableList(labelIds);
+        this.groupId = -1;
+    }
+
+    /**
+     * Creates a new DefaultTunnel reference using the tunnel reference.
+     *
+     * @param tunnel DefaultTunnel reference
+     */
+    public DefaultTunnel(DefaultTunnel tunnel) {
+        this.id = tunnel.id;
+        this.labelIds = tunnel.labelIds;
+        this.groupId = tunnel.groupId;
+    }
+
+    @Override
+    public String id() {
+        return this.id;
+    }
+
+    @Override
+    public List<Integer> labelIds() {
+        return this.labelIds;
+    }
+
+    @Override
+    public int groupId() {
+        return this.groupId;
+    }
+
+    @Override
+    public void setGroupId(int id) {
+        this.groupId = id;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o instanceof DefaultTunnel) {
+            DefaultTunnel tunnel = (DefaultTunnel) o;
+            // We compare only the tunnel paths.
+            if (tunnel.labelIds.equals(this.labelIds)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return labelIds.hashCode();
+    }
+
+    @Override
+    public boolean isAllowedToRemoveGroup() {
+        return this.allowedToRemoveGroup;
+    }
+
+    @Override
+    public void allowToRemoveGroup(boolean b) {
+        this.allowedToRemoveGroup = b;
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/EcmpShortestPathGraph.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/EcmpShortestPathGraph.java
new file mode 100644
index 0000000..c9bd596
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/EcmpShortestPathGraph.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2015-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;
+
+import org.onlab.graph.ScalarWeight;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Sets;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Set;
+
+/**
+ * This class creates breadth-first-search (BFS) tree for a given root device
+ * and returns paths from the root Device to leaf Devices (target devices).
+ * The paths are snapshot paths at the point of the class instantiation.
+ */
+public class EcmpShortestPathGraph {
+    LinkedList<DeviceId> deviceQueue = new LinkedList<>();
+    LinkedList<Integer> distanceQueue = new LinkedList<>();
+    HashMap<DeviceId, Integer> deviceSearched = new HashMap<>();
+    HashMap<DeviceId, ArrayList<Link>> upstreamLinks = new HashMap<>();
+    HashMap<DeviceId, ArrayList<Path>> paths = new HashMap<>();
+    HashMap<Integer, ArrayList<DeviceId>> distanceDeviceMap = new HashMap<>();
+    DeviceId rootDevice;
+    private SegmentRoutingManager srManager;
+    private static final Logger log = LoggerFactory.getLogger(EcmpShortestPathGraph.class);
+
+    /**
+     * Constructor.
+     *
+     * @param rootDevice root of the BFS tree
+     * @param srManager SegmentRoutingManager object
+     */
+    public EcmpShortestPathGraph(DeviceId rootDevice, SegmentRoutingManager srManager) {
+        this.rootDevice = rootDevice;
+        this.srManager = srManager;
+        calcECMPShortestPathGraph();
+    }
+
+    /**
+     * Calculates the BFS tree.
+     */
+   private void calcECMPShortestPathGraph() {
+        deviceQueue.add(rootDevice);
+        int currDistance = 0;
+        distanceQueue.add(currDistance);
+        deviceSearched.put(rootDevice, currDistance);
+        while (!deviceQueue.isEmpty()) {
+            DeviceId sw = deviceQueue.poll();
+            Set<DeviceId> prevSw = Sets.newHashSet();
+            currDistance = distanceQueue.poll();
+
+            for (Link link : srManager.linkService.getDeviceEgressLinks(sw)) {
+                if (srManager.linkHandler.avoidLink(link)) {
+                    continue;
+                }
+                DeviceId reachedDevice = link.dst().deviceId();
+                if (prevSw.contains(reachedDevice)) {
+                    // Ignore LAG links between the same set of Devices
+                    continue;
+                } else  {
+                    prevSw.add(reachedDevice);
+                }
+
+                Integer distance = deviceSearched.get(reachedDevice);
+                if ((distance != null) && (distance < (currDistance + 1))) {
+                    continue;
+                }
+                if (distance == null) {
+                    // First time visiting this Device node
+                    deviceQueue.add(reachedDevice);
+                    distanceQueue.add(currDistance + 1);
+                    deviceSearched.put(reachedDevice, currDistance + 1);
+
+                    ArrayList<DeviceId> distanceSwArray = distanceDeviceMap
+                            .get(currDistance + 1);
+                    if (distanceSwArray == null) {
+                        distanceSwArray = new ArrayList<>();
+                        distanceSwArray.add(reachedDevice);
+                        distanceDeviceMap.put(currDistance + 1, distanceSwArray);
+                    } else {
+                        distanceSwArray.add(reachedDevice);
+                    }
+                }
+
+                ArrayList<Link> upstreamLinkArray =
+                        upstreamLinks.get(reachedDevice);
+                if (upstreamLinkArray == null) {
+                    upstreamLinkArray = new ArrayList<>();
+                    upstreamLinkArray.add(copyDefaultLink(link));
+                    //upstreamLinkArray.add(link);
+                    upstreamLinks.put(reachedDevice, upstreamLinkArray);
+                } else {
+                    // ECMP links
+                    upstreamLinkArray.add(copyDefaultLink(link));
+                }
+            }
+        }
+    }
+
+    private void getDFSPaths(DeviceId dstDeviceDeviceId, Path path, ArrayList<Path> paths) {
+        DeviceId rootDeviceDeviceId = rootDevice;
+        for (Link upstreamLink : upstreamLinks.get(dstDeviceDeviceId)) {
+            /* Deep clone the path object */
+            Path sofarPath;
+            ArrayList<Link> sofarLinks = new ArrayList<>();
+            if (path != null && !path.links().isEmpty()) {
+                sofarLinks.addAll(path.links());
+            }
+            sofarLinks.add(upstreamLink);
+            sofarPath = new DefaultPath(ProviderId.NONE, sofarLinks, ScalarWeight.toWeight(0));
+            if (upstreamLink.src().deviceId().equals(rootDeviceDeviceId)) {
+                paths.add(sofarPath);
+                return;
+            } else {
+                getDFSPaths(upstreamLink.src().deviceId(), sofarPath, paths);
+            }
+        }
+    }
+
+    /**
+     * Return root Device for the graph.
+     *
+     * @return root Device
+     */
+    public DeviceId getRootDevice() {
+        return rootDevice;
+    }
+
+    /**
+     * Return the computed ECMP paths from the root Device to a given Device in
+     * the network.
+     *
+     * @param targetDevice the target Device
+     * @return the list of ECMP Paths from the root Device to the target Device
+     */
+    public ArrayList<Path> getECMPPaths(DeviceId targetDevice) {
+        ArrayList<Path> pathArray = paths.get(targetDevice);
+        if (pathArray == null && deviceSearched.containsKey(
+                targetDevice)) {
+            pathArray = new ArrayList<>();
+            DeviceId sw = targetDevice;
+            getDFSPaths(sw, null, pathArray);
+            paths.put(targetDevice, pathArray);
+        }
+        return pathArray;
+    }
+
+    /**
+     * Return the complete info of the computed ECMP paths for each Device
+     * learned in multiple iterations from the root Device.
+     *
+     * @return the hash table of Devices learned in multiple Dijkstra
+     *         iterations and corresponding ECMP paths to it from the root
+     *         Device
+     */
+    public HashMap<Integer, HashMap<DeviceId,
+            ArrayList<Path>>> getCompleteLearnedDeviceesAndPaths() {
+
+        HashMap<Integer, HashMap<DeviceId, ArrayList<Path>>> pathGraph = new HashMap<>();
+
+        for (Integer itrIndx : distanceDeviceMap.keySet()) {
+            HashMap<DeviceId, ArrayList<Path>> swMap = new HashMap<>();
+            for (DeviceId sw : distanceDeviceMap.get(itrIndx)) {
+                swMap.put(sw, getECMPPaths(sw));
+            }
+            pathGraph.put(itrIndx, swMap);
+        }
+
+        return pathGraph;
+    }
+
+    /**
+     * Returns the complete info of the computed ECMP paths for each target device
+     * learned in multiple iterations from the root Device. The computed info
+     * returned is per iteration (Integer key of outer HashMap). In each
+     * iteration, for the target devices reached (DeviceId key of inner HashMap),
+     * the ECMP paths are detailed (2D array).
+     *
+     * @return the hash table of target Devices learned in multiple Dijkstra
+     *         iterations and corresponding ECMP paths in terms of Devices to
+     *         be traversed (via) from the root Device to the target Device
+     */
+    public HashMap<Integer, HashMap<DeviceId,
+            ArrayList<ArrayList<DeviceId>>>> getAllLearnedSwitchesAndVia() {
+
+        HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> deviceViaMap = new HashMap<>();
+
+        for (Integer itrIndx : distanceDeviceMap.keySet()) {
+            HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swMap = new HashMap<>();
+
+            for (DeviceId sw : distanceDeviceMap.get(itrIndx)) {
+                ArrayList<ArrayList<DeviceId>> swViaArray = new ArrayList<>();
+                for (Path path : getECMPPaths(sw)) {
+                    ArrayList<DeviceId> swVia = new ArrayList<>();
+                    for (Link link : path.links()) {
+                        if (link.src().deviceId().equals(rootDevice)) {
+                            /* No need to add the root Device again in
+                             * the Via list
+                             */
+                            continue;
+                        }
+                        swVia.add(link.src().deviceId());
+                    }
+                    swViaArray.add(swVia);
+                }
+                swMap.put(sw, swViaArray);
+            }
+            deviceViaMap.put(itrIndx, swMap);
+        }
+        return deviceViaMap;
+    }
+
+
+    private Link copyDefaultLink(Link link) {
+        DefaultLink src = (DefaultLink) link;
+        DefaultLink defaultLink = DefaultLink.builder()
+                .providerId(src.providerId())
+                .src(src.src())
+                .dst(src.dst())
+                .type(src.type())
+                .annotations(src.annotations())
+                .build();
+
+        return defaultLink;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sBuilder = new StringBuilder();
+        for (Device device: srManager.deviceService.getDevices()) {
+            if (!device.id().equals(rootDevice)) {
+                sBuilder.append("\r\n  Paths from " + rootDevice + " to "
+                                + device.id());
+                ArrayList<Path> paths = getECMPPaths(device.id());
+                if (paths != null) {
+                    for (Path path : paths) {
+                        sBuilder.append("\r\n       == "); // equal cost paths delimiter
+                        for (int i = path.links().size() - 1; i >= 0; i--) {
+                            Link link = path.links().get(i);
+                            sBuilder.append(" : " + link.src() + " -> " + link.dst());
+                        }
+                    }
+                } else {
+                    sBuilder.append("\r\n       == no paths");
+                }
+            }
+        }
+        return sBuilder.toString();
+    }
+}
+
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
new file mode 100644
index 0000000..908a339
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
@@ -0,0 +1,680 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostLocation;
+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.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultObjectiveContext;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostLocationProbingService.ProbeMode;
+import org.onosproject.net.host.HostService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Sets;
+
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Handles host-related events.
+ */
+public class HostHandler {
+    private static final Logger log = LoggerFactory.getLogger(HostHandler.class);
+    static final int HOST_MOVED_DELAY_MS = 1000;
+
+    protected final SegmentRoutingManager srManager;
+    private HostService hostService;
+    private FlowObjectiveService flowObjectiveService;
+
+    /**
+     * Constructs the HostHandler.
+     *
+     * @param srManager Segment Routing manager
+     */
+    HostHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        hostService = srManager.hostService;
+        flowObjectiveService = srManager.flowObjectiveService;
+    }
+
+    protected void init(DeviceId devId) {
+        hostService.getHosts().forEach(host ->
+            host.locations().stream()
+                    .filter(location -> location.deviceId().equals(devId) ||
+                            location.deviceId().equals(srManager.getPairDeviceId(devId).orElse(null)))
+                    .forEach(location -> processHostAddedAtLocation(host, location))
+        );
+    }
+
+    void processHostAddedEvent(HostEvent event) {
+        processHostAdded(event.subject());
+    }
+
+    private void processHostAdded(Host host) {
+        host.locations().forEach(location -> processHostAddedAtLocation(host, location));
+        // ensure dual-homed host locations have viable uplinks
+        if (host.locations().size() > 1) {
+            host.locations().forEach(loc -> {
+                if (srManager.mastershipService.isLocalMaster(loc.deviceId())) {
+                    srManager.linkHandler.checkUplinksForDualHomedHosts(loc);
+                }
+            });
+        }
+    }
+
+    void processHostAddedAtLocation(Host host, HostLocation location) {
+        checkArgument(host.locations().contains(location), "{} is not a location of {}", location, host);
+
+        MacAddress hostMac = host.mac();
+        VlanId hostVlanId = host.vlan();
+        Set<HostLocation> locations = host.locations();
+        Set<IpAddress> ips = host.ipAddresses();
+        log.info("Host {}/{} is added at {}", hostMac, hostVlanId, locations);
+
+        if (srManager.isMasterOf(location)) {
+            processBridgingRule(location.deviceId(), location.port(), hostMac, hostVlanId, false);
+            ips.forEach(ip ->
+                    processRoutingRule(location.deviceId(), location.port(), hostMac, hostVlanId, ip, false)
+            );
+        }
+
+        // Use the pair link temporarily before the second location of a dual-homed host shows up.
+        // This do not affect single-homed hosts since the flow will be blocked in
+        // processBridgingRule or processRoutingRule due to VLAN or IP mismatch respectively
+        srManager.getPairDeviceId(location.deviceId()).ifPresent(pairDeviceId -> {
+            if (srManager.mastershipService.isLocalMaster(pairDeviceId) &&
+                    host.locations().stream().noneMatch(l -> l.deviceId().equals(pairDeviceId))) {
+                srManager.getPairLocalPorts(pairDeviceId).ifPresent(pairRemotePort -> {
+                    // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
+                    //       when the host is untagged
+                    VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(location)).orElse(hostVlanId);
+
+                    processBridgingRule(pairDeviceId, pairRemotePort, hostMac, vlanId, false);
+                    ips.forEach(ip -> processRoutingRule(pairDeviceId, pairRemotePort, hostMac, vlanId,
+                                    ip, false));
+
+                    if (srManager.activeProbing) {
+                        probe(host, location, pairDeviceId, pairRemotePort);
+                    }
+                });
+            }
+        });
+    }
+
+    void processHostRemovedEvent(HostEvent event) {
+        processHostRemoved(event.subject());
+    }
+
+    private void processHostRemoved(Host host) {
+        MacAddress hostMac = host.mac();
+        VlanId hostVlanId = host.vlan();
+        Set<HostLocation> locations = host.locations();
+        Set<IpAddress> ips = host.ipAddresses();
+        log.info("Host {}/{} is removed from {}", hostMac, hostVlanId, locations);
+
+        locations.forEach(location -> {
+            if (srManager.isMasterOf(location)) {
+                processBridgingRule(location.deviceId(), location.port(), hostMac, hostVlanId, true);
+                ips.forEach(ip ->
+                        processRoutingRule(location.deviceId(), location.port(), hostMac, hostVlanId, ip, true)
+                );
+            }
+
+            // Also remove redirection flows on the pair device if exists.
+            Optional<DeviceId> pairDeviceId = srManager.getPairDeviceId(location.deviceId());
+            Optional<PortNumber> pairLocalPort = srManager.getPairLocalPorts(location.deviceId());
+            if (pairDeviceId.isPresent() && pairLocalPort.isPresent() &&
+                    srManager.mastershipService.isLocalMaster(pairDeviceId.get())) {
+                // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
+                //       when the host is untagged
+                VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(location)).orElse(hostVlanId);
+
+                processBridgingRule(pairDeviceId.get(), pairLocalPort.get(), hostMac, vlanId, true);
+                ips.forEach(ip ->
+                        processRoutingRule(pairDeviceId.get(), pairLocalPort.get(), hostMac, vlanId,
+                                ip, true));
+            }
+        });
+    }
+
+    void processHostMovedEvent(HostEvent event) {
+        MacAddress hostMac = event.subject().mac();
+        VlanId hostVlanId = event.subject().vlan();
+        Set<HostLocation> prevLocations = event.prevSubject().locations();
+        Set<IpAddress> prevIps = event.prevSubject().ipAddresses();
+        Set<HostLocation> newLocations = event.subject().locations();
+        Set<IpAddress> newIps = event.subject().ipAddresses();
+
+        // FIXME: Delay event handling a little bit to wait for the previous redirection flows to be completed
+        //        The permanent solution would be introducing CompletableFuture and wait for it
+        if (prevLocations.size() == 1 && newLocations.size() == 2) {
+            log.debug("Delay event handling when host {}/{} moves from 1 to 2 locations", hostMac, hostVlanId);
+            ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
+            executorService.schedule(() ->
+                    processHostMoved(hostMac, hostVlanId, prevLocations, prevIps, newLocations, newIps),
+                    HOST_MOVED_DELAY_MS, TimeUnit.MILLISECONDS);
+        } else {
+            processHostMoved(hostMac, hostVlanId, prevLocations, prevIps, newLocations, newIps);
+        }
+    }
+
+    private void processHostMoved(MacAddress hostMac, VlanId hostVlanId, Set<HostLocation> prevLocations,
+                                  Set<IpAddress> prevIps, Set<HostLocation> newLocations, Set<IpAddress> newIps) {
+        log.info("Host {}/{} is moved from {} to {}", hostMac, hostVlanId, prevLocations, newLocations);
+        Set<DeviceId> newDeviceIds = newLocations.stream().map(HostLocation::deviceId)
+                .collect(Collectors.toSet());
+
+        // For each old location
+        Sets.difference(prevLocations, newLocations).stream().filter(srManager::isMasterOf)
+                .forEach(prevLocation -> {
+            // Remove routing rules for old IPs
+            Sets.difference(prevIps, newIps).forEach(ip ->
+                    processRoutingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId,
+                            ip, true)
+            );
+
+            // Redirect the flows to pair link if configured
+            // Note: Do not continue removing any rule
+            Optional<DeviceId> pairDeviceId = srManager.getPairDeviceId(prevLocation.deviceId());
+            Optional<PortNumber> pairLocalPort = srManager.getPairLocalPorts(prevLocation.deviceId());
+            if (pairDeviceId.isPresent() && pairLocalPort.isPresent() && newLocations.stream()
+                    .anyMatch(location -> location.deviceId().equals(pairDeviceId.get()))) {
+                // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
+                //       when the host is untagged
+                VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(prevLocation)).orElse(hostVlanId);
+
+                processBridgingRule(prevLocation.deviceId(), pairLocalPort.get(), hostMac, vlanId, false);
+                newIps.forEach(ip ->
+                        processRoutingRule(prevLocation.deviceId(), pairLocalPort.get(), hostMac, vlanId,
+                            ip, false));
+                return;
+            }
+
+            // Remove bridging rule and routing rules for unchanged IPs if the host moves from a switch to another.
+            // Otherwise, do not remove and let the adding part update the old flow
+            if (!newDeviceIds.contains(prevLocation.deviceId())) {
+                processBridgingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId, true);
+                Sets.intersection(prevIps, newIps).forEach(ip ->
+                        processRoutingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId,
+                                ip, true)
+                );
+            }
+
+            // Remove bridging rules if new interface vlan is different from old interface vlan
+            // Otherwise, do not remove and let the adding part update the old flow
+            if (newLocations.stream().noneMatch(newLocation -> {
+                VlanId oldAssignedVlan = srManager.getInternalVlanId(prevLocation);
+                VlanId newAssignedVlan = srManager.getInternalVlanId(newLocation);
+                // Host is tagged and the new location has the host vlan in vlan-tagged
+                return srManager.getTaggedVlanId(newLocation).contains(hostVlanId) ||
+                        (oldAssignedVlan != null && newAssignedVlan != null &&
+                        // Host is untagged and the new location has the same assigned vlan
+                        oldAssignedVlan.equals(newAssignedVlan));
+            })) {
+                processBridgingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId, true);
+            }
+
+            // Remove routing rules for unchanged IPs if none of the subnet of new location contains
+            // the IP. Otherwise, do not remove and let the adding part update the old flow
+            Sets.intersection(prevIps, newIps).forEach(ip -> {
+                if (newLocations.stream().noneMatch(newLocation ->
+                        srManager.deviceConfiguration.inSameSubnet(newLocation, ip))) {
+                    processRoutingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId,
+                            ip, true);
+                }
+            });
+        });
+
+        // For each new location, add all new IPs.
+        Sets.difference(newLocations, prevLocations).stream().filter(srManager::isMasterOf)
+                .forEach(newLocation -> {
+            processBridgingRule(newLocation.deviceId(), newLocation.port(), hostMac, hostVlanId, false);
+            newIps.forEach(ip ->
+                    processRoutingRule(newLocation.deviceId(), newLocation.port(), hostMac, hostVlanId,
+                            ip, false)
+            );
+        });
+
+        // For each unchanged location, add new IPs and remove old IPs.
+        Sets.intersection(newLocations, prevLocations).stream().filter(srManager::isMasterOf)
+                .forEach(unchangedLocation -> {
+            Sets.difference(prevIps, newIps).forEach(ip ->
+                    processRoutingRule(unchangedLocation.deviceId(), unchangedLocation.port(), hostMac,
+                            hostVlanId, ip, true)
+            );
+
+            Sets.difference(newIps, prevIps).forEach(ip ->
+                    processRoutingRule(unchangedLocation.deviceId(), unchangedLocation.port(), hostMac,
+                        hostVlanId, ip, false)
+            );
+        });
+
+        // ensure dual-homed host locations have viable uplinks
+        if (newLocations.size() > prevLocations.size()) {
+            newLocations.forEach(loc -> {
+                if (srManager.mastershipService.isLocalMaster(loc.deviceId())) {
+                    srManager.linkHandler.checkUplinksForDualHomedHosts(loc);
+                }
+            });
+        }
+    }
+
+    void processHostUpdatedEvent(HostEvent event) {
+        Host host = event.subject();
+        MacAddress hostMac = host.mac();
+        VlanId hostVlanId = host.vlan();
+        Set<HostLocation> locations = host.locations();
+        Set<IpAddress> prevIps = event.prevSubject().ipAddresses();
+        Set<IpAddress> newIps = host.ipAddresses();
+        log.info("Host {}/{} is updated", hostMac, hostVlanId);
+
+        locations.stream().filter(srManager::isMasterOf).forEach(location -> {
+            Sets.difference(prevIps, newIps).forEach(ip ->
+                    processRoutingRule(location.deviceId(), location.port(), hostMac, hostVlanId, ip, true)
+            );
+            Sets.difference(newIps, prevIps).forEach(ip ->
+                    processRoutingRule(location.deviceId(), location.port(), hostMac, hostVlanId, ip, false)
+            );
+        });
+
+        // Use the pair link temporarily before the second location of a dual-homed host shows up.
+        // This do not affect single-homed hosts since the flow will be blocked in
+        // processBridgingRule or processRoutingRule due to VLAN or IP mismatch respectively
+        locations.forEach(location ->
+            srManager.getPairDeviceId(location.deviceId()).ifPresent(pairDeviceId -> {
+                if (srManager.mastershipService.isLocalMaster(pairDeviceId) &&
+                        locations.stream().noneMatch(l -> l.deviceId().equals(pairDeviceId))) {
+                    Set<IpAddress> ipsToAdd = Sets.difference(newIps, prevIps);
+                    Set<IpAddress> ipsToRemove = Sets.difference(prevIps, newIps);
+
+                    srManager.getPairLocalPorts(pairDeviceId).ifPresent(pairRemotePort -> {
+                        // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
+                        //       when the host is untagged
+                        VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(location)).orElse(hostVlanId);
+
+                        ipsToRemove.forEach(ip ->
+                                processRoutingRule(pairDeviceId, pairRemotePort, hostMac, vlanId, ip, true)
+                        );
+                        ipsToAdd.forEach(ip ->
+                                processRoutingRule(pairDeviceId, pairRemotePort, hostMac, vlanId, ip, false)
+                        );
+
+                        if (srManager.activeProbing) {
+                            probe(host, location, pairDeviceId, pairRemotePort);
+                        }
+                    });
+                }
+            })
+        );
+    }
+
+    /**
+     * When a non-pair port comes up, probe each host on the pair device if
+     * (1) the host is tagged and the tagged vlan of current port contains host vlan; or
+     * (2) the host is untagged and the internal vlan is the same on the host port and current port.
+     *
+     * @param cp connect point
+     */
+    void processPortUp(ConnectPoint cp) {
+        if (cp.port().equals(srManager.getPairLocalPorts(cp.deviceId()).orElse(null))) {
+            return;
+        }
+        if (srManager.activeProbing) {
+            srManager.getPairDeviceId(cp.deviceId())
+                    .ifPresent(pairDeviceId -> srManager.hostService.getConnectedHosts(pairDeviceId).stream()
+                            .filter(host -> isHostInVlanOfPort(host, pairDeviceId, cp))
+                            .forEach(host -> srManager.probingService.probeHostLocation(host, cp, ProbeMode.DISCOVER))
+                    );
+        }
+    }
+
+    /**
+     * Checks if given host located on given device id matches VLAN config of current port.
+     *
+     * @param host host to check
+     * @param deviceId device id to check
+     * @param cp current connect point
+     * @return true if the host located at deviceId matches the VLAN config on cp
+     */
+    private boolean isHostInVlanOfPort(Host host, DeviceId deviceId, ConnectPoint cp) {
+        VlanId internalVlan = srManager.getInternalVlanId(cp);
+        Set<VlanId> taggedVlan = srManager.getTaggedVlanId(cp);
+
+        return taggedVlan.contains(host.vlan()) ||
+                (internalVlan != null && host.locations().stream()
+                        .filter(l -> l.deviceId().equals(deviceId))
+                        .map(srManager::getInternalVlanId)
+                        .anyMatch(internalVlan::equals));
+    }
+
+    /**
+     * Send a probe on all locations with the same VLAN on pair device, excluding pair port.
+     *
+     * @param host host to probe
+     * @param location newly discovered host location
+     * @param pairDeviceId pair device id
+     * @param pairRemotePort pair remote port
+     */
+    private void probe(Host host, ConnectPoint location, DeviceId pairDeviceId, PortNumber pairRemotePort) {
+        VlanId vlanToProbe = host.vlan().equals(VlanId.NONE) ?
+                srManager.getInternalVlanId(location) : host.vlan();
+        srManager.interfaceService.getInterfaces().stream()
+                .filter(i -> i.vlanTagged().contains(vlanToProbe) ||
+                        i.vlanUntagged().equals(vlanToProbe) ||
+                        i.vlanNative().equals(vlanToProbe))
+                .filter(i -> i.connectPoint().deviceId().equals(pairDeviceId))
+                .filter(i -> !i.connectPoint().port().equals(pairRemotePort))
+                .forEach(i -> {
+                    log.debug("Probing host {} on pair device {}", host.id(), i.connectPoint());
+                    srManager.probingService.probeHostLocation(host, i.connectPoint(), ProbeMode.DISCOVER);
+                });
+    }
+
+    /**
+     * Generates a forwarding objective builder for bridging rules.
+     * <p>
+     * The forwarding objective bridges packets destined to a given MAC to
+     * given port on given device.
+     *
+     * @param deviceId Device that host attaches to
+     * @param mac MAC address of the host
+     * @param hostVlanId VLAN ID of the host
+     * @param outport Port that host attaches to
+     * @param revoke true if forwarding objective is meant to revoke forwarding rule
+     * @return Forwarding objective builder
+     */
+    ForwardingObjective.Builder bridgingFwdObjBuilder(
+            DeviceId deviceId, MacAddress mac, VlanId hostVlanId,
+            PortNumber outport, boolean revoke) {
+        ConnectPoint connectPoint = new ConnectPoint(deviceId, outport);
+        VlanId untaggedVlan = srManager.getUntaggedVlanId(connectPoint);
+        Set<VlanId> taggedVlans = srManager.getTaggedVlanId(connectPoint);
+        VlanId nativeVlan = srManager.getNativeVlanId(connectPoint);
+
+        // Create host selector
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        sbuilder.matchEthDst(mac);
+
+        // Create host treatment
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+        tbuilder.immediate().setOutput(outport);
+
+        // Create host meta
+        TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
+
+        // Adjust the selector, treatment and meta according to VLAN configuration
+        if (taggedVlans.contains(hostVlanId)) {
+            sbuilder.matchVlanId(hostVlanId);
+            mbuilder.matchVlanId(hostVlanId);
+        } else if (hostVlanId.equals(VlanId.NONE)) {
+            if (untaggedVlan != null) {
+                sbuilder.matchVlanId(untaggedVlan);
+                mbuilder.matchVlanId(untaggedVlan);
+                tbuilder.immediate().popVlan();
+            } else if (nativeVlan != null) {
+                sbuilder.matchVlanId(nativeVlan);
+                mbuilder.matchVlanId(nativeVlan);
+                tbuilder.immediate().popVlan();
+            } else {
+                log.warn("Untagged host {}/{} is not allowed on {} without untagged or native" +
+                        "vlan config", mac, hostVlanId, connectPoint);
+                return null;
+            }
+        } else {
+            log.warn("Tagged host {}/{} is not allowed on {} without VLAN listed in tagged vlan",
+                    mac, hostVlanId, connectPoint);
+            return null;
+        }
+
+        // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed.
+        // If the objective is to revoke an existing rule, and for some reason
+        // the next-objective does not exist, then a new one should not be created
+        int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outport,
+                tbuilder.build(), mbuilder.build(), !revoke);
+        if (portNextObjId == -1) {
+            // Warning log will come from getPortNextObjective method
+            return null;
+        }
+
+        return DefaultForwardingObjective.builder()
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .withSelector(sbuilder.build())
+                .nextStep(portNextObjId)
+                .withPriority(100)
+                .fromApp(srManager.appId)
+                .makePermanent();
+    }
+
+    /**
+     * Populate or revoke a bridging rule on given deviceId that matches given mac, given vlan and
+     * output to given port.
+     *
+     * @param deviceId device ID
+     * @param port port
+     * @param mac mac address
+     * @param vlanId VLAN ID
+     * @param revoke true to revoke the rule; false to populate
+     */
+    private void processBridgingRule(DeviceId deviceId, PortNumber port, MacAddress mac,
+                                     VlanId vlanId, boolean revoke) {
+        log.debug("{} bridging entry for host {}/{} at {}:{}", revoke ? "Revoking" : "Populating",
+                mac, vlanId, deviceId, port);
+
+        ForwardingObjective.Builder fob = bridgingFwdObjBuilder(deviceId, mac, vlanId, port, revoke);
+        if (fob == null) {
+            log.warn("Fail to build fwd obj for host {}/{}. Abort.", mac, vlanId);
+            return;
+        }
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("Brigding rule for {}/{} {}", mac, vlanId,
+                        revoke ? "revoked" : "populated"),
+                (objective, error) -> log.warn("Failed to {} bridging rule for {}/{}: {}",
+                        revoke ? "revoked" : "populated", mac, vlanId, error));
+        flowObjectiveService.forward(deviceId, revoke ? fob.remove(context) : fob.add(context));
+    }
+
+    /**
+     * Populate or revoke a routing rule on given deviceId that matches given ip,
+     * set destination mac to given mac, set vlan to given vlan and output to given port.
+     *
+     * @param deviceId device ID
+     * @param port port
+     * @param mac mac address
+     * @param vlanId VLAN ID
+     * @param ip IP address
+     * @param revoke true to revoke the rule; false to populate
+     */
+    private void processRoutingRule(DeviceId deviceId, PortNumber port, MacAddress mac,
+                                    VlanId vlanId, IpAddress ip, boolean revoke) {
+        ConnectPoint location = new ConnectPoint(deviceId, port);
+        if (!srManager.deviceConfiguration.inSameSubnet(location, ip)) {
+            log.info("{} is not included in the subnet config of {}/{}. Ignored.", ip, deviceId, port);
+            return;
+        }
+
+        log.info("{} routing rule for {} at {}", revoke ? "Revoking" : "Populating", ip, location);
+        if (revoke) {
+            srManager.defaultRoutingHandler.revokeRoute(deviceId, ip.toIpPrefix(), mac, vlanId, port);
+        } else {
+            srManager.defaultRoutingHandler.populateRoute(deviceId, ip.toIpPrefix(), mac, vlanId, port);
+        }
+    }
+
+    /**
+     * Populate or revoke a bridging rule on given deviceId that matches given vlanId,
+     * and hostMAC connected to given port, and output to given port only when
+     * vlan information is valid.
+     *
+     * @param deviceId device ID that host attaches to
+     * @param portNum port number that host attaches to
+     * @param hostMac mac address of the host connected to the switch port
+     * @param vlanId Vlan ID configured on the switch port
+     * @param popVlan true to pop Vlan tag at TrafficTreatment, false otherwise
+     * @param install true to populate the objective, false to revoke
+     */
+    private void updateBridgingRule(DeviceId deviceId, PortNumber portNum, MacAddress hostMac,
+                            VlanId vlanId, boolean popVlan, boolean install) {
+        // Create host selector
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        sbuilder.matchEthDst(hostMac);
+
+        // Create host meta
+        TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
+
+        sbuilder.matchVlanId(vlanId);
+        mbuilder.matchVlanId(vlanId);
+
+        // Create host treatment
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+        tbuilder.immediate().setOutput(portNum);
+
+        if (popVlan) {
+            tbuilder.immediate().popVlan();
+        }
+
+        int portNextObjId = srManager.getPortNextObjectiveId(deviceId, portNum,
+                                                             tbuilder.build(), mbuilder.build(), install);
+        if (portNextObjId != -1) {
+            ForwardingObjective.Builder fob = DefaultForwardingObjective.builder()
+                    .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                    .withSelector(sbuilder.build())
+                    .nextStep(portNextObjId)
+                    .withPriority(100)
+                    .fromApp(srManager.appId)
+                    .makePermanent();
+
+            ObjectiveContext context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("Brigding rule for {}/{} {}", hostMac, vlanId,
+                                             install ? "populated" : "revoked"),
+                    (objective, error) -> log.warn("Failed to {} bridging rule for {}/{}: {}",
+                                                   install ? "populate" : "revoke", hostMac, vlanId, error));
+            flowObjectiveService.forward(deviceId, install ? fob.add(context) : fob.remove(context));
+        } else {
+            log.warn("Failed to retrieve next objective for {}/{}", hostMac, vlanId);
+        }
+    }
+
+    /**
+     * Update forwarding objective for unicast bridging and unicast routing.
+     * Also check the validity of updated interface configuration on VLAN.
+     *
+     * @param deviceId device ID that host attaches to
+     * @param portNum port number that host attaches to
+     * @param vlanId Vlan ID configured on the switch port
+     * @param popVlan true to pop Vlan tag at TrafficTreatment, false otherwise
+     * @param install true to populate the objective, false to revoke
+     */
+    void processIntfVlanUpdatedEvent(DeviceId deviceId, PortNumber portNum, VlanId vlanId,
+                                 boolean popVlan, boolean install) {
+        ConnectPoint connectPoint = new ConnectPoint(deviceId, portNum);
+        Set<Host> hosts = hostService.getConnectedHosts(connectPoint);
+
+        if (hosts == null || hosts.size() == 0) {
+            return;
+        }
+
+        hosts.forEach(host -> {
+            MacAddress mac = host.mac();
+            VlanId hostVlanId = host.vlan();
+
+            // Check whether the host vlan is valid for new interface configuration
+            if ((!popVlan && hostVlanId.equals(vlanId)) ||
+                    (popVlan && hostVlanId.equals(VlanId.NONE))) {
+                updateBridgingRule(deviceId, portNum, mac, vlanId, popVlan, install);
+                // Update Forwarding objective and corresponding simple Next objective
+                // for each host and IP address connected to given port
+                host.ipAddresses().forEach(ipAddress ->
+                    srManager.routingRulePopulator.updateFwdObj(deviceId, portNum, ipAddress.toIpPrefix(),
+                                                                mac, vlanId, popVlan, install)
+                );
+            }
+        });
+    }
+
+    /**
+     * Populate or revoke routing rule for each host, according to the updated
+     * subnet configuration on the interface.
+     * @param cp connect point of the updated interface
+     * @param ipPrefixSet IP Prefixes added or removed
+     * @param install true if IP Prefixes added, false otherwise
+     */
+    void processIntfIpUpdatedEvent(ConnectPoint cp, Set<IpPrefix> ipPrefixSet, boolean install) {
+        Set<Host> hosts = hostService.getConnectedHosts(cp);
+
+        if (hosts == null || hosts.size() == 0) {
+            log.warn("processIntfIpUpdatedEvent: No hosts connected to {}", cp);
+            return;
+        }
+
+        // Check whether the host IP address is in the interface's subnet
+        hosts.forEach(host ->
+            host.ipAddresses().forEach(hostIpAddress -> {
+                ipPrefixSet.forEach(ipPrefix -> {
+                    if (install && ipPrefix.contains(hostIpAddress)) {
+                            srManager.routingRulePopulator.populateRoute(cp.deviceId(), hostIpAddress.toIpPrefix(),
+                                                                         host.mac(), host.vlan(), cp.port());
+                    } else if (!install && ipPrefix.contains(hostIpAddress)) {
+                            srManager.routingRulePopulator.revokeRoute(cp.deviceId(), hostIpAddress.toIpPrefix(),
+                                                                       host.mac(), host.vlan(), cp.port());
+                    }
+                });
+            }));
+    }
+
+    /**
+     * Returns the set of portnumbers on the given device that are part of the
+     * locations for dual-homed hosts.
+     *
+     * @param deviceId the given deviceId
+     * @return set of port numbers on given device that are dual-homed host
+     *         locations. May be empty if no dual homed hosts are connected to
+     *         the given device
+     */
+    Set<PortNumber> getDualHomedHostPorts(DeviceId deviceId) {
+        Set<PortNumber> dualHomedLocations = new HashSet<>();
+        srManager.hostService.getConnectedHosts(deviceId).stream()
+            .filter(host -> host.locations().size() == 2)
+            .forEach(host -> host.locations().stream()
+                     .filter(loc -> loc.deviceId().equals(deviceId))
+                        .forEach(loc -> dualHomedLocations.add(loc.port())));
+        return dualHomedLocations;
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
new file mode 100644
index 0000000..8228bb5
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
@@ -0,0 +1,466 @@
+/*
+ * Copyright 2015-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;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MPLS;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.ndp.NeighborSolicitation;
+import org.onosproject.net.neighbour.NeighbourMessageContext;
+import org.onosproject.net.neighbour.NeighbourMessageType;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * Handler of ICMP packets that responses or forwards ICMP packets that
+ * are sent to the controller.
+ */
+public class IcmpHandler extends SegmentRoutingNeighbourHandler {
+
+    private static Logger log = LoggerFactory.getLogger(IcmpHandler.class);
+
+    /**
+     * Creates an IcmpHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public IcmpHandler(SegmentRoutingManager srManager) {
+        super(srManager);
+    }
+
+    /**
+     * Utility function to send packet out.
+     *
+     * @param outport the output port
+     * @param payload the packet to send
+     * @param sid the segment id
+     * @param destIpAddress the destination ip address
+     * @param allowedHops the hop limit/ttl
+     */
+    private void sendPacketOut(ConnectPoint outport,
+                               Ethernet payload,
+                               int sid,
+                               IpAddress destIpAddress,
+                               byte allowedHops) {
+        int destSid;
+        if (destIpAddress.isIp4()) {
+            destSid = config.getIPv4SegmentId(payload.getDestinationMAC());
+        } else {
+            destSid = config.getIPv6SegmentId(payload.getDestinationMAC());
+        }
+
+        if (sid == -1 || destSid == sid ||
+                config.inSameSubnet(outport.deviceId(), destIpAddress)) {
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().
+                    setOutput(outport.port()).build();
+            OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
+                                                              treatment, ByteBuffer.wrap(payload.serialize()));
+            srManager.packetService.emit(packet);
+        } else {
+            log.trace("Send a MPLS packet as a ICMP response");
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(outport.port())
+                    .build();
+
+            payload.setEtherType(Ethernet.MPLS_UNICAST);
+            MPLS mplsPkt = new MPLS();
+            mplsPkt.setLabel(sid);
+            mplsPkt.setTtl(allowedHops);
+            mplsPkt.setPayload(payload.getPayload());
+            payload.setPayload(mplsPkt);
+
+            OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
+                                                              treatment, ByteBuffer.wrap(payload.serialize()));
+
+            srManager.packetService.emit(packet);
+        }
+    }
+
+    //////////////////////////////////////
+    //     ICMP Echo/Reply Protocol     //
+    //////////////////////////////////////
+
+    /**
+     * Process incoming ICMP packet.
+     * If it is an ICMP request to router, then sends an ICMP response.
+     * Otherwise ignore the packet.
+     *
+     * @param eth inbound ICMP packet
+     * @param inPort the input port
+     */
+    public void processIcmp(Ethernet eth, ConnectPoint inPort) {
+        DeviceId deviceId = inPort.deviceId();
+        IPv4 ipv4Packet = (IPv4) eth.getPayload();
+        Ip4Address destinationAddress = Ip4Address.valueOf(ipv4Packet.getDestinationAddress());
+        Set<IpAddress> gatewayIpAddresses = config.getPortIPs(deviceId);
+        IpAddress routerIp;
+        try {
+            routerIp = config.getRouterIpv4(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting processPacketIn.");
+            return;
+        }
+        // ICMP to the router IP or gateway IP
+        if (((ICMP) ipv4Packet.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST &&
+                (destinationAddress.equals(routerIp.getIp4Address()) ||
+                        gatewayIpAddresses.contains(destinationAddress))) {
+            sendIcmpResponse(eth, inPort);
+        } else {
+            log.trace("Ignore ICMP that targets for {}", destinationAddress);
+        }
+        // We remove the packet from the queue
+        srManager.ipHandler.dequeuePacket(ipv4Packet, destinationAddress);
+    }
+
+    /**
+     * Sends an ICMP reply message.
+     *
+     * @param icmpRequest the original ICMP request
+     * @param outport the output port where the ICMP reply should be sent to
+     */
+    private void sendIcmpResponse(Ethernet icmpRequest, ConnectPoint outport) {
+        Ethernet icmpReplyEth = ICMP.buildIcmpReply(icmpRequest);
+        IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload();
+        IPv4 icmpReplyIpv4 = (IPv4) icmpReplyEth.getPayload();
+        Ip4Address destIpAddress = Ip4Address.valueOf(icmpRequestIpv4.getSourceAddress());
+        Ip4Address destRouterAddress = config.getRouterIpAddressForASubnetHost(destIpAddress);
+
+        // Note: Source IP of the ICMP request doesn't belong to any configured subnet.
+        //       The source might be an indirectly attached host (e.g. behind a router)
+        //       Lookup the route store for the nexthop instead.
+        if (destRouterAddress == null) {
+            Optional<DeviceId> deviceId = srManager.routeService
+                    .longestPrefixLookup(destIpAddress).map(srManager::nextHopLocations)
+                    .flatMap(locations -> locations.stream().findFirst())
+                    .map(ConnectPoint::deviceId);
+            if (deviceId.isPresent()) {
+                try {
+                    destRouterAddress = config.getRouterIpv4(deviceId.get());
+                } catch (DeviceConfigNotFoundException e) {
+                    log.warn("Device config for {} not found. Abort ICMP processing", deviceId);
+                    return;
+                }
+            }
+        }
+
+        int destSid = config.getIPv4SegmentId(destRouterAddress);
+        if (destSid < 0) {
+            log.warn("Failed to lookup SID of the switch that {} attaches to. " +
+                    "Unable to process ICMP request.", destIpAddress);
+            return;
+        }
+        sendPacketOut(outport, icmpReplyEth, destSid, destIpAddress, icmpReplyIpv4.getTtl());
+    }
+
+    ///////////////////////////////////////////
+    //      ICMPv6 Echo/Reply Protocol       //
+    ///////////////////////////////////////////
+
+    /**
+     * Process incoming ICMPv6 packet.
+     * If it is an ICMPv6 request to router, then sends an ICMPv6 response.
+     * Otherwise ignore the packet.
+     *
+     * @param eth the incoming ICMPv6 packet
+     * @param inPort the input port
+     */
+    public void processIcmpv6(Ethernet eth, ConnectPoint inPort) {
+        DeviceId deviceId = inPort.deviceId();
+        IPv6 ipv6Packet = (IPv6) eth.getPayload();
+        ICMP6 icmp6 = (ICMP6) ipv6Packet.getPayload();
+        Ip6Address destinationAddress = Ip6Address.valueOf(ipv6Packet.getDestinationAddress());
+        Set<IpAddress> gatewayIpAddresses = config.getPortIPs(deviceId);
+        IpAddress routerIp;
+
+        // Only proceed with echo request
+        if (icmp6.getIcmpType() != ICMP6.ECHO_REQUEST) {
+            return;
+        }
+
+        try {
+            routerIp = config.getRouterIpv6(deviceId);
+
+            Optional<Ip6Address> linkLocalIp = srManager.interfaceService.getInterfacesByPort(inPort)
+                    .stream()
+                    .map(Interface::mac)
+                    .map(MacAddress::toBytes)
+                    .map(IPv6::getLinkLocalAddress)
+                    .map(Ip6Address::valueOf)
+                    .findFirst();
+
+            // Ensure ICMP to the router IP, EUI-64 link-local IP, or gateway IP
+            if (destinationAddress.equals(routerIp.getIp6Address()) ||
+                    (linkLocalIp.isPresent() && destinationAddress.equals(linkLocalIp.get())) ||
+                    gatewayIpAddresses.contains(destinationAddress)) {
+                sendIcmpv6Response(eth, inPort);
+            } else {
+                log.trace("Ignore ICMPv6 that targets for {}", destinationAddress);
+            }
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Ignore ICMPv6 that targets to {}.", destinationAddress);
+        }
+    }
+
+    /**
+     * Sends an ICMPv6 reply message.
+     *
+     * Note: we assume that packets sending from the edge switches to the hosts
+     * have untagged VLAN.
+     * @param ethRequest the original ICMP request
+     * @param outport the output port where the ICMP reply should be sent to
+     */
+    private void sendIcmpv6Response(Ethernet ethRequest, ConnectPoint outport) {
+        // Note: We assume that packets arrive at the edge switches have untagged VLAN.
+        Ethernet ethReply = ICMP6.buildIcmp6Reply(ethRequest);
+        IPv6 icmpRequestIpv6 = (IPv6) ethRequest.getPayload();
+        IPv6 icmpReplyIpv6 = (IPv6) ethRequest.getPayload();
+        Ip6Address destIpAddress = Ip6Address.valueOf(icmpRequestIpv6.getSourceAddress());
+        Ip6Address destRouterAddress = config.getRouterIpAddressForASubnetHost(destIpAddress);
+
+        // Note: Source IP of the ICMP request doesn't belong to any configured subnet.
+        //       The source might be an indirect host behind a router.
+        //       Lookup the route store for the nexthop instead.
+        if (destRouterAddress == null) {
+            Optional<DeviceId> deviceId = srManager.routeService
+                    .longestPrefixLookup(destIpAddress).map(srManager::nextHopLocations)
+                    .flatMap(locations -> locations.stream().findFirst())
+                    .map(ConnectPoint::deviceId);
+            if (deviceId.isPresent()) {
+                try {
+                    destRouterAddress = config.getRouterIpv6(deviceId.get());
+                } catch (DeviceConfigNotFoundException e) {
+                    log.warn("Device config for {} not found. Abort ICMPv6 processing", deviceId);
+                    return;
+                }
+            }
+        }
+
+        // Search SID only if store lookup is success otherwise proceed with "sid=-1"
+        int sid = -1;
+        if (destRouterAddress !=  null) {
+            sid = config.getIPv6SegmentId(destRouterAddress);
+            if (sid < 0) {
+                log.warn("Failed to lookup SID of the switch that {} attaches to. " +
+                        "Unable to process ICMPv6 request.", destIpAddress);
+                return;
+            }
+        }
+        sendPacketOut(outport, ethReply, sid, destIpAddress, icmpReplyIpv6.getHopLimit());
+    }
+
+    ///////////////////////////////////////////
+    //  ICMPv6 Neighbour Discovery Protocol  //
+    ///////////////////////////////////////////
+
+    /**
+     * Process incoming NDP packet.
+     *
+     * If it is an NDP request for the router or for the gateway, then sends a NDP reply.
+     * If it is an NDP request to unknown host flood in the subnet.
+     * If it is an NDP packet to known host forward the packet to the host.
+     *
+     * FIXME If the NDP packets use link local addresses we fail.
+     *
+     * @param pkt inbound packet
+     * @param hostService the host service
+     */
+    public void processPacketIn(NeighbourMessageContext pkt, HostService hostService) {
+        // First we validate the ndp packet
+        SegmentRoutingAppConfig appConfig = srManager.cfgService
+                .getConfig(srManager.appId, SegmentRoutingAppConfig.class);
+        if (appConfig != null && appConfig.suppressSubnet().contains(pkt.inPort())) {
+            // Ignore NDP packets come from suppressed ports
+            pkt.drop();
+            return;
+        }
+
+        if (pkt.type() == NeighbourMessageType.REQUEST) {
+            handleNdpRequest(pkt, hostService);
+        } else {
+            handleNdpReply(pkt, hostService);
+        }
+
+    }
+
+    /**
+     * Helper method to handle the ndp requests.
+     * @param pkt the ndp packet request and context information
+     * @param hostService the host service
+     */
+    private void handleNdpRequest(NeighbourMessageContext pkt, HostService hostService) {
+        // ND request for the gateway. We have to reply on behalf of the gateway.
+        if (isNdpForGateway(pkt)) {
+            log.trace("Sending NDP reply on behalf of gateway IP for pkt: {}", pkt.target());
+            MacAddress routerMac = config.getRouterMacForAGatewayIp(pkt.target());
+            sendResponse(pkt, routerMac, hostService);
+        } else {
+
+            // Process NDP targets towards EUI-64 address.
+            try {
+                DeviceId deviceId = pkt.inPort().deviceId();
+
+                Optional<Ip6Address> linkLocalIp = srManager.interfaceService.getInterfacesByPort(pkt.inPort())
+                        .stream()
+                        .map(Interface::mac)
+                        .map(MacAddress::toBytes)
+                        .map(IPv6::getLinkLocalAddress)
+                        .map(Ip6Address::valueOf)
+                        .findFirst();
+
+                if (linkLocalIp.isPresent() && pkt.target().equals(linkLocalIp.get())) {
+                    MacAddress routerMac = config.getDeviceMac(deviceId);
+                    sendResponse(pkt, routerMac, hostService);
+                }
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn(e.getMessage() + " Unable to handle NDP packet to {}. Aborting.", pkt.target());
+                return;
+            }
+
+            // NOTE: Ignore NDP packets except those target for the router
+            //       We will reconsider enabling this when we have host learning support
+            /*
+            // ND request for an host. We do a search by Ip.
+            Set<Host> hosts = hostService.getHostsByIp(pkt.target());
+            // Possible misconfiguration ? In future this case
+            // should be handled we can have same hosts in different VLANs.
+            if (hosts.size() > 1) {
+                log.warn("More than one host with IP {}", pkt.target());
+            }
+            Host targetHost = hosts.stream().findFirst().orElse(null);
+            // If we know the host forward to its attachment point.
+            if (targetHost != null) {
+                log.debug("Forward NDP request to the target host");
+                pkt.forward(targetHost.location());
+            } else {
+                // Flood otherwise.
+                log.debug("Flood NDP request to the target subnet");
+                flood(pkt);
+            }
+            */
+        }
+    }
+
+    /**
+     * Helper method to handle the ndp replies.
+     *
+     * @param pkt the ndp packet reply and context information
+     * @param hostService the host service
+     */
+    private void handleNdpReply(NeighbourMessageContext pkt, HostService hostService) {
+        if (isNdpForGateway(pkt)) {
+            log.debug("Forwarding all the ip packets we stored");
+            Ip6Address hostIpAddress = pkt.sender().getIp6Address();
+            srManager.ipHandler.forwardPackets(pkt.inPort().deviceId(), hostIpAddress);
+        } else {
+            // NOTE: Ignore NDP packets except those target for the router
+            //       We will reconsider enabling this when we have host learning support
+            /*
+            HostId hostId = HostId.hostId(pkt.dstMac(), pkt.vlan());
+            Host targetHost = hostService.getHost(hostId);
+            if (targetHost != null) {
+                log.debug("Forwarding the reply to the host");
+                pkt.forward(targetHost.location());
+            } else {
+                // We don't have to flood towards spine facing ports.
+                if (pkt.vlan().equals(SegmentRoutingManager.INTERNAL_VLAN)) {
+                    return;
+                }
+                log.debug("Flooding the reply to the subnet");
+                flood(pkt);
+            }
+            */
+        }
+    }
+
+    /**
+     * Utility to verify if the ND are for the gateway.
+     *
+     * @param pkt the ndp packet
+     * @return true if the ndp is for the gateway. False otherwise
+     */
+    private boolean isNdpForGateway(NeighbourMessageContext pkt) {
+        DeviceId deviceId = pkt.inPort().deviceId();
+        Set<IpAddress> gatewayIpAddresses = null;
+
+        try {
+            if (pkt.target().equals(config.getRouterIpv6(deviceId))) {
+                return true;
+            }
+            gatewayIpAddresses = config.getPortIPs(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting check for router IP in processing ndp");
+            return false;
+        }
+        return gatewayIpAddresses != null && gatewayIpAddresses.stream()
+                .filter(IpAddress::isIp6)
+                .anyMatch(gatewayIp -> gatewayIp.equals(pkt.target()) ||
+                        Arrays.equals(IPv6.getSolicitNodeAddress(gatewayIp.toOctets()),
+                                pkt.target().toOctets()));
+    }
+
+    /**
+     * Sends a NDP request for the target IP address to all ports except in-port.
+     *
+     * @param deviceId Switch device ID
+     * @param targetAddress target IP address for ARP
+     * @param inPort in-port
+     */
+    public void sendNdpRequest(DeviceId deviceId, IpAddress targetAddress, ConnectPoint inPort) {
+        byte[] senderMacAddress = new byte[MacAddress.MAC_ADDRESS_LENGTH];
+        byte[] senderIpAddress = new byte[Ip6Address.BYTE_LENGTH];
+        // Retrieves device info.
+        if (!getSenderInfo(senderMacAddress, senderIpAddress, deviceId, targetAddress)) {
+            log.warn("Aborting sendNdpRequest, we cannot get all the information needed");
+            return;
+        }
+        // We have to compute the dst mac address and dst ip address.
+        byte[] dstIp = IPv6.getSolicitNodeAddress(targetAddress.toOctets());
+        byte[] dstMac = IPv6.getMCastMacAddress(dstIp);
+        // Creates the request.
+        Ethernet ndpRequest = NeighborSolicitation.buildNdpSolicit(
+                targetAddress.toOctets(),
+                senderIpAddress,
+                dstIp,
+                senderMacAddress,
+                dstMac,
+                VlanId.NONE
+        );
+        flood(ndpRequest, inPort, targetAddress);
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/IpHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/IpHandler.java
new file mode 100644
index 0000000..c445ac4
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/IpHandler.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2015-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;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IP;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.packet.IpAddress.Version.INET6;
+
+/**
+ * Handler of IP packets that forwards IP packets that are sent to the controller,
+ * except the ICMP packets which are processed by @link{IcmpHandler}.
+ */
+public class IpHandler {
+
+    private static Logger log = LoggerFactory.getLogger(IpHandler.class);
+    private SegmentRoutingManager srManager;
+    private DeviceConfiguration config;
+    private ConcurrentHashMap<IpAddress, ConcurrentLinkedQueue<IP>> ipPacketQueue;
+
+    /**
+     * Creates an IpHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public IpHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.deviceConfiguration);
+        ipPacketQueue = new ConcurrentHashMap<>();
+    }
+
+    /**
+     * Enqueues the packet using the destination address as key.
+     *
+     * @param ipPacket the ip packet to store
+     * @param destinationAddress the destination address
+     */
+    private void enqueuePacket(IP ipPacket, IpAddress destinationAddress) {
+
+        ipPacketQueue
+            .computeIfAbsent(destinationAddress, a -> new ConcurrentLinkedQueue<>())
+            .add(ipPacket);
+
+    }
+
+    /**
+     * Dequeues the packet using the destination address as key.
+     *
+     * @param ipPacket the ip packet to remove
+     * @param destinationAddress the destination address
+     */
+    public void dequeuePacket(IP ipPacket, IpAddress destinationAddress) {
+
+        if (ipPacketQueue.get(destinationAddress) == null) {
+            return;
+        }
+        ipPacketQueue.get(destinationAddress).remove(ipPacket);
+    }
+
+    /**
+     * Forwards the packet to a given host and deque the packet.
+     *
+     * @param deviceId the target device
+     * @param eth the packet to send
+     * @param dest the target host
+     */
+    private void forwardToHost(DeviceId deviceId, Ethernet eth, Host dest) {
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().
+                setOutput(dest.location().port()).build();
+        OutboundPacket packet = new DefaultOutboundPacket(deviceId,
+                                                          treatment, ByteBuffer.wrap(eth.serialize()));
+        srManager.packetService.emit(packet);
+    }
+
+    //////////////////////
+    //  IPv4 Handling  //
+    ////////////////////
+
+    /**
+     * Processes incoming IP packets.
+     *
+     * If it is an IP packet for known host, then forward it to the host.
+     * If it is an IP packet for unknown host in subnet, then send an ARP request
+     * to the subnet.
+     *
+     * @param pkt incoming packet
+     * @param connectPoint the target device
+     */
+    public void processPacketIn(IPv4 pkt, ConnectPoint connectPoint) {
+
+        DeviceId deviceId = connectPoint.deviceId();
+        Ip4Address destinationAddress = Ip4Address.valueOf(pkt.getDestinationAddress());
+
+        // IP packet for know hosts
+        if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
+            forwardPackets(deviceId, destinationAddress);
+
+        // IP packet for unknown host in one of the configured subnets of the router
+        } else if (config.inSameSubnet(deviceId, destinationAddress)) {
+            srManager.arpHandler.sendArpRequest(deviceId, destinationAddress, connectPoint);
+
+        // IP packets for unknown host
+        } else {
+            log.debug("IPv4 packet for unknown host {} which is not in the subnet",
+                    destinationAddress);
+            // Do nothing
+        }
+    }
+
+    /**
+     * Adds the IP packet to a buffer.
+     * The packets are forwarded to corresponding destination when the destination
+     * MAC address is known via ARP response.
+     *
+     * @param ipPacket IP packet to add to the buffer
+     */
+    public void addToPacketBuffer(IPv4 ipPacket) {
+
+        // Better not buffer TCP packets due to out-of-order packet transfer
+        if (ipPacket.getProtocol() == IPv4.PROTOCOL_TCP) {
+            return;
+        }
+        IpAddress destIpAddress = IpAddress.valueOf(ipPacket.getDestinationAddress());
+        enqueuePacket(ipPacket, destIpAddress);
+    }
+
+    /**
+     * Forwards IP packets in the buffer to the destination IP address.
+     * It is called when the controller finds the destination MAC address
+     * via ARP responses.
+     *
+     * @param deviceId switch device ID
+     * @param destIpAddress destination IP address
+     */
+    public void forwardPackets(DeviceId deviceId, Ip4Address destIpAddress) {
+        if (ipPacketQueue.get(destIpAddress) == null) {
+            return;
+        }
+        for (IP ipPacket : ipPacketQueue.get(destIpAddress)) {
+            if (ipPacket.getVersion() == ((byte) 4)) {
+                IPv4 ipv4Packet = (IPv4) ipPacket;
+                Ip4Address destAddress = Ip4Address.valueOf(ipv4Packet.getDestinationAddress());
+                if (config.inSameSubnet(deviceId, destAddress)) {
+                    ipv4Packet.setTtl((byte) (ipv4Packet.getTtl() - 1));
+                    ipv4Packet.setChecksum((short) 0);
+                    for (Host dest : srManager.hostService.getHostsByIp(destIpAddress)) {
+                        Ethernet eth = new Ethernet();
+                        eth.setDestinationMACAddress(dest.mac());
+                        try {
+                            eth.setSourceMACAddress(config.getDeviceMac(deviceId));
+                        } catch (DeviceConfigNotFoundException e) {
+                            log.warn(e.getMessage()
+                                             + " Skipping forwardPackets for this destination.");
+                            continue;
+                        }
+                        eth.setEtherType(Ethernet.TYPE_IPV4);
+                        eth.setPayload(ipv4Packet);
+                        forwardToHost(deviceId, eth, dest);
+                        ipPacketQueue.get(destIpAddress).remove(ipPacket);
+                    }
+                    ipPacketQueue.get(destIpAddress).remove(ipPacket);
+                }
+            }
+        }
+    }
+
+    //////////////////////
+    //  IPv6 Handling  //
+    ////////////////////
+
+    /**
+     * Processes incoming IPv6 packets.
+     *
+     * If it is an IPv6 packet for known host, then forward it to the host.
+     * If it is an IPv6 packet for unknown host in subnet, then send an NDP request
+     * to the subnet.
+     *
+     * @param pkt incoming packet
+     * @param connectPoint the target device
+     */
+    public void processPacketIn(IPv6 pkt, ConnectPoint connectPoint) {
+
+        DeviceId deviceId = connectPoint.deviceId();
+        Ip6Address destinationAddress = Ip6Address.valueOf(pkt.getDestinationAddress());
+
+        // IPv6 packet for know hosts
+        if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
+            forwardPackets(deviceId, destinationAddress);
+
+            // IPv6 packet for unknown host in one of the configured subnets of the router
+        } else if (config.inSameSubnet(deviceId, destinationAddress)) {
+            srManager.icmpHandler.sendNdpRequest(deviceId, destinationAddress, connectPoint);
+
+            // IPv6 packets for unknown host
+        } else {
+            log.debug("IPv6 packet for unknown host {} which is not in the subnet",
+                      destinationAddress);
+        }
+    }
+
+    /**
+     * Adds the IPv6 packet to a buffer.
+     * The packets are forwarded to corresponding destination when the destination
+     * MAC address is known via NDP response.
+     *
+     * @param ipPacket IP packet to add to the buffer
+     */
+    public void addToPacketBuffer(IPv6 ipPacket) {
+
+        // Better not buffer TCP packets due to out-of-order packet transfer
+        if (ipPacket.getNextHeader() == IPv6.PROTOCOL_TCP) {
+            return;
+        }
+        IpAddress destIpAddress = IpAddress.valueOf(INET6, ipPacket.getDestinationAddress());
+        enqueuePacket(ipPacket, destIpAddress);
+    }
+
+    /**
+     * Forwards IP packets in the buffer to the destination IP address.
+     * It is called when the controller finds the destination MAC address
+     * via NDP replies.
+     *
+     * @param deviceId the target device
+     * @param destIpAddress the destination ip address
+     */
+    public void forwardPackets(DeviceId deviceId, Ip6Address destIpAddress) {
+        if (ipPacketQueue.get(destIpAddress) == null) {
+            return;
+        }
+        for (IP ipPacket : ipPacketQueue.get(destIpAddress)) {
+            if (ipPacket.getVersion() == ((byte) 6)) {
+                IPv6 ipv6Packet = (IPv6) ipPacket;
+                Ip6Address destAddress = Ip6Address.valueOf(ipv6Packet.getDestinationAddress());
+                if (config.inSameSubnet(deviceId, destAddress)) {
+                    ipv6Packet.setHopLimit((byte) (ipv6Packet.getHopLimit() - 1));
+                    for (Host dest : srManager.hostService.getHostsByIp(destIpAddress)) {
+                        Ethernet eth = new Ethernet();
+                        eth.setDestinationMACAddress(dest.mac());
+                        try {
+                            eth.setSourceMACAddress(config.getDeviceMac(deviceId));
+                        } catch (DeviceConfigNotFoundException e) {
+                            log.warn(e.getMessage()
+                                             + " Skipping forwardPackets for this destination.");
+                            continue;
+                        }
+                        eth.setEtherType(Ethernet.TYPE_IPV6);
+                        eth.setPayload(ipv6Packet);
+                        forwardToHost(deviceId, eth, dest);
+                        ipPacketQueue.get(destIpAddress).remove(ipPacket);
+                    }
+                    ipPacketQueue.get(destIpAddress).remove(ipPacket);
+                }
+            }
+            ipPacketQueue.get(destIpAddress).remove(ipPacket);
+        }
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/LinkHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/LinkHandler.java
new file mode 100644
index 0000000..c643991
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/LinkHandler.java
@@ -0,0 +1,586 @@
+/*
+ * 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;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.EventuallyConsistentMapBuilder;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+
+public class LinkHandler {
+    private static final Logger log = LoggerFactory.getLogger(LinkHandler.class);
+    protected final SegmentRoutingManager srManager;
+    protected LinkService linkService;
+
+    // Local store for all links seen and their present status, used for
+    // optimized routing. The existence of the link in the keys is enough to know
+    // if the link has been "seen-before" by this instance of the controller.
+    // The boolean value indicates if the link is currently up or not.
+    // Currently the optimized routing logic depends on "forgetting" a link
+    // when a switch goes down, but "remembering" it when only the link goes down.
+    private Map<Link, Boolean> seenLinks = new ConcurrentHashMap<>();
+
+    private EventuallyConsistentMap<DeviceId, Set<PortNumber>> downedPortStore = null;
+
+    /**
+     * Constructs the LinkHandler.
+     *
+     * @param srManager Segment Routing manager
+     */
+    LinkHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        linkService = srManager.linkService;
+        log.debug("Creating EC map downedportstore");
+        EventuallyConsistentMapBuilder<DeviceId, Set<PortNumber>> downedPortsMapBuilder
+                = srManager.storageService.eventuallyConsistentMapBuilder();
+        downedPortStore = downedPortsMapBuilder.withName("downedportstore")
+                .withSerializer(srManager.createSerializer())
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        log.trace("Current size {}", downedPortStore.size());
+        init();
+    }
+
+    /**
+     * Constructs the LinkHandler for unit-testing.
+     *
+     * @param srManager SegmentRoutingManager
+     * @param linkService LinkService
+     */
+    LinkHandler(SegmentRoutingManager srManager, LinkService linkService) {
+        this.srManager = srManager;
+        this.linkService = linkService;
+    }
+
+    /**
+     * Initialize LinkHandler.
+     */
+    private void init() {
+        log.info("Loading stored links");
+        srManager.linkService.getActiveLinks()
+                .forEach(link -> processLinkAdded(link));
+    }
+
+    /**
+     * Preprocessing of added link before being sent for route-path handling.
+     * Also performs post processing of link.
+     *
+     * @param link the link to be processed
+     */
+    void processLinkAdded(Link link) {
+        log.info("** LINK ADDED {}", link.toString());
+        if (!isLinkValid(link)) {
+            return;
+        }
+        if (srManager.deviceConfiguration == null ||
+                !srManager.deviceConfiguration.isConfigured(link.src().deviceId())) {
+            updateSeenLink(link, true);
+            // XXX revisit - what about devicePortMap
+            log.warn("Source device of this link is not configured.. "
+                    + "not processing further");
+            return;
+        }
+
+        // Irrespective of whether the local is a MASTER or not for this device,
+        // create group handler instance and push default TTP flow rules if needed,
+        // as in a multi-instance setup, instances can initiate groups for any
+        // device.
+        DefaultGroupHandler groupHandler = srManager.groupHandlerMap
+                .get(link.src().deviceId());
+        if (groupHandler != null) {
+            groupHandler.portUpForLink(link);
+        } else {
+            // XXX revisit/cleanup
+            Device device = srManager.deviceService.getDevice(link.src().deviceId());
+            if (device != null) {
+                log.warn("processLinkAdded: Link Added "
+                        + "Notification without Device Added "
+                        + "event, still handling it");
+                srManager.processDeviceAdded(device);
+                groupHandler = srManager.groupHandlerMap.get(link.src().deviceId());
+                groupHandler.portUpForLink(link);
+            }
+        }
+
+        /*
+         // process link only if it is bidirectional
+         if (!isBidirectional(link)) {
+            log.debug("Link not bidirectional.. waiting for other direction " +
+                      "src {} --> dst {} ", link.dst(), link.src());
+            // note that if we are not processing for routing, it should at least
+            // be considered a seen-link
+            updateSeenLink(link, true); return;
+          }
+         //TODO ensure that rehash is still done correctly even if link is not processed for
+         //rerouting - perhaps rehash in both directions when it ultimately becomes bidi?
+         */
+
+        log.debug("Starting optimized route-path processing for added link "
+                + "{} --> {}", link.src(), link.dst());
+        boolean seenBefore = isSeenLink(link);
+        // seenLink updates will be done after route-path changes
+        srManager.defaultRoutingHandler
+                .populateRoutingRulesForLinkStatusChange(null, link, null);
+
+        if (srManager.mastershipService.isLocalMaster(link.src().deviceId())) {
+            // handle edge-ports for dual-homed hosts
+            updateDualHomedHostPorts(link, true);
+
+            // It's possible that linkUp causes no route-path change as ECMP graph does
+            // not change if the link is a parallel link (same src-dst as
+            // another link). However we still need to update ECMP hash groups to include new buckets
+            // for the link that has come up.
+            if (groupHandler != null) {
+                if (!seenBefore && isParallelLink(link)) {
+                    // if link seen first time, we need to ensure hash-groups have
+                    // all ports
+                    log.debug("Attempting retryHash for paralled first-time link {}",
+                            link);
+                    groupHandler.retryHash(link, false, true);
+                } else {
+                    // seen before-link
+                    if (isParallelLink(link)) {
+                        log.debug("Attempting retryHash for paralled seen-before "
+                                + "link {}", link);
+                        groupHandler.retryHash(link, false, false);
+                    }
+                }
+            }
+        }
+
+        srManager.mcastHandler.init();
+    }
+
+    /**
+     * Preprocessing of removed link before being sent for route-path handling.
+     * Also performs post processing of link.
+     *
+     * @param link the link to be processed
+     */
+    void processLinkRemoved(Link link) {
+        log.info("** LINK REMOVED {}", link.toString());
+        if (!isLinkValid(link)) {
+            return;
+        }
+        // when removing links, update seen links first, before doing route-path
+        // changes
+        updateSeenLink(link, false);
+        // handle edge-ports for dual-homed hosts
+        if (srManager.mastershipService.isLocalMaster(link.src().deviceId())) {
+            updateDualHomedHostPorts(link, false);
+        }
+
+        // device availability check helps to ensure that multiple link-removed
+        // events are actually treated as a single switch removed event.
+        // purgeSeenLink is necessary so we do rerouting (instead of rehashing)
+        // when switch comes back.
+        if (link.src().elementId() instanceof DeviceId
+                && !srManager.deviceService.isAvailable(link.src().deviceId())) {
+            purgeSeenLink(link);
+            return;
+        }
+        if (link.dst().elementId() instanceof DeviceId
+                && !srManager.deviceService.isAvailable(link.dst().deviceId())) {
+            purgeSeenLink(link);
+            return;
+        }
+
+        log.debug("Starting optimized route-path processing for removed link "
+                + "{} --> {}", link.src(), link.dst());
+        srManager.defaultRoutingHandler
+                .populateRoutingRulesForLinkStatusChange(link, null, null);
+
+        // update local groupHandler stores
+        DefaultGroupHandler groupHandler = srManager.groupHandlerMap
+                .get(link.src().deviceId());
+        if (groupHandler != null) {
+            if (srManager.mastershipService.isLocalMaster(link.src().deviceId())
+                    && isParallelLink(link)) {
+                log.debug("* retrying hash for parallel link removed:{}", link);
+                groupHandler.retryHash(link, true, false);
+            } else {
+                log.debug("Not attempting retry-hash for link removed: {} .. {}",
+                          link,
+                          (srManager.mastershipService.isLocalMaster(link.src()
+                                  .deviceId())) ? "not parallel"
+                                                : "not master");
+            }
+            // ensure local stores are updated
+            groupHandler.portDown(link.src().port());
+        } else {
+            log.warn("group handler not found for dev:{} when removing link: {}",
+                     link.src().deviceId(), link);
+        }
+
+        srManager.mcastHandler.processLinkDown(link);
+    }
+
+    /**
+     * Checks validity of link. Examples of invalid links include
+     * indirect-links, links between ports on the same switch, and more.
+     *
+     * @param link the link to be processed
+     * @return true if valid link
+     */
+    private boolean isLinkValid(Link link) {
+        if (link.type() != Link.Type.DIRECT) {
+            // NOTE: A DIRECT link might be transiently marked as INDIRECT
+            // if BDDP is received before LLDP. We can safely ignore that
+            // until the LLDP is received and the link is marked as DIRECT.
+            log.info("Ignore link {}->{}. Link type is {} instead of DIRECT.",
+                     link.src(), link.dst(), link.type());
+            return false;
+        }
+        DeviceId srcId = link.src().deviceId();
+        DeviceId dstId = link.dst().deviceId();
+        if (srcId.equals(dstId)) {
+            log.warn("Links between ports on the same switch are not "
+                    + "allowed .. ignoring link {}", link);
+            return false;
+        }
+        DeviceConfiguration devConfig = srManager.deviceConfiguration;
+        if (devConfig == null) {
+            log.warn("Cannot check validity of link without device config");
+            return true;
+        }
+        try {
+            if (!devConfig.isEdgeDevice(srcId)
+                    && !devConfig.isEdgeDevice(dstId)) {
+                // ignore links between spines
+                // XXX revisit when handling multi-stage fabrics
+                log.warn("Links between spines not allowed...ignoring "
+                        + "link {}", link);
+                return false;
+            }
+            if (devConfig.isEdgeDevice(srcId)
+                    && devConfig.isEdgeDevice(dstId)) {
+                // ignore links between leaves if they are not pair-links
+                // XXX revisit if removing pair-link config or allowing more than
+                // one pair-link
+                if (devConfig.getPairDeviceId(srcId).equals(dstId)
+                        && devConfig.getPairLocalPort(srcId)
+                                .equals(link.src().port())
+                        && devConfig.getPairLocalPort(dstId)
+                                .equals(link.dst().port())) {
+                    // found pair link - allow it
+                    return true;
+                } else {
+                    log.warn("Links between leaves other than pair-links are "
+                            + "not allowed...ignoring link {}", link);
+                    return false;
+                }
+            }
+        } catch (DeviceConfigNotFoundException e) {
+            // We still want to count the links in seenLinks even though there
+            // is no config. So we let it return true
+            log.warn("Could not check validity of link {} as subtending devices "
+                    + "are not yet configured", link);
+        }
+        return true;
+    }
+
+    /**
+     * Administratively enables or disables edge ports if the link that was
+     * added or removed was the only uplink port from an edge device. Only edge
+     * ports that belong to dual-homed hosts are considered.
+     *
+     * @param link the link to be processed
+     * @param added true if link was added, false if link was removed
+     */
+    private void updateDualHomedHostPorts(Link link, boolean added) {
+        if (!onlyUplink(link)) {
+            return;
+        }
+        if (added) {
+            // re-enable previously disabled ports on this dev
+            Set<PortNumber> p = downedPortStore.remove(link.src().deviceId());
+            if (p != null) {
+                log.warn("Link src {} -->dst {} added is the first uplink, "
+                        + "enabling dual homed ports: {}", link.src().deviceId(),
+                     link.dst().deviceId(), (p.isEmpty()) ? "no ports" : p);
+                p.forEach(pnum -> srManager.deviceAdminService
+                        .changePortState(link.src().deviceId(), pnum, true));
+            }
+        } else {
+            // find dual homed hosts on this dev to disable
+            Set<PortNumber> dhp = srManager.hostHandler
+                    .getDualHomedHostPorts(link.src().deviceId());
+            log.warn("Link src {} -->dst {} removed was the last uplink, "
+                    + "disabling  dual homed ports:  {}", link.src().deviceId(),
+                     link.dst().deviceId(), (dhp.isEmpty()) ? "no ports" : dhp);
+            dhp.forEach(pnum -> srManager.deviceAdminService
+                        .changePortState(link.src().deviceId(), pnum, false));
+            if (!dhp.isEmpty()) {
+                // update global store
+                Set<PortNumber> p = downedPortStore.get(link.src().deviceId());
+                if (p == null) {
+                    p = dhp;
+                } else {
+                    p.addAll(dhp);
+                }
+                downedPortStore.put(link.src().deviceId(), p);
+            }
+        }
+    }
+
+    /**
+     * Returns true if given link is the only active uplink from src-device of
+     * link. An uplink is defined as a unidirectional link with src as
+     * edgeRouter and dst as non-edgeRouter.
+     *
+     * @param link
+     * @return true if given link is-the-first/was-the-last uplink from the src
+     *         device
+     */
+    private boolean onlyUplink(Link link) {
+        DeviceConfiguration devConfig = srManager.deviceConfiguration;
+        try {
+            if (!devConfig.isEdgeDevice(link.src().deviceId())
+                    || devConfig.isEdgeDevice(link.dst().deviceId())) {
+                return false;
+            }
+            // note that using linkservice here would cause race conditions as
+            // more links can show up while the app is still processing the first one
+            Set<Link> devLinks = seenLinks.entrySet().stream()
+                    .filter(entry -> entry.getKey().src().deviceId()
+                            .equals(link.src().deviceId()))
+                    .filter(entry -> entry.getValue())
+                    .filter(entry -> !entry.getKey().equals(link))
+                    .map(entry -> entry.getKey())
+                    .collect(Collectors.toSet());
+
+            for (Link l : devLinks) {
+                if (devConfig.isEdgeDevice(l.dst().deviceId())) {
+                    continue;
+                }
+                log.debug("Link {} is not the only active uplink. Found another"
+                        + "link {}", link, l);
+                return false;
+            }
+            log.debug("Link {} is the only uplink", link);
+            return true;
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn("Unable to determine if link is only uplink"
+                    + e.getMessage());
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if this controller instance has seen this link before. The
+     * link may not be currently up, but as long as the link had been seen
+     * before this method will return true. The one exception is when the link
+     * was indeed seen before, but this controller instance was forced to forget
+     * it by a call to purgeSeenLink method.
+     *
+     * @param link the infrastructure link being queried
+     * @return true if this controller instance has seen this link before
+     */
+    boolean isSeenLink(Link link) {
+        return seenLinks.containsKey(link);
+    }
+
+    /**
+     * Updates the seen link store. Updates can be for links that are currently
+     * available or not.
+     *
+     * @param link the link to update in the seen-link local store
+     * @param up the status of the link, true if up, false if down
+     */
+    void updateSeenLink(Link link, boolean up) {
+        seenLinks.put(link, up);
+    }
+
+    /**
+     * Returns the status of a seen-link (up or down). If the link has not been
+     * seen-before, a null object is returned.
+     *
+     * @param link the infrastructure link being queried
+     * @return null if the link was not seen-before; true if the seen-link is
+     *         up; false if the seen-link is down
+     */
+    private Boolean isSeenLinkUp(Link link) {
+        return seenLinks.get(link);
+    }
+
+    /**
+     * Makes this controller instance forget a previously seen before link.
+     *
+     * @param link the infrastructure link to purge
+     */
+    private void purgeSeenLink(Link link) {
+        seenLinks.remove(link);
+    }
+
+    /**
+     * Returns the status of a link as parallel link. A parallel link is defined
+     * as a link which has common src and dst switches as another seen-link that
+     * is currently enabled. It is not necessary for the link being queried to
+     * be a seen-link.
+     *
+     * @param link the infrastructure link being queried
+     * @return true if a seen-link exists that is up, and shares the same src
+     *         and dst switches as the link being queried
+     */
+    private boolean isParallelLink(Link link) {
+        for (Entry<Link, Boolean> seen : seenLinks.entrySet()) {
+            Link seenLink = seen.getKey();
+            if (seenLink.equals(link)) {
+                continue;
+            }
+            if (seenLink.src().deviceId().equals(link.src().deviceId())
+                    && seenLink.dst().deviceId().equals(link.dst().deviceId())
+                    && seen.getValue()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if the link being queried is a bidirectional link. A bidi
+     * link is defined as a link, whose reverse link - ie. the link in the
+     * reverse direction - has been seen-before and is up. It is not necessary
+     * for the link being queried to be a seen-link.
+     *
+     * @param link the infrastructure link being queried
+     * @return true if another unidirectional link exists in the reverse
+     *         direction, has been seen-before and is up
+     */
+    boolean isBidirectional(Link link) {
+        Link reverseLink = linkService.getLink(link.dst(), link.src());
+        if (reverseLink == null) {
+            return false;
+        }
+        Boolean result = isSeenLinkUp(reverseLink);
+        if (result == null) {
+            return false;
+        }
+        return result.booleanValue();
+    }
+
+    /**
+     * Determines if the given link should be avoided in routing calculations by
+     * policy or design.
+     *
+     * @param link the infrastructure link being queried
+     * @return true if link should be avoided
+     */
+    boolean avoidLink(Link link) {
+        // XXX currently only avoids all pair-links. In the future can be
+        // extended to avoid any generic link
+        DeviceId src = link.src().deviceId();
+        PortNumber srcPort = link.src().port();
+        DeviceConfiguration devConfig = srManager.deviceConfiguration;
+        if (devConfig == null || !devConfig.isConfigured(src)) {
+            log.warn("Device {} not configured..cannot avoid link {}", src,
+                     link);
+            return false;
+        }
+        DeviceId pairDev;
+        PortNumber pairLocalPort, pairRemotePort = null;
+        try {
+            pairDev = devConfig.getPairDeviceId(src);
+            pairLocalPort = devConfig.getPairLocalPort(src);
+            if (pairDev != null) {
+                pairRemotePort = devConfig
+                        .getPairLocalPort(pairDev);
+            }
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn("Pair dev for dev {} not configured..cannot avoid link {}",
+                     src, link);
+            return false;
+        }
+
+        return srcPort.equals(pairLocalPort)
+                && link.dst().deviceId().equals(pairDev)
+                && link.dst().port().equals(pairRemotePort);
+    }
+
+    /**
+     * Cleans up internal LinkHandler stores.
+     *
+     * @param device the device that has been removed
+     */
+    void processDeviceRemoved(Device device) {
+        seenLinks.keySet()
+                .removeIf(key -> key.src().deviceId().equals(device.id())
+                        || key.dst().deviceId().equals(device.id()));
+    }
+
+    /**
+     * Administratively disables the host location switchport if the edge device
+     * has no viable uplinks.
+     *
+     * @param loc one of the locations of the dual-homed host
+     */
+    void checkUplinksForDualHomedHosts(HostLocation loc) {
+        try {
+            for (Link l : srManager.linkService.getDeviceLinks(loc.deviceId())) {
+                if (srManager.deviceConfiguration.isEdgeDevice(l.dst().deviceId())
+                        || l.state() == Link.State.INACTIVE) {
+                    continue;
+                }
+                // found valid uplink - so, nothing to do
+                return;
+            }
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn("Could not check for valid uplinks due to missing device"
+                    + "config " + e.getMessage());
+            return;
+        }
+        log.warn("Dual homed host location {} has no valid uplinks; "
+                + "disabling  dual homed port", loc);
+        srManager.deviceAdminService.changePortState(loc.deviceId(), loc.port(),
+                                                     false);
+        Set<PortNumber> p = downedPortStore.get(loc.deviceId());
+        if (p == null) {
+            p = Sets.newHashSet(loc.port());
+        } else {
+            p.add(loc.port());
+        }
+        downedPortStore.put(loc.deviceId(), p);
+    }
+
+    ImmutableMap<Link, Boolean> getSeenLinks() {
+        return ImmutableMap.copyOf(seenLinks);
+    }
+
+    ImmutableMap<DeviceId, Set<PortNumber>> getDownedPorts() {
+        return ImmutableMap.copyOf(downedPortStore.entrySet());
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/McastHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/McastHandler.java
new file mode 100644
index 0000000..fff2c92
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/McastHandler.java
@@ -0,0 +1,1453 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+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.net.config.basics.McastConfig;
+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.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;
+import org.onosproject.net.mcast.McastEvent;
+import org.onosproject.net.mcast.McastRoute;
+import org.onosproject.net.mcast.McastRouteInfo;
+import org.onosproject.net.topology.TopologyService;
+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;
+
+import java.time.Instant;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.concurrent.Executors.newScheduledThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.segmentrouting.SegmentRoutingManager.INTERNAL_VLAN;
+
+/**
+ * Handles multicast-related events.
+ */
+public class McastHandler {
+    private static final Logger log = LoggerFactory.getLogger(McastHandler.class);
+    private final SegmentRoutingManager srManager;
+    private final ApplicationId coreAppId;
+    private final StorageService storageService;
+    private final TopologyService topologyService;
+    private final ConsistentMap<McastStoreKey, NextObjective> mcastNextObjStore;
+    private final KryoNamespace.Builder mcastKryo;
+    private final ConsistentMap<McastStoreKey, McastRole> mcastRoleStore;
+
+    // Mcast lock to serialize local operations
+    private final Lock mcastLock = new ReentrantLock();
+
+    /**
+     * Acquires the lock used when making mcast changes.
+     */
+    private void mcastLock() {
+        mcastLock.lock();
+    }
+
+    /**
+     * Releases the lock used when making mcast changes.
+     */
+    private void mcastUnlock() {
+        mcastLock.unlock();
+    }
+
+    // Stability threshold for Mcast. Seconds
+    private static final long MCAST_STABLITY_THRESHOLD = 5;
+    // Last change done
+    private Instant lastMcastChange = Instant.now();
+
+    /**
+     * Determines if mcast in the network has been stable in the last
+     * MCAST_STABLITY_THRESHOLD seconds, by comparing the current time
+     * to the last mcast change timestamp.
+     *
+     * @return true if stable
+     */
+    private boolean isMcastStable() {
+        long last = (long) (lastMcastChange.toEpochMilli() / 1000.0);
+        long now = (long) (Instant.now().toEpochMilli() / 1000.0);
+        log.debug("Mcast stable since {}s", now - last);
+        return (now - last) > MCAST_STABLITY_THRESHOLD;
+    }
+
+    // Verify interval for Mcast
+    private static final long MCAST_VERIFY_INTERVAL = 30;
+
+    // Executor for mcast bucket corrector
+    private ScheduledExecutorService executorService
+            = newScheduledThreadPool(1, groupedThreads("mcastBktCorrector", "mcastbktC-%d", log));
+
+    /**
+     * Role in the multicast tree.
+     */
+    public enum McastRole {
+        /**
+         * The device is the ingress device of this group.
+         */
+        INGRESS,
+        /**
+         * The device is the transit device of this group.
+         */
+        TRANSIT,
+        /**
+         * The device is the egress device of this group.
+         */
+        EGRESS
+    }
+
+    /**
+     * Constructs the McastEventHandler.
+     *
+     * @param srManager Segment Routing manager
+     */
+    public McastHandler(SegmentRoutingManager srManager) {
+        coreAppId = srManager.coreService.getAppId(CoreService.CORE_APP_NAME);
+        this.srManager = srManager;
+        this.storageService = srManager.storageService;
+        this.topologyService = srManager.topologyService;
+        mcastKryo = new KryoNamespace.Builder()
+                .register(KryoNamespaces.API)
+                .register(McastStoreKey.class)
+                .register(McastRole.class);
+        mcastNextObjStore = storageService
+                .<McastStoreKey, NextObjective>consistentMapBuilder()
+                .withName("onos-mcast-nextobj-store")
+                .withSerializer(Serializer.using(mcastKryo.build("McastHandler-NextObj")))
+                .build();
+        mcastRoleStore = storageService
+                .<McastStoreKey, McastRole>consistentMapBuilder()
+                .withName("onos-mcast-role-store")
+                .withSerializer(Serializer.using(mcastKryo.build("McastHandler-Role")))
+                .build();
+        // Init the executor service and the buckets corrector
+        executorService.scheduleWithFixedDelay(new McastBucketCorrector(), 10,
+                                               MCAST_VERIFY_INTERVAL,
+                                               TimeUnit.SECONDS);
+    }
+
+    /**
+     * Read initial multicast from mcast store.
+     */
+    protected void init() {
+        srManager.multicastRouteService.getRoutes().forEach(mcastRoute -> {
+            ConnectPoint source = srManager.multicastRouteService.fetchSource(mcastRoute);
+            Set<ConnectPoint> sinks = srManager.multicastRouteService.fetchSinks(mcastRoute);
+            sinks.forEach(sink -> {
+                processSinkAddedInternal(source, sink, mcastRoute.group());
+            });
+        });
+    }
+
+    /**
+     * Clean up when deactivating the application.
+     */
+    protected void terminate() {
+        executorService.shutdown();
+    }
+
+    /**
+     * Processes the SOURCE_ADDED event.
+     *
+     * @param event McastEvent with SOURCE_ADDED type
+     */
+    protected void processSourceAdded(McastEvent event) {
+        log.info("processSourceAdded {}", event);
+        McastRouteInfo mcastRouteInfo = event.subject();
+        if (!mcastRouteInfo.isComplete()) {
+            log.info("Incompleted McastRouteInfo. Abort.");
+            return;
+        }
+        ConnectPoint source = mcastRouteInfo.source().orElse(null);
+        Set<ConnectPoint> sinks = mcastRouteInfo.sinks();
+        IpAddress mcastIp = mcastRouteInfo.route().group();
+
+        sinks.forEach(sink -> processSinkAddedInternal(source, sink, mcastIp));
+    }
+
+    /**
+     * Processes the SINK_ADDED event.
+     *
+     * @param event McastEvent with SINK_ADDED type
+     */
+    protected void processSinkAdded(McastEvent event) {
+        log.info("processSinkAdded {}", event);
+        McastRouteInfo mcastRouteInfo = event.subject();
+        if (!mcastRouteInfo.isComplete()) {
+            log.info("Incompleted McastRouteInfo. Abort.");
+            return;
+        }
+        ConnectPoint source = mcastRouteInfo.source().orElse(null);
+        ConnectPoint sink = mcastRouteInfo.sink().orElse(null);
+        IpAddress mcastIp = mcastRouteInfo.route().group();
+
+        processSinkAddedInternal(source, sink, mcastIp);
+    }
+
+    /**
+     * Processes the SINK_REMOVED event.
+     *
+     * @param event McastEvent with SINK_REMOVED type
+     */
+    protected void processSinkRemoved(McastEvent event) {
+        log.info("processSinkRemoved {}", event);
+        McastRouteInfo mcastRouteInfo = event.subject();
+        if (!mcastRouteInfo.isComplete()) {
+            log.info("Incompleted McastRouteInfo. Abort.");
+            return;
+        }
+        ConnectPoint source = mcastRouteInfo.source().orElse(null);
+        ConnectPoint sink = mcastRouteInfo.sink().orElse(null);
+        IpAddress mcastIp = mcastRouteInfo.route().group();
+
+        processSinkRemovedInternal(source, sink, mcastIp);
+    }
+
+    /**
+     * Processes the ROUTE_REMOVED event.
+     *
+     * @param event McastEvent with ROUTE_REMOVED type
+     */
+    protected void processRouteRemoved(McastEvent event) {
+        log.info("processRouteRemoved {}", event);
+        McastRouteInfo mcastRouteInfo = event.subject();
+        if (!mcastRouteInfo.source().isPresent()) {
+            log.info("Incompleted McastRouteInfo. Abort.");
+            return;
+        }
+        // Get group ip and ingress connect point
+        IpAddress mcastIp = mcastRouteInfo.route().group();
+        ConnectPoint source = mcastRouteInfo.source().get();
+
+        processRouteRemovedInternal(source, mcastIp);
+    }
+
+    /**
+     * Removes the entire mcast tree related to this group.
+     *
+     * @param mcastIp multicast group IP address
+     */
+    private void processRouteRemovedInternal(ConnectPoint source, IpAddress mcastIp) {
+        lastMcastChange = Instant.now();
+        mcastLock();
+        try {
+            log.debug("Processing route down for group {}", mcastIp);
+
+            // Find out the ingress, transit and egress device of the affected group
+            DeviceId ingressDevice = getDevice(mcastIp, McastRole.INGRESS)
+                    .stream().findAny().orElse(null);
+            DeviceId transitDevice = getDevice(mcastIp, McastRole.TRANSIT)
+                    .stream().findAny().orElse(null);
+            Set<DeviceId> egressDevices = getDevice(mcastIp, McastRole.EGRESS);
+
+            // Verify leadership on the operation
+            if (!isLeader(source)) {
+                log.debug("Skip {} due to lack of leadership", mcastIp);
+                return;
+            }
+
+            // If there are egress devices, sinks could be only on the ingress
+            if (!egressDevices.isEmpty()) {
+                egressDevices.forEach(
+                        deviceId -> removeGroupFromDevice(deviceId, mcastIp, assignedVlan(null))
+                );
+            }
+            // Transit could be null
+            if (transitDevice != null) {
+                removeGroupFromDevice(transitDevice, mcastIp, assignedVlan(null));
+            }
+            // Ingress device should be not null
+            if (ingressDevice != null) {
+                removeGroupFromDevice(ingressDevice, mcastIp, assignedVlan(source));
+            }
+
+        } finally {
+            mcastUnlock();
+        }
+    }
+
+    /**
+     * Removes a path from source to sink for given multicast group.
+     *
+     * @param source connect point of the multicast source
+     * @param sink connection point of the multicast sink
+     * @param mcastIp multicast group IP address
+     */
+    private void processSinkRemovedInternal(ConnectPoint source, ConnectPoint sink,
+                                          IpAddress mcastIp) {
+        lastMcastChange = Instant.now();
+        mcastLock();
+        try {
+            // Verify leadership on the operation
+            if (!isLeader(source)) {
+                log.debug("Skip {} due to lack of leadership", mcastIp);
+                return;
+            }
+
+            // 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.
+                if (source.port().equals(sink.port())) {
+                    log.warn("Skip {} since sink {} is on the same port of source {}. Abort",
+                             mcastIp, sink, source);
+                    return;
+                }
+                removePortFromDevice(sink.deviceId(), sink.port(), mcastIp, assignedVlan(source));
+                return;
+            }
+
+            // Process the egress device
+            boolean isLast = removePortFromDevice(sink.deviceId(), sink.port(), mcastIp, assignedVlan(null));
+            if (isLast) {
+                mcastRoleStore.remove(new McastStoreKey(mcastIp, sink.deviceId()));
+            }
+
+            // If this is the last sink on the device, also update upstream
+            Optional<Path> mcastPath = getPath(source.deviceId(), sink.deviceId(), mcastIp);
+            if (mcastPath.isPresent()) {
+                List<Link> links = Lists.newArrayList(mcastPath.get().links());
+                Collections.reverse(links);
+                for (Link link : links) {
+                    if (isLast) {
+                        isLast = removePortFromDevice(
+                                link.src().deviceId(),
+                                link.src().port(),
+                                mcastIp,
+                                assignedVlan(link.src().deviceId().equals(source.deviceId()) ? source : null)
+                        );
+                        mcastRoleStore.remove(new McastStoreKey(mcastIp, link.src().deviceId()));
+                    }
+                }
+            }
+        } finally {
+            mcastUnlock();
+        }
+    }
+
+    /**
+     * Establishes a path from source to sink for given multicast group.
+     *
+     * @param source connect point of the multicast source
+     * @param sink connection point of the multicast sink
+     * @param mcastIp multicast group IP address
+     */
+    private void processSinkAddedInternal(ConnectPoint source, ConnectPoint sink,
+            IpAddress mcastIp) {
+        lastMcastChange = Instant.now();
+        mcastLock();
+        try {
+            // Continue only when this instance is the master of source device
+            if (!srManager.mastershipService.isLocalMaster(source.deviceId())) {
+                log.debug("Skip {} due to lack of mastership of the source device {}",
+                          mcastIp, source.deviceId());
+                return;
+            }
+
+            // Process the ingress device
+            addFilterToDevice(source.deviceId(), source.port(), assignedVlan(source), mcastIp);
+
+            // 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.
+                if (source.port().equals(sink.port())) {
+                    log.warn("Skip {} since sink {} is on the same port of source {}. Abort",
+                             mcastIp, sink, source);
+                    return;
+                }
+                addPortToDevice(sink.deviceId(), sink.port(), mcastIp, assignedVlan(source));
+                mcastRoleStore.put(new McastStoreKey(mcastIp, sink.deviceId()), McastRole.INGRESS);
+                return;
+            }
+
+            // Find a path. If present, create/update groups and flows for each hop
+            Optional<Path> mcastPath = getPath(source.deviceId(), sink.deviceId(), mcastIp);
+            if (mcastPath.isPresent()) {
+                List<Link> links = mcastPath.get().links();
+                checkState(links.size() == 2,
+                           "Path in leaf-spine topology should always be two hops: ", links);
+
+                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);
+                });
+
+                // Process the egress device
+                addPortToDevice(sink.deviceId(), sink.port(), mcastIp, assignedVlan(null));
+
+                // Setup mcast roles
+                mcastRoleStore.put(new McastStoreKey(mcastIp, source.deviceId()),
+                                   McastRole.INGRESS);
+                mcastRoleStore.put(new McastStoreKey(mcastIp, links.get(0).dst().deviceId()),
+                                   McastRole.TRANSIT);
+                mcastRoleStore.put(new McastStoreKey(mcastIp, sink.deviceId()),
+                                   McastRole.EGRESS);
+            } else {
+                log.warn("Unable to find a path from {} to {}. Abort sinkAdded",
+                         source.deviceId(), sink.deviceId());
+            }
+        } finally {
+            mcastUnlock();
+        }
+    }
+
+    /**
+     * Processes the LINK_DOWN event.
+     *
+     * @param affectedLink Link that is going down
+     */
+    protected void processLinkDown(Link affectedLink) {
+        lastMcastChange = Instant.now();
+        mcastLock();
+        try {
+            // Get groups affected by the link down event
+            getAffectedGroups(affectedLink).forEach(mcastIp -> {
+                // TODO Optimize when the group editing is in place
+                log.debug("Processing link down {} for group {}",
+                          affectedLink, mcastIp);
+
+                // Find out the ingress, transit and egress device of affected group
+                DeviceId ingressDevice = getDevice(mcastIp, McastRole.INGRESS)
+                        .stream().findAny().orElse(null);
+                DeviceId transitDevice = getDevice(mcastIp, McastRole.TRANSIT)
+                        .stream().findAny().orElse(null);
+                Set<DeviceId> egressDevices = getDevice(mcastIp, McastRole.EGRESS);
+                ConnectPoint source = getSource(mcastIp);
+
+                // Do not proceed if any of these info is missing
+                if (ingressDevice == null || transitDevice == null
+                        || egressDevices == null || source == null) {
+                    log.warn("Missing ingress {}, transit {}, egress {} devices or source {}",
+                             ingressDevice, transitDevice, egressDevices, source);
+                    return;
+                }
+
+                // Continue only when this instance is the master of source device
+                if (!srManager.mastershipService.isLocalMaster(source.deviceId())) {
+                    log.debug("Skip {} due to lack of mastership of the source device {}",
+                             source.deviceId());
+                    return;
+                }
+
+                // Remove entire transit
+                removeGroupFromDevice(transitDevice, mcastIp, assignedVlan(null));
+
+                // Remove transit-facing port on ingress device
+                PortNumber ingressTransitPort = ingressTransitPort(mcastIp);
+                if (ingressTransitPort != null) {
+                    removePortFromDevice(ingressDevice, ingressTransitPort, mcastIp, assignedVlan(source));
+                    mcastRoleStore.remove(new McastStoreKey(mcastIp, transitDevice));
+                }
+
+                // Construct a new path for each egress device
+                egressDevices.forEach(egressDevice -> {
+                    Optional<Path> mcastPath = getPath(ingressDevice, egressDevice, mcastIp);
+                    if (mcastPath.isPresent()) {
+                        installPath(mcastIp, source, mcastPath.get());
+                    } else {
+                        log.warn("Fail to recover egress device {} from link failure {}",
+                                 egressDevice, affectedLink);
+                        removeGroupFromDevice(egressDevice, mcastIp, assignedVlan(null));
+                    }
+                });
+            });
+        } finally {
+            mcastUnlock();
+        }
+    }
+
+    /**
+     * Process the DEVICE_DOWN event.
+     *
+     * @param deviceDown device going down
+     */
+    protected void processDeviceDown(DeviceId deviceDown) {
+        lastMcastChange = Instant.now();
+        mcastLock();
+        try {
+            // Get the mcast groups affected by the device going down
+            getAffectedGroups(deviceDown).forEach(mcastIp -> {
+                // TODO Optimize when the group editing is in place
+                log.debug("Processing device down {} for group {}",
+                          deviceDown, mcastIp);
+
+                // Find out the ingress, transit and egress device of affected group
+                DeviceId ingressDevice = getDevice(mcastIp, McastRole.INGRESS)
+                        .stream().findAny().orElse(null);
+                DeviceId transitDevice = getDevice(mcastIp, McastRole.TRANSIT)
+                        .stream().findAny().orElse(null);
+                Set<DeviceId> egressDevices = getDevice(mcastIp, McastRole.EGRESS);
+                ConnectPoint source = 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
+                // If sinks are in the same leaf, we have just ingress and source
+                if (ingressDevice == null || source == null) {
+                    log.warn("Missing ingress {} or source {} for group {}",
+                             ingressDevice, source, mcastIp);
+                    return;
+                }
+
+                // Verify leadership on the operation
+                if (!isLeader(source)) {
+                    log.debug("Skip {} due to lack of leadership", mcastIp);
+                    return;
+                }
+
+                // If it exists, we have to remove it in any case
+                if (transitDevice != null) {
+                    // Remove entire transit
+                    removeGroupFromDevice(transitDevice, mcastIp, assignedVlan(null));
+                }
+                // If the ingress is down
+                if (ingressDevice.equals(deviceDown)) {
+                    // Remove entire ingress
+                    removeGroupFromDevice(ingressDevice, mcastIp, 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))
+                        );
+                    }
+                } else {
+                    // Egress or transit could be down at this point
+                    // Get the ingress-transit port if it exists
+                    PortNumber ingressTransitPort = ingressTransitPort(mcastIp);
+                    if (ingressTransitPort != null) {
+                        // Remove transit-facing port on ingress device
+                        removePortFromDevice(ingressDevice, ingressTransitPort, mcastIp, assignedVlan(source));
+                    }
+                    // One of the egress device is down
+                    if (egressDevices.contains(deviceDown)) {
+                        // Remove entire device down
+                        removeGroupFromDevice(deviceDown, mcastIp, assignedVlan(null));
+                        // Remove the device down from egress
+                        egressDevices.remove(deviceDown);
+                        // If there are no more egress and ingress does not have sinks
+                        if (egressDevices.isEmpty() && !hasSinks(ingressDevice, mcastIp)) {
+                            // Remove entire ingress
+                            mcastRoleStore.remove(new McastStoreKey(mcastIp, ingressDevice));
+                            // We have done
+                            return;
+                        }
+                    }
+                    // Construct a new path for each egress device
+                    egressDevices.forEach(egressDevice -> {
+                        Optional<Path> mcastPath = getPath(ingressDevice, egressDevice, mcastIp);
+                        // 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 {
+                            // 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));
+                        }
+                    });
+                }
+            });
+        } finally {
+            mcastUnlock();
+        }
+    }
+
+    /**
+     * 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) {
+        // 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;
+        }
+
+        FilteringObjective.Builder filtObjBuilder =
+                filterObjBuilder(deviceId, port, assignedVlan, mcastIp);
+        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.
+     *
+     * @param deviceId device ID
+     * @param port port to be added
+     * @param mcastIp multicast group
+     * @param assignedVlan assigned VLAN ID
+     */
+    private void addPortToDevice(DeviceId deviceId, PortNumber port,
+            IpAddress mcastIp, VlanId assignedVlan) {
+        McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, deviceId);
+        ImmutableSet.Builder<PortNumber> portBuilder = ImmutableSet.builder();
+        NextObjective newNextObj;
+        if (!mcastNextObjStore.containsKey(mcastStoreKey)) {
+            // First time someone request this mcast group via this device
+            portBuilder.add(port);
+            // New nextObj
+            newNextObj = nextObjBuilder(mcastIp, assignedVlan,
+                                        portBuilder.build(), null).add();
+            // Store the new port
+            mcastNextObjStore.put(mcastStoreKey, newNextObj);
+        } else {
+            // 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());
+            if (existingPorts.contains(port)) {
+                log.info("NextObj for {}/{} already exists. Abort", deviceId, port);
+                return;
+            }
+            // Let's add the port and reuse the previous one
+            portBuilder.addAll(existingPorts).add(port);
+            // Reuse previous nextObj
+            newNextObj = 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,
+                                        portBuilder.build(), nextObj.id()).addToExisting();
+        }
+        // Create, store and apply the new nextObj and fwdObj
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("Successfully add {} on {}/{}, vlan {}",
+                        mcastIp, deviceId, port.toLong(), assignedVlan),
+                (objective, error) ->
+                        log.warn("Failed to add {} on {}/{}, vlan {}: {}",
+                                mcastIp, deviceId, port.toLong(), assignedVlan, error));
+        ForwardingObjective fwdObj =
+                fwdObjBuilder(mcastIp, assignedVlan, newNextObj.id()).add(context);
+        srManager.flowObjectiveService.next(deviceId, newNextObj);
+        srManager.flowObjectiveService.forward(deviceId, fwdObj);
+    }
+
+    /**
+     * Removes a port from given multicast group on given device.
+     * This involves the update of L3 multicast group and multicast routing
+     * table entry.
+     *
+     * @param deviceId device ID
+     * @param port port to be added
+     * @param mcastIp multicast group
+     * @param assignedVlan assigned VLAN ID
+     * @return true if this is the last sink on this device
+     */
+    private boolean removePortFromDevice(DeviceId deviceId, PortNumber port,
+            IpAddress mcastIp, VlanId assignedVlan) {
+        McastStoreKey mcastStoreKey =
+                new McastStoreKey(mcastIp, deviceId);
+        // This device is not serving this multicast group
+        if (!mcastNextObjStore.containsKey(mcastStoreKey)) {
+            log.warn("{} is not serving {} on port {}. Abort.", deviceId, mcastIp, port);
+            return false;
+        }
+        NextObjective nextObj = mcastNextObjStore.get(mcastStoreKey).value();
+
+        Set<PortNumber> existingPorts = 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);
+            return false;
+        }
+        // Copy and modify the ImmutableSet
+        existingPorts = Sets.newHashSet(existingPorts);
+        existingPorts.remove(port);
+
+        NextObjective newNextObj;
+        ObjectiveContext context;
+        ForwardingObjective fwdObj;
+        if (existingPorts.isEmpty()) {
+            // If this is the last sink, remove flows and last bucket
+            // NOTE: Rely on GroupStore garbage collection rather than explicitly
+            //       remove L3MG since there might be other flows/groups refer to
+            //       the same L2IG
+            context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("Successfully remove {} on {}/{}, vlan {}",
+                            mcastIp, deviceId, port.toLong(), assignedVlan),
+                    (objective, error) ->
+                            log.warn("Failed to remove {} on {}/{}, vlan {}: {}",
+                                    mcastIp, deviceId, port.toLong(), assignedVlan, error));
+            fwdObj = fwdObjBuilder(mcastIp, assignedVlan, nextObj.id()).remove(context);
+            mcastNextObjStore.remove(mcastStoreKey);
+        } else {
+            // If this is not the last sink, update flows and groups
+            context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("Successfully update {} on {}/{}, vlan {}",
+                            mcastIp, deviceId, port.toLong(), assignedVlan),
+                    (objective, error) ->
+                            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,
+                                        existingPorts, nextObj.id()).removeFromExisting();
+            fwdObj = fwdObjBuilder(mcastIp, assignedVlan, newNextObj.id()).add(context);
+            mcastNextObjStore.put(mcastStoreKey, newNextObj);
+        }
+        // Let's modify the next objective removing the bucket
+        newNextObj = nextObjBuilder(mcastIp, assignedVlan,
+                                    ImmutableSet.of(port), nextObj.id()).removeFromExisting();
+        srManager.flowObjectiveService.next(deviceId, newNextObj);
+        srManager.flowObjectiveService.forward(deviceId, fwdObj);
+        return existingPorts.isEmpty();
+    }
+
+    /**
+     * Removes entire group on given device.
+     *
+     * @param deviceId device ID
+     * @param mcastIp multicast group to be removed
+     * @param assignedVlan assigned VLAN ID
+     */
+    private void removeGroupFromDevice(DeviceId deviceId, IpAddress mcastIp,
+            VlanId assignedVlan) {
+        McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, deviceId);
+        // This device is not serving this multicast group
+        if (!mcastNextObjStore.containsKey(mcastStoreKey)) {
+            log.warn("{} is not serving {}. Abort.", deviceId, mcastIp);
+            return;
+        }
+        NextObjective nextObj = mcastNextObjStore.get(mcastStoreKey).value();
+        // NOTE: Rely on GroupStore garbage collection rather than explicitly
+        //       remove L3MG since there might be other flows/groups refer to
+        //       the same L2IG
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("Successfully remove {} on {}, vlan {}",
+                        mcastIp, deviceId, assignedVlan),
+                (objective, error) ->
+                        log.warn("Failed to remove {} on {}, vlan {}: {}",
+                                mcastIp, deviceId, assignedVlan, error));
+        ForwardingObjective fwdObj = fwdObjBuilder(mcastIp, assignedVlan, nextObj.id()).remove(context);
+        srManager.flowObjectiveService.forward(deviceId, fwdObj);
+        mcastNextObjStore.remove(mcastStoreKey);
+        mcastRoleStore.remove(mcastStoreKey);
+    }
+
+    private void installPath(IpAddress mcastIp, ConnectPoint source, Path mcastPath) {
+        // Get Links
+        List<Link> links = mcastPath.links();
+        // For each link, modify the next on the source device adding the src port
+        // 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);
+        });
+        // Setup new transit mcast role
+        mcastRoleStore.put(new McastStoreKey(mcastIp, links.get(0).dst().deviceId()),
+                           McastRole.TRANSIT);
+    }
+
+    /**
+     * 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 deviceId Device ID
+     * @param ingressPort ingress port of the multicast stream
+     * @param assignedVlan assigned VLAN ID
+     * @return filtering objective builder
+     */
+    private FilteringObjective.Builder filterObjBuilder(DeviceId deviceId, PortNumber ingressPort,
+            VlanId assignedVlan, IpAddress mcastIp) {
+        FilteringObjective.Builder filtBuilder = DefaultFilteringObjective.builder();
+
+        if (mcastIp.isIp4()) {
+            filtBuilder.withKey(Criteria.matchInPort(ingressPort))
+            .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST,
+                    MacAddress.IPV4_MULTICAST_MASK))
+            .addCondition(Criteria.matchVlanId(egressVlan()))
+            .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+        } else {
+            filtBuilder.withKey(Criteria.matchInPort(ingressPort))
+            .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV6_MULTICAST,
+                     MacAddress.IPV6_MULTICAST_MASK))
+            .addCondition(Criteria.matchVlanId(egressVlan()))
+            .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+        }
+        TrafficTreatment tt = DefaultTrafficTreatment.builder()
+                .pushVlan().setVlanId(assignedVlan).build();
+        filtBuilder.withMeta(tt);
+
+        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();
+    }
+
+    /**
+     * Gets a path from src to dst.
+     * If a path was allocated before, returns the allocated path.
+     * Otherwise, randomly pick one from available paths.
+     *
+     * @param src source device ID
+     * @param dst destination device ID
+     * @param mcastIp multicast group
+     * @return an optional path from src to dst
+     */
+    private Optional<Path> getPath(DeviceId src, DeviceId dst, IpAddress mcastIp) {
+        List<Path> allPaths = Lists.newArrayList(
+                topologyService.getPaths(topologyService.currentTopology(), src, dst));
+        log.debug("{} path(s) found from {} to {}", allPaths.size(), src, dst);
+        if (allPaths.isEmpty()) {
+            return Optional.empty();
+        }
+
+        // Create a map index of suitablity-to-list of paths. For example
+        // a path in the list associated to the index 1 shares only the
+        // first hop and it is less suitable of a path belonging to the index
+        // 2 that shares leaf-spine.
+        Map<Integer, List<Path>> eligiblePaths = Maps.newHashMap();
+        // Some init steps
+        int nhop;
+        McastStoreKey mcastStoreKey;
+        Link hop;
+        PortNumber srcPort;
+        Set<PortNumber> existingPorts;
+        NextObjective nextObj;
+        // Iterate over paths looking for eligible paths
+        for (Path path : allPaths) {
+            // Unlikely, it will happen...
+            if (!src.equals(path.links().get(0).src().deviceId())) {
+                continue;
+            }
+            nhop = 0;
+            // Iterate over the links
+            while (nhop < path.links().size()) {
+                // Get the link and verify if a next related
+                // to the src device exist in the store
+                hop = path.links().get(nhop);
+                mcastStoreKey = new McastStoreKey(mcastIp, hop.src().deviceId());
+                // It does not exist in the store, exit
+                if (!mcastNextObjStore.containsKey(mcastStoreKey)) {
+                    break;
+                }
+                // Get the output ports on the next
+                nextObj = mcastNextObjStore.get(mcastStoreKey).value();
+                existingPorts = getPorts(nextObj.next());
+                // And the src port on the link
+                srcPort = hop.src().port();
+                // the src port is not used as output, exit
+                if (!existingPorts.contains(srcPort)) {
+                    break;
+                }
+                nhop++;
+            }
+            // n_hop defines the index
+            if (nhop > 0) {
+                eligiblePaths.compute(nhop, (index, paths) -> {
+                    paths = paths == null ? Lists.newArrayList() : paths;
+                    paths.add(path);
+                    return paths;
+                });
+            }
+        }
+
+        // No suitable paths
+        if (eligiblePaths.isEmpty()) {
+            log.debug("No eligiblePath(s) found from {} to {}", src, dst);
+            // Otherwise, randomly pick a path
+            Collections.shuffle(allPaths);
+            return allPaths.stream().findFirst();
+        }
+
+        // Let's take the best ones
+        Integer bestIndex = eligiblePaths.keySet()
+                .stream()
+                .sorted(Comparator.reverseOrder())
+                .findFirst().orElse(null);
+        List<Path> bestPaths = eligiblePaths.get(bestIndex);
+        log.debug("{} eligiblePath(s) found from {} to {}",
+                  bestPaths.size(), src, dst);
+        // randomly pick a path on the highest index
+        Collections.shuffle(bestPaths);
+        return bestPaths.stream().findFirst();
+    }
+
+    /**
+     * Gets device(s) of given role in given multicast group.
+     *
+     * @param mcastIp multicast IP
+     * @param role multicast role
+     * @return set of device ID or empty set if not found
+     */
+    private Set<DeviceId> getDevice(IpAddress mcastIp, McastRole role) {
+        return mcastRoleStore.entrySet().stream()
+                .filter(entry -> entry.getKey().mcastIp().equals(mcastIp) &&
+                        entry.getValue().value() == role)
+                .map(Map.Entry::getKey).map(McastStoreKey::deviceId)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Gets source connect point of given multicast group.
+     *
+     * @param mcastIp multicast IP
+     * @return source connect point or null if not found
+     */
+    private ConnectPoint getSource(IpAddress mcastIp) {
+        return srManager.multicastRouteService.getRoutes().stream()
+                .filter(mcastRoute -> mcastRoute.group().equals(mcastIp))
+                .map(mcastRoute -> srManager.multicastRouteService.fetchSource(mcastRoute))
+                .findAny().orElse(null);
+    }
+
+    /**
+     * Gets groups which is affected by the link down event.
+     *
+     * @param link link going down
+     * @return a set of multicast IpAddress
+     */
+    private Set<IpAddress> getAffectedGroups(Link link) {
+        DeviceId deviceId = link.src().deviceId();
+        PortNumber port = link.src().port();
+        return mcastNextObjStore.entrySet().stream()
+                .filter(entry -> entry.getKey().deviceId().equals(deviceId) &&
+                        getPorts(entry.getValue().value().next()).contains(port))
+                .map(Map.Entry::getKey).map(McastStoreKey::mcastIp)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Gets groups which are affected by the device down event.
+     *
+     * @param deviceId device going down
+     * @return a set of multicast IpAddress
+     */
+    private Set<IpAddress> getAffectedGroups(DeviceId deviceId) {
+        return mcastNextObjStore.entrySet().stream()
+                .filter(entry -> entry.getKey().deviceId().equals(deviceId))
+                .map(Map.Entry::getKey).map(McastStoreKey::mcastIp)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * 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 the spine-facing port on ingress device of given multicast group.
+     *
+     * @param mcastIp multicast IP
+     * @return spine-facing port on ingress device
+     */
+    private PortNumber ingressTransitPort(IpAddress mcastIp) {
+        DeviceId ingressDevice = getDevice(mcastIp, McastRole.INGRESS)
+                .stream().findAny().orElse(null);
+        if (ingressDevice != null) {
+            NextObjective nextObj = mcastNextObjStore
+                    .get(new McastStoreKey(mcastIp, ingressDevice)).value();
+            Set<PortNumber> ports = getPorts(nextObj.next());
+
+            for (PortNumber port : ports) {
+                // Spine-facing port should have no subnet and no xconnect
+                if (srManager.deviceConfiguration != null &&
+                        srManager.deviceConfiguration.getPortSubnets(ingressDevice, port).isEmpty() &&
+                        !srManager.xConnectHandler.hasXConnect(new ConnectPoint(ingressDevice, port))) {
+                    return port;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Verify if the given device has sinks
+     * for the multicast group.
+     *
+     * @param deviceId device Id
+     * @param mcastIp multicast IP
+     * @return true if the device has sink for the group.
+     * False otherwise.
+     */
+    private boolean hasSinks(DeviceId deviceId, IpAddress mcastIp) {
+        if (deviceId != null) {
+            // Get the nextobjective
+            Versioned<NextObjective> versionedNextObj = mcastNextObjStore.get(
+                    new McastStoreKey(mcastIp, deviceId)
+            );
+            // If it exists
+            if (versionedNextObj != null) {
+                NextObjective nextObj = versionedNextObj.value();
+                // Retrieves all the output ports
+                Set<PortNumber> ports = 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
+                    if (srManager.deviceConfiguration != null &&
+                            (!srManager.deviceConfiguration.getPortSubnets(deviceId, port).isEmpty() ||
+                            srManager.xConnectHandler.hasXConnect(new ConnectPoint(deviceId, port)))) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 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) {
+        // 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;
+        }
+
+        FilteringObjective.Builder filtObjBuilder =
+                filterObjBuilder(deviceId, port, assignedVlan, mcastIp);
+        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.
+     *
+     * @param deviceId device ID
+     * @param portNum ingress port number
+     * @param vlanId assigned VLAN ID
+     * @param install true to add, false to remove
+     */
+    protected void updateFilterToDevice(DeviceId deviceId, PortNumber portNum,
+                                        VlanId vlanId, boolean install) {
+        lastMcastChange = Instant.now();
+        mcastLock();
+        try {
+            // Iterates over the route and updates properly the filtering objective
+            // on the source device.
+            srManager.multicastRouteService.getRoutes().forEach(mcastRoute -> {
+                ConnectPoint source = srManager.multicastRouteService.fetchSource(mcastRoute);
+                if (source.deviceId().equals(deviceId) && source.port().equals(portNum)) {
+                    if (install) {
+                        addFilterToDevice(deviceId, portNum, vlanId, mcastRoute.group());
+                    } else {
+                        removeFilterToDevice(deviceId, portNum, vlanId, mcastRoute.group());
+                    }
+                }
+            });
+        } finally {
+            mcastUnlock();
+        }
+    }
+
+    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.
+     * Verification consists in creating new nexts with VERIFY operation. Actually,
+     * the operation is totally delegated to the driver.
+     */
+     private final class McastBucketCorrector implements Runnable {
+
+        @Override
+        public void run() {
+            // Verify if the Mcast has been stable for MCAST_STABLITY_THRESHOLD
+            if (!isMcastStable()) {
+                return;
+            }
+            // Acquires lock
+            mcastLock();
+            try {
+                // Iterates over the routes and verify the related next objectives
+                srManager.multicastRouteService.getRoutes()
+                    .stream()
+                    .map(McastRoute::group)
+                    .forEach(mcastIp -> {
+                        log.trace("Running mcast buckets corrector for mcast group: {}",
+                                  mcastIp);
+
+                        // For each group we get current information in the store
+                        // and issue a check of the next objectives in place
+                        DeviceId ingressDevice = getDevice(mcastIp, McastRole.INGRESS)
+                                .stream().findAny().orElse(null);
+                        DeviceId transitDevice = getDevice(mcastIp, McastRole.TRANSIT)
+                                .stream().findAny().orElse(null);
+                        Set<DeviceId> egressDevices = getDevice(mcastIp, McastRole.EGRESS);
+                        ConnectPoint source = getSource(mcastIp);
+
+                        // Do not proceed if ingress device or source of this group are missing
+                        if (ingressDevice == null || source == null) {
+                            log.warn("Unable to run buckets corrector. " +
+                                             "Missing ingress {} or source {} for group {}",
+                                     ingressDevice, source, mcastIp);
+                            return;
+                        }
+
+                        // Continue only when this instance is the master of source device
+                        if (!srManager.mastershipService.isLocalMaster(source.deviceId())) {
+                            log.trace("Unable to run buckets corrector. " +
+                                             "Skip {} due to lack of mastership " +
+                                             "of the source device {}",
+                                     mcastIp, source.deviceId());
+                            return;
+                        }
+
+                        // Create the set of the devices to be processed
+                        ImmutableSet.Builder<DeviceId> devicesBuilder = ImmutableSet.builder();
+                        devicesBuilder.add(ingressDevice);
+                        if (transitDevice != null) {
+                            devicesBuilder.add(transitDevice);
+                        }
+                        if (!egressDevices.isEmpty()) {
+                            devicesBuilder.addAll(egressDevices);
+                        }
+                        Set<DeviceId> devicesToProcess = devicesBuilder.build();
+
+                        // Iterate over the devices
+                        devicesToProcess.forEach(deviceId -> {
+                            McastStoreKey currentKey = new McastStoreKey(mcastIp, deviceId);
+                            // If next exists in our store verify related next objective
+                            if (mcastNextObjStore.containsKey(currentKey)) {
+                                NextObjective currentNext = mcastNextObjStore.get(currentKey).value();
+                                // Get current ports
+                                Set<PortNumber> currentPorts = getPorts(currentNext.next());
+                                // Rebuild the next objective
+                                currentNext = nextObjBuilder(
+                                        mcastIp,
+                                        assignedVlan(deviceId.equals(source.deviceId()) ? source : null),
+                                        currentPorts,
+                                        currentNext.id()
+                                ).verify();
+                                // Send to the flowobjective service
+                                srManager.flowObjectiveService.next(deviceId, currentNext);
+                            } else {
+                                log.warn("Unable to run buckets corrector." +
+                                                 "Missing next for {} and group {}",
+                                         deviceId, mcastIp);
+                            }
+                        });
+
+                    });
+            } finally {
+                // Finally, it releases the lock
+                mcastUnlock();
+            }
+
+        }
+    }
+
+    public Map<McastStoreKey, Integer> getMcastNextIds(IpAddress mcastIp) {
+        // If mcast ip is present
+        if (mcastIp != null) {
+            return mcastNextObjStore.entrySet().stream()
+                    .filter(mcastEntry -> mcastIp.equals(mcastEntry.getKey().mcastIp()))
+                    .collect(Collectors.toMap(Map.Entry::getKey,
+                                              entry -> entry.getValue().value().id()));
+        }
+        // Otherwise take all the groups
+        return mcastNextObjStore.entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey,
+                                          entry -> entry.getValue().value().id()));
+    }
+
+    public Map<McastStoreKey, McastHandler.McastRole> getMcastRoles(IpAddress mcastIp) {
+        // If mcast ip is present
+        if (mcastIp != null) {
+            return mcastRoleStore.entrySet().stream()
+                    .filter(mcastEntry -> mcastIp.equals(mcastEntry.getKey().mcastIp()))
+                    .collect(Collectors.toMap(Map.Entry::getKey,
+                                              entry -> entry.getValue().value()));
+        }
+        // Otherwise take all the groups
+        return mcastRoleStore.entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey,
+                                          entry -> entry.getValue().value()));
+    }
+
+    public Map<ConnectPoint, List<ConnectPoint>> getMcastPaths(IpAddress mcastIp) {
+        Map<ConnectPoint, List<ConnectPoint>> mcastPaths = Maps.newHashMap();
+        // Get the source
+        ConnectPoint source = getSource(mcastIp);
+        // Source cannot be null, we don't know the starting point
+        if (source != null) {
+            // Init steps
+            Set<DeviceId> visited = Sets.newHashSet();
+            List<ConnectPoint> currentPath = Lists.newArrayList(
+                    source
+            );
+            // Build recursively the mcast paths
+            buildMcastPaths(source.deviceId(), visited, mcastPaths, currentPath, mcastIp);
+        }
+        return mcastPaths;
+    }
+
+    private void buildMcastPaths(DeviceId toVisit, Set<DeviceId> visited,
+                                 Map<ConnectPoint, List<ConnectPoint>> mcastPaths,
+                                 List<ConnectPoint> currentPath, IpAddress mcastIp) {
+        // If we have visited the node to visit
+        // there is a loop
+        if (visited.contains(toVisit)) {
+            return;
+        }
+        // Visit next-hop
+        visited.add(toVisit);
+        McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, toVisit);
+        // Looking for next-hops
+        if (mcastNextObjStore.containsKey(mcastStoreKey)) {
+            // Build egress connectpoints
+            NextObjective nextObjective = mcastNextObjStore.get(mcastStoreKey).value();
+            // Get Ports
+            Set<PortNumber> outputPorts = getPorts(nextObjective.next());
+            // Build relative cps
+            ImmutableSet.Builder<ConnectPoint> cpBuilder = ImmutableSet.builder();
+            outputPorts.forEach(portNumber -> cpBuilder.add(new ConnectPoint(toVisit, portNumber)));
+            Set<ConnectPoint> egressPoints = cpBuilder.build();
+            // Define other variables for the next steps
+            Set<Link> egressLinks;
+            List<ConnectPoint> newCurrentPath;
+            Set<DeviceId> newVisited;
+            DeviceId newToVisit;
+            for (ConnectPoint egressPoint : egressPoints) {
+                egressLinks = srManager.linkService.getEgressLinks(egressPoint);
+                // If it does not have egress links, stop
+                if (egressLinks.isEmpty()) {
+                    // Add the connect points to the path
+                    newCurrentPath = Lists.newArrayList(currentPath);
+                    newCurrentPath.add(0, egressPoint);
+                    // Save in the map
+                    mcastPaths.put(egressPoint, newCurrentPath);
+                } else {
+                    newVisited = Sets.newHashSet(visited);
+                    // Iterate over the egress links for the next hops
+                    for (Link egressLink : egressLinks) {
+                        // Update to visit
+                        newToVisit = egressLink.dst().deviceId();
+                        // Add the connect points to the path
+                        newCurrentPath = Lists.newArrayList(currentPath);
+                        newCurrentPath.add(0, egressPoint);
+                        newCurrentPath.add(0, egressLink.dst());
+                        // Go to the next hop
+                        buildMcastPaths(newToVisit, newVisited, mcastPaths, newCurrentPath, mcastIp);
+                    }
+                }
+            }
+        }
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/Policy.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/Policy.java
new file mode 100644
index 0000000..c9baf93
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/Policy.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2015-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;
+
+/**
+ * Interface for Segment Routing Policy.
+ */
+public interface Policy {
+    /**
+     * Enums for policy type.
+     */
+    enum Type {
+        /**
+         * Tunnel flow policy type.
+         */
+        TUNNEL_FLOW,
+
+        /**
+         * Load balancing policy type.
+         */
+        LOADBALANCE,
+
+        /**
+         * policy to avoid specific routers or links.
+         */
+        AVOID,
+
+        /**
+         * Access Control policy type.
+         */
+        DENY
+    }
+
+    /**
+     * Returns the policy ID.
+     *
+     * @return policy ID
+     */
+    String id();
+
+    /**
+     * Returns the priority of the policy.
+     *
+     * @return priority
+     */
+    int priority();
+
+    /**
+     * Returns the policy type.
+     *
+     * @return policy type
+     */
+    Type type();
+
+    /**
+     * Returns the source IP address of the policy.
+     *
+     * @return source IP address
+     */
+    String srcIp();
+
+    /**
+     * Returns the destination IP address of the policy.
+     *
+     * @return destination IP address
+     */
+    String dstIp();
+
+    /**
+     * Returns the IP protocol of the policy.
+     *
+     * @return IP protocol
+     */
+    String ipProto();
+
+    /**
+     * Returns the source port of the policy.
+     *
+     * @return source port
+     */
+    short srcPort();
+
+    /**
+     * Returns the destination of the policy.
+     *
+     * @return destination port
+     */
+    short dstPort();
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java
new file mode 100644
index 0000000..a341bb1
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2015-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;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.TpPort;
+import org.onosproject.cli.net.IpProtocol;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Segment Routing Policy Handler.
+ */
+public class PolicyHandler {
+
+    protected final Logger log = getLogger(getClass());
+
+    private ApplicationId appId;
+    private DeviceConfiguration deviceConfiguration;
+    private FlowObjectiveService flowObjectiveService;
+    private TunnelHandler tunnelHandler;
+    private final EventuallyConsistentMap<String, Policy> policyStore;
+    /**
+     * Result of policy creation.
+     */
+    public enum Result {
+        /**
+         * Success.
+         */
+        SUCCESS,
+
+        /**
+         * The same policy exists already.
+         */
+        POLICY_EXISTS,
+
+        /**
+         * The policy ID exists already.
+         */
+        ID_EXISTS,
+
+        /**
+         * Cannot find associated tunnel.
+         */
+        TUNNEL_NOT_FOUND,
+
+        /**
+         * Policy was not found.
+         */
+        POLICY_NOT_FOUND,
+
+        /**
+         * Policy type {} is not supported yet.
+         */
+        UNSUPPORTED_TYPE
+    }
+
+    /**
+     * Constructs policy handler.
+     *
+     * @param appId                segment routing application ID
+     * @param deviceConfiguration  DeviceConfiguration reference
+     * @param flowObjectiveService FlowObjectiveService reference
+     * @param tunnelHandler        tunnel handler reference
+     * @param policyStore          policy store
+     */
+    public PolicyHandler(ApplicationId appId,
+                         DeviceConfiguration deviceConfiguration,
+                         FlowObjectiveService flowObjectiveService,
+                         TunnelHandler tunnelHandler,
+                         EventuallyConsistentMap<String, Policy> policyStore) {
+        this.appId = appId;
+        this.deviceConfiguration = deviceConfiguration;
+        this.flowObjectiveService = flowObjectiveService;
+        this.tunnelHandler = tunnelHandler;
+        this.policyStore = policyStore;
+    }
+
+    /**
+     * Returns the policies.
+     *
+     * @return policy list
+     */
+    public List<Policy> getPolicies() {
+        return policyStore.values()
+                .stream()
+                .filter(policy -> policy instanceof TunnelPolicy)
+                .map(policy -> new TunnelPolicy((TunnelPolicy) policy))
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Creates a policy using the policy information given.
+     *  @param policy policy reference to create
+     *  @return ID_EXISTS if the same policy ID exists,
+     *  POLICY_EXISTS if the same policy exists, TUNNEL_NOT_FOUND if the tunnel
+     *  does not exists, UNSUPPORTED_TYPE if the policy type is not supported,
+     *  SUCCESS if the policy is created successfully
+     */
+    public Result createPolicy(Policy policy) {
+
+        if (policyStore.containsKey(policy.id())) {
+            log.warn("The policy id {} exists already", policy.id());
+            return Result.ID_EXISTS;
+        }
+
+        if (policyStore.containsValue(policy)) {
+            log.warn("The same policy exists already");
+            return Result.POLICY_EXISTS;
+        }
+
+        if (policy.type() == Policy.Type.TUNNEL_FLOW) {
+
+            TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
+            Tunnel tunnel = tunnelHandler.getTunnel(tunnelPolicy.tunnelId());
+            if (tunnel == null) {
+                return Result.TUNNEL_NOT_FOUND;
+            }
+
+            ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
+                    .builder()
+                    .fromApp(appId)
+                    .makePermanent()
+                    .nextStep(tunnel.groupId())
+                    .withPriority(tunnelPolicy.priority())
+                    .withSelector(buildSelector(policy))
+                    .withFlag(ForwardingObjective.Flag.VERSATILE);
+
+            DeviceId source = deviceConfiguration.getDeviceId(tunnel.labelIds().get(0));
+            flowObjectiveService.forward(source, fwdBuilder.add());
+
+        } else {
+            log.warn("Policy type {} is not supported yet.", policy.type());
+            return Result.UNSUPPORTED_TYPE;
+        }
+
+        policyStore.put(policy.id(), policy);
+
+        return Result.SUCCESS;
+    }
+
+    /**
+     * Removes the policy given.
+     *
+     * @param policyInfo policy information to remove
+     * @return POLICY_NOT_FOUND if the policy to remove does not exists,
+     * SUCCESS if it is removed successfully
+     */
+    public Result removePolicy(Policy policyInfo) {
+
+        if (policyStore.get(policyInfo.id()) != null) {
+            Policy policy = policyStore.get(policyInfo.id());
+            if (policy.type() == Policy.Type.TUNNEL_FLOW) {
+                TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
+                Tunnel tunnel = tunnelHandler.getTunnel(tunnelPolicy.tunnelId());
+
+                ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
+                        .builder()
+                        .fromApp(appId)
+                        .makePermanent()
+                        .withSelector(buildSelector(policy))
+                        .withPriority(tunnelPolicy.priority())
+                        .nextStep(tunnel.groupId())
+                        .withFlag(ForwardingObjective.Flag.VERSATILE);
+
+                DeviceId source = deviceConfiguration.getDeviceId(tunnel.labelIds().get(0));
+                flowObjectiveService.forward(source, fwdBuilder.remove());
+
+                policyStore.remove(policyInfo.id());
+            }
+        } else {
+            log.warn("Policy {} was not found", policyInfo.id());
+            return Result.POLICY_NOT_FOUND;
+        }
+
+        return Result.SUCCESS;
+    }
+
+
+    private TrafficSelector buildSelector(Policy policy) {
+
+        TrafficSelector.Builder tsb = DefaultTrafficSelector.builder();
+        tsb.matchEthType(Ethernet.TYPE_IPV4);
+        if (policy.dstIp() != null && !policy.dstIp().isEmpty()) {
+            tsb.matchIPDst(IpPrefix.valueOf(policy.dstIp()));
+        }
+        if (policy.srcIp() != null && !policy.srcIp().isEmpty()) {
+            tsb.matchIPSrc(IpPrefix.valueOf(policy.srcIp()));
+        }
+        if (policy.ipProto() != null && !policy.ipProto().isEmpty()) {
+            Short ipProto = IpProtocol.valueOf(policy.ipProto()).value();
+            tsb.matchIPProtocol(ipProto.byteValue());
+            if (IpProtocol.valueOf(policy.ipProto()).equals(IpProtocol.TCP)) {
+                if (policy.srcPort() != 0) {
+                    tsb.matchTcpSrc(TpPort.tpPort(policy.srcPort()));
+                }
+                if (policy.dstPort() != 0) {
+                    tsb.matchTcpDst(TpPort.tpPort(policy.dstPort()));
+                }
+            } else if (IpProtocol.valueOf(policy.ipProto()).equals(IpProtocol.UDP)) {
+                if (policy.srcPort() != 0) {
+                    tsb.matchUdpSrc(TpPort.tpPort(policy.srcPort()));
+                }
+                if (policy.dstPort() != 0) {
+                    tsb.matchUdpDst(TpPort.tpPort(policy.dstPort()));
+                }
+            }
+        }
+
+        return tsb.build();
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/PortAuthTracker.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/PortAuthTracker.java
new file mode 100644
index 0000000..2127019
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/PortAuthTracker.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2017-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;
+
+
+import com.google.common.base.Objects;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.segmentrouting.config.BlockedPortsConfig;
+import org.onosproject.utils.Comparators;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.portNumber;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Keeps track of ports that have been configured for blocking,
+ * and their current authentication state.
+ */
+public class PortAuthTracker {
+
+    private static final Logger log = getLogger(PortAuthTracker.class);
+
+    private Map<DeviceId, Map<PortNumber, BlockState>> blockedPorts = new HashMap<>();
+    private Map<DeviceId, Map<PortNumber, BlockState>> oldMap;
+
+    @Override
+    public String toString() {
+        return "PortAuthTracker{entries = " + blockedPorts.size() + "}";
+    }
+
+    /**
+     * Changes the state of the given device id / port number pair to the
+     * specified state.
+     *
+     * @param d        device identifier
+     * @param p        port number
+     * @param newState the updated state
+     * @return true, if the state changed from what was previously mapped
+     */
+    private boolean changeStateTo(DeviceId d, PortNumber p, BlockState newState) {
+        Map<PortNumber, BlockState> portMap =
+                blockedPorts.computeIfAbsent(d, k -> new HashMap<>());
+        BlockState oldState =
+                portMap.computeIfAbsent(p, k -> BlockState.UNCHECKED);
+        portMap.put(p, newState);
+        return (oldState != newState);
+    }
+
+    /**
+     * Radius has authorized the supplicant at this connect point. If
+     * we are tracking this port, clear the blocking flow and mark the
+     * port as authorized.
+     *
+     * @param connectPoint supplicant connect point
+     */
+    void radiusAuthorize(ConnectPoint connectPoint) {
+        DeviceId d = connectPoint.deviceId();
+        PortNumber p = connectPoint.port();
+        if (configured(d, p)) {
+            clearBlockingFlow(d, p);
+            markAsAuthenticated(d, p);
+        }
+    }
+
+    /**
+     * Supplicant at specified connect point has logged off Radius. If
+     * we are tracking this port, install a blocking flow and mark the
+     * port as blocked.
+     *
+     * @param connectPoint supplicant connect point
+     */
+    void radiusLogoff(ConnectPoint connectPoint) {
+        DeviceId d = connectPoint.deviceId();
+        PortNumber p = connectPoint.port();
+        if (configured(d, p)) {
+            installBlockingFlow(d, p);
+            markAsBlocked(d, p);
+        }
+    }
+
+    /**
+     * Marks the specified device/port as blocked.
+     *
+     * @param d device id
+     * @param p port number
+     * @return true if the state changed (was not already blocked)
+     */
+    private boolean markAsBlocked(DeviceId d, PortNumber p) {
+        return changeStateTo(d, p, BlockState.BLOCKED);
+    }
+
+    /**
+     * Marks the specified device/port as authenticated.
+     *
+     * @param d device id
+     * @param p port number
+     * @return true if the state changed (was not already authenticated)
+     */
+    private boolean markAsAuthenticated(DeviceId d, PortNumber p) {
+        return changeStateTo(d, p, BlockState.AUTHENTICATED);
+    }
+
+    /**
+     * Returns true if the given device/port are configured for blocking.
+     *
+     * @param d device id
+     * @param p port number
+     * @return true if this device/port configured for blocking
+     */
+    private boolean configured(DeviceId d, PortNumber p) {
+        Map<PortNumber, BlockState> portMap = blockedPorts.get(d);
+        return portMap != null && portMap.get(p) != null;
+    }
+
+    private BlockState whatState(DeviceId d, PortNumber p,
+                                 Map<DeviceId, Map<PortNumber, BlockState>> m) {
+        Map<PortNumber, BlockState> portMap = m.get(d);
+        if (portMap == null) {
+            return BlockState.UNCHECKED;
+        }
+        BlockState state = portMap.get(p);
+        if (state == null) {
+            return BlockState.UNCHECKED;
+        }
+        return state;
+    }
+
+    /**
+     * Returns the current state of the given device/port.
+     *
+     * @param d device id
+     * @param p port number
+     * @return current block-state
+     */
+    BlockState currentState(DeviceId d, PortNumber p) {
+        return whatState(d, p, blockedPorts);
+    }
+
+    /**
+     * Returns the current state of the given connect point.
+     *
+     * @param cp connect point
+     * @return current block-state
+     */
+
+    BlockState currentState(ConnectPoint cp) {
+        return whatState(cp.deviceId(), cp.port(), blockedPorts);
+    }
+
+    /**
+     * Returns the number of entries being tracked.
+     *
+     * @return the number of tracked entries
+     */
+    int entryCount() {
+        int count = 0;
+        for (Map<PortNumber, BlockState> m : blockedPorts.values()) {
+            count += m.size();
+        }
+        return count;
+    }
+
+    /**
+     * Returns the previously recorded state of the given device/port.
+     *
+     * @param d device id
+     * @param p port number
+     * @return previous block-state
+     */
+    private BlockState oldState(DeviceId d, PortNumber p) {
+        return whatState(d, p, oldMap);
+    }
+
+    private void configurePort(DeviceId d, PortNumber p) {
+        boolean alreadyAuthenticated =
+                oldState(d, p) == BlockState.AUTHENTICATED;
+
+        if (alreadyAuthenticated) {
+            clearBlockingFlow(d, p);
+            markAsAuthenticated(d, p);
+        } else {
+            installBlockingFlow(d, p);
+            markAsBlocked(d, p);
+        }
+        log.info("Configuring port {}/{} as {}", d, p,
+                 alreadyAuthenticated ? "AUTHENTICATED" : "BLOCKED");
+    }
+
+    private boolean notInMap(DeviceId deviceId, PortNumber portNumber) {
+        Map<PortNumber, BlockState> m = blockedPorts.get(deviceId);
+        return m == null || m.get(portNumber) == null;
+    }
+
+    private void logPortsNoLongerBlocked() {
+        for (Map.Entry<DeviceId, Map<PortNumber, BlockState>> entry :
+                oldMap.entrySet()) {
+            DeviceId d = entry.getKey();
+            Map<PortNumber, BlockState> portMap = entry.getValue();
+
+            for (PortNumber p : portMap.keySet()) {
+                if (notInMap(d, p)) {
+                    clearBlockingFlow(d, p);
+                    log.info("De-configuring port {}/{} (UNCHECKED)", d, p);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Reconfigures the port tracker using the supplied configuration.
+     *
+     * @param cfg the new configuration
+     */
+    void configurePortBlocking(BlockedPortsConfig cfg) {
+        // remember the old map; prepare a new map
+        oldMap = blockedPorts;
+        blockedPorts = new HashMap<>();
+
+        // for each configured device, add configured ports to map
+        for (String devId : cfg.deviceIds()) {
+            cfg.portIterator(devId)
+                    .forEachRemaining(p -> configurePort(deviceId(devId),
+                                                         portNumber(p)));
+        }
+
+        // have we de-configured any ports?
+        logPortsNoLongerBlocked();
+
+        // allow old map to be garbage collected
+        oldMap = null;
+    }
+
+    private List<PortAuthState> reportPortsAuthState() {
+        List<PortAuthState> result = new ArrayList<>();
+
+        for (Map.Entry<DeviceId, Map<PortNumber, BlockState>> entry :
+                blockedPorts.entrySet()) {
+            DeviceId d = entry.getKey();
+            Map<PortNumber, BlockState> portMap = entry.getValue();
+
+            for (PortNumber p : portMap.keySet()) {
+                result.add(new PortAuthState(d, p, portMap.get(p)));
+            }
+        }
+        Collections.sort(result);
+        return result;
+    }
+
+    /**
+     * Installs a "blocking" flow for device/port specified.
+     *
+     * @param d device id
+     * @param p port number
+     */
+    void installBlockingFlow(DeviceId d, PortNumber p) {
+        log.debug("Installing Blocking Flow at {}/{}", d, p);
+        // TODO: invoke SegmentRoutingService.block(...) appropriately
+        log.info("TODO >> Installing Blocking Flow at {}/{}", d, p);
+    }
+
+    /**
+     * Removes the "blocking" flow from device/port specified.
+     *
+     * @param d device id
+     * @param p port number
+     */
+    void clearBlockingFlow(DeviceId d, PortNumber p) {
+        log.debug("Clearing Blocking Flow from {}/{}", d, p);
+        // TODO: invoke SegmentRoutingService.block(...) appropriately
+        log.info("TODO >> Clearing Blocking Flow from {}/{}", d, p);
+    }
+
+
+    /**
+     * Designates the state of a given port. One of:
+     * <ul>
+     * <li> UNCHECKED: not configured for blocking </li>
+     * <li> BLOCKED: configured for blocking, and not yet authenticated </li>
+     * <li> AUTHENTICATED: configured for blocking, but authenticated </li>
+     * </ul>
+     */
+    public enum BlockState {
+        UNCHECKED,
+        BLOCKED,
+        AUTHENTICATED
+    }
+
+    /**
+     * A simple DTO binding of device identifier, port number, and block state.
+     */
+    public static final class PortAuthState implements Comparable<PortAuthState> {
+        private final DeviceId d;
+        private final PortNumber p;
+        private final BlockState s;
+
+        private PortAuthState(DeviceId d, PortNumber p, BlockState s) {
+            this.d = d;
+            this.p = p;
+            this.s = s;
+        }
+
+        @Override
+        public String toString() {
+            return String.valueOf(d) + "/" + p + " -- " + s;
+        }
+
+        @Override
+        public int compareTo(PortAuthState o) {
+            // NOTE: only compare against "deviceid/port"
+            int result = Comparators.ELEMENT_ID_COMPARATOR.compare(d, o.d);
+            return (result != 0) ? result : Long.signum(p.toLong() - o.p.toLong());
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            final PortAuthTracker.PortAuthState that = (PortAuthTracker.PortAuthState) obj;
+
+            return Comparators.ELEMENT_ID_COMPARATOR.compare(this.d, that.d) == 0 &&
+                    p.toLong() == that.p.toLong();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(this.d, this.p);
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
new file mode 100644
index 0000000..21870ee
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.RemovalCause;
+import com.google.common.cache.RemovalNotification;
+import com.google.common.collect.Sets;
+
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.routeservice.ResolvedRoute;
+import org.onosproject.routeservice.RouteEvent;
+import org.onosproject.net.DeviceId;
+import org.onosproject.routeservice.RouteInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * Handles RouteEvent and manages routing entries.
+ */
+public class RouteHandler {
+    private static final Logger log = LoggerFactory.getLogger(RouteHandler.class);
+    private final SegmentRoutingManager srManager;
+
+    private static final int WAIT_TIME_MS = 1000;
+    /**
+     * The routeEventCache is implemented to avoid race condition by giving more time to the
+     * underlying flow subsystem to process previous populateSubnet call.
+     */
+    private Cache<IpPrefix, RouteEvent> routeEventCache = CacheBuilder.newBuilder()
+            .expireAfterWrite(WAIT_TIME_MS, TimeUnit.MILLISECONDS)
+            .removalListener((RemovalNotification<IpPrefix, RouteEvent> notification) -> {
+                IpPrefix prefix = notification.getKey();
+                RouteEvent routeEvent = notification.getValue();
+                RemovalCause cause = notification.getCause();
+                log.debug("routeEventCache removal event. prefix={}, routeEvent={}, cause={}",
+                        prefix, routeEvent, cause);
+
+                switch (notification.getCause()) {
+                    case REPLACED:
+                    case EXPIRED:
+                        dequeueRouteEvent(routeEvent);
+                        break;
+                    default:
+                        break;
+                }
+            }).build();
+
+    RouteHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+
+        Executors.newSingleThreadScheduledExecutor()
+                .scheduleAtFixedRate(routeEventCache::cleanUp, 0, WAIT_TIME_MS, TimeUnit.MILLISECONDS);
+    }
+
+    protected void init(DeviceId deviceId) {
+        srManager.routeService.getRouteTables().forEach(routeTableId ->
+            srManager.routeService.getRoutes(routeTableId).forEach(routeInfo ->
+                routeInfo.allRoutes().forEach(resolvedRoute ->
+                    srManager.nextHopLocations(resolvedRoute).stream()
+                            .filter(location -> deviceId.equals(location.deviceId()))
+                            .forEach(location -> processRouteAddedInternal(resolvedRoute)
+                    )
+                )
+            )
+        );
+    }
+
+    void processRouteAdded(RouteEvent event) {
+        enqueueRouteEvent(event);
+    }
+
+    private void processRouteAddedInternal(ResolvedRoute route) {
+        processRouteAddedInternal(Sets.newHashSet(route));
+    }
+
+    private void processRouteAddedInternal(Collection<ResolvedRoute> routes) {
+        if (!isReady()) {
+            log.info("System is not ready. Skip adding route for {}", routes);
+            return;
+        }
+
+        log.info("processRouteAddedInternal. routes={}", routes);
+
+        Set<ConnectPoint> allLocations = Sets.newHashSet();
+        Set<IpPrefix> allPrefixes = Sets.newHashSet();
+        routes.forEach(route -> {
+            allLocations.addAll(srManager.nextHopLocations(route));
+            allPrefixes.add(route.prefix());
+        });
+        log.debug("RouteAdded. populateSubnet {}, {}", allLocations, allPrefixes);
+        srManager.defaultRoutingHandler.populateSubnet(allLocations, allPrefixes);
+
+        routes.forEach(route -> {
+            IpPrefix prefix = route.prefix();
+            MacAddress nextHopMac = route.nextHopMac();
+            VlanId nextHopVlan = route.nextHopVlan();
+            Set<ConnectPoint> locations = srManager.nextHopLocations(route);
+
+            locations.forEach(location -> {
+                log.debug("RouteAdded. addSubnet {}, {}", location, prefix);
+                srManager.deviceConfiguration.addSubnet(location, prefix);
+                log.debug("RouteAdded populateRoute {}, {}, {}, {}", location, prefix, nextHopMac, nextHopVlan);
+                srManager.defaultRoutingHandler.populateRoute(location.deviceId(), prefix,
+                        nextHopMac, nextHopVlan, location.port());
+            });
+        });
+    }
+
+    void processRouteUpdated(RouteEvent event) {
+        enqueueRouteEvent(event);
+    }
+
+    void processAlternativeRoutesChanged(RouteEvent event) {
+        enqueueRouteEvent(event);
+    }
+
+    private void processRouteUpdatedInternal(Set<ResolvedRoute> routes, Set<ResolvedRoute> oldRoutes) {
+        if (!isReady()) {
+            log.info("System is not ready. Skip updating route for {} -> {}", oldRoutes, routes);
+            return;
+        }
+
+        log.info("processRouteUpdatedInternal. routes={}, oldRoutes={}", routes, oldRoutes);
+
+        Set<ConnectPoint> allLocations = Sets.newHashSet();
+        Set<IpPrefix> allPrefixes = Sets.newHashSet();
+        routes.forEach(route -> {
+            allLocations.addAll(srManager.nextHopLocations(route));
+            allPrefixes.add(route.prefix());
+        });
+        log.debug("RouteUpdated. populateSubnet {}, {}", allLocations, allPrefixes);
+        srManager.defaultRoutingHandler.populateSubnet(allLocations, allPrefixes);
+
+        Set<ResolvedRoute> toBeRemoved = Sets.difference(oldRoutes, routes).immutableCopy();
+        Set<ResolvedRoute> toBeAdded = Sets.difference(routes, oldRoutes).immutableCopy();
+
+        toBeRemoved.forEach(route -> {
+            srManager.nextHopLocations(route).forEach(oldLocation -> {
+                if (toBeAdded.stream().map(srManager::nextHopLocations)
+                        .flatMap(Set::stream).map(ConnectPoint::deviceId)
+                        .noneMatch(deviceId -> deviceId.equals(oldLocation.deviceId()))) {
+                    IpPrefix prefix = route.prefix();
+                    log.debug("RouteUpdated. removeSubnet {}, {}", oldLocation, prefix);
+                    srManager.deviceConfiguration.removeSubnet(oldLocation, prefix);
+                    // We don't remove the flow on the old location in occasion of two next hops becoming one
+                    // since the populateSubnet will point the old location to the new location via spine.
+                }
+            });
+        });
+
+        toBeAdded.forEach(route -> {
+            IpPrefix prefix = route.prefix();
+            MacAddress nextHopMac = route.nextHopMac();
+            VlanId nextHopVlan = route.nextHopVlan();
+            Set<ConnectPoint> locations = srManager.nextHopLocations(route);
+
+            locations.forEach(location -> {
+                log.debug("RouteUpdated. addSubnet {}, {}", location, prefix);
+                srManager.deviceConfiguration.addSubnet(location, prefix);
+                log.debug("RouteUpdated. populateRoute {}, {}, {}, {}", location, prefix, nextHopMac, nextHopVlan);
+                srManager.defaultRoutingHandler.populateRoute(location.deviceId(), prefix,
+                        nextHopMac, nextHopVlan, location.port());
+            });
+        });
+    }
+
+    void processRouteRemoved(RouteEvent event) {
+        enqueueRouteEvent(event);
+    }
+
+    private void processRouteRemovedInternal(Collection<ResolvedRoute> routes) {
+        if (!isReady()) {
+            log.info("System is not ready. Skip removing route for {}", routes);
+            return;
+        }
+
+        log.info("processRouteRemovedInternal. routes={}", routes);
+
+        Set<IpPrefix> allPrefixes = Sets.newHashSet();
+        routes.forEach(route -> {
+            allPrefixes.add(route.prefix());
+        });
+        log.debug("RouteRemoved. revokeSubnet {}", allPrefixes);
+        srManager.defaultRoutingHandler.revokeSubnet(allPrefixes);
+
+        routes.forEach(route -> {
+            IpPrefix prefix = route.prefix();
+            MacAddress nextHopMac = route.nextHopMac();
+            VlanId nextHopVlan = route.nextHopVlan();
+            Set<ConnectPoint> locations = srManager.nextHopLocations(route);
+
+            locations.forEach(location -> {
+                log.debug("RouteRemoved. removeSubnet {}, {}", location, prefix);
+                srManager.deviceConfiguration.removeSubnet(location, prefix);
+                log.debug("RouteRemoved. revokeRoute {}, {}, {}, {}", location, prefix, nextHopMac, nextHopVlan);
+                srManager.defaultRoutingHandler.revokeRoute(location.deviceId(), prefix,
+                        nextHopMac, nextHopVlan, location.port());
+
+                // Also remove redirection flows on the pair device if exists.
+                Optional<DeviceId> pairDeviceId = srManager.getPairDeviceId(location.deviceId());
+                Optional<PortNumber> pairLocalPort = srManager.getPairLocalPorts(location.deviceId());
+                if (pairDeviceId.isPresent() && pairLocalPort.isPresent()) {
+                    // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
+                    //       when the host is untagged
+                    VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(location)).orElse(nextHopVlan);
+
+                    log.debug("RouteRemoved. revokeRoute {}, {}, {}, {}", location, prefix, nextHopMac, nextHopVlan);
+                    srManager.defaultRoutingHandler.revokeRoute(pairDeviceId.get(), prefix,
+                            nextHopMac, vlanId, pairLocalPort.get());
+                }
+            });
+        });
+    }
+
+    void processHostMovedEvent(HostEvent event) {
+        log.info("processHostMovedEvent {}", event);
+        MacAddress hostMac = event.subject().mac();
+        VlanId hostVlanId = event.subject().vlan();
+
+        affectedRoutes(hostMac, hostVlanId).forEach(affectedRoute -> {
+            IpPrefix prefix = affectedRoute.prefix();
+            Set<HostLocation> prevLocations = event.prevSubject().locations();
+            Set<HostLocation> newLocations = event.subject().locations();
+
+            // For each old location
+            Sets.difference(prevLocations, newLocations).stream().filter(srManager::isMasterOf)
+                    .forEach(prevLocation -> {
+                // Redirect the flows to pair link if configured
+                // Note: Do not continue removing any rule
+                Optional<DeviceId> pairDeviceId = srManager.getPairDeviceId(prevLocation.deviceId());
+                Optional<PortNumber> pairLocalPort = srManager.getPairLocalPorts(prevLocation.deviceId());
+                if (pairDeviceId.isPresent() && pairLocalPort.isPresent() && newLocations.stream()
+                        .anyMatch(location -> location.deviceId().equals(pairDeviceId.get()))) {
+                    // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
+                    //       when the host is untagged
+                    VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(prevLocation)).orElse(hostVlanId);
+                    log.debug("HostMoved. populateRoute {}, {}, {}, {}", prevLocation, prefix, hostMac, vlanId);
+                    srManager.defaultRoutingHandler.populateRoute(prevLocation.deviceId(), prefix,
+                            hostMac, vlanId, pairLocalPort.get());
+                    return;
+                }
+
+                // No pair information supplied. Remove route
+                log.debug("HostMoved. revokeRoute {}, {}, {}, {}", prevLocation, prefix, hostMac, hostVlanId);
+                srManager.defaultRoutingHandler.revokeRoute(prevLocation.deviceId(), prefix,
+                        hostMac, hostVlanId, prevLocation.port());
+            });
+
+            // For each new location, add all new IPs.
+            Sets.difference(newLocations, prevLocations).stream().filter(srManager::isMasterOf)
+                    .forEach(newLocation -> {
+                log.debug("HostMoved. populateRoute {}, {}, {}, {}", newLocation, prefix, hostMac, hostVlanId);
+                srManager.defaultRoutingHandler.populateRoute(newLocation.deviceId(), prefix,
+                        hostMac, hostVlanId, newLocation.port());
+            });
+
+        });
+    }
+
+    private Set<ResolvedRoute> affectedRoutes(MacAddress mac, VlanId vlanId) {
+        return srManager.routeService.getRouteTables().stream()
+                .map(routeTableId -> srManager.routeService.getRoutes(routeTableId))
+                .flatMap(Collection::stream)
+                .map(RouteInfo::allRoutes)
+                .flatMap(Collection::stream)
+                .filter(resolvedRoute -> mac.equals(resolvedRoute.nextHopMac()) &&
+                        vlanId.equals(resolvedRoute.nextHopVlan())).collect(Collectors.toSet());
+    }
+
+    private boolean isReady() {
+        return Objects.nonNull(srManager.deviceConfiguration) &&
+                Objects.nonNull(srManager.defaultRoutingHandler);
+    }
+
+    void enqueueRouteEvent(RouteEvent routeEvent) {
+        log.debug("Enqueue routeEvent {}", routeEvent);
+        routeEventCache.put(routeEvent.subject().prefix(), routeEvent);
+    }
+
+    void dequeueRouteEvent(RouteEvent routeEvent) {
+        log.debug("Dequeue routeEvent {}", routeEvent);
+        switch (routeEvent.type()) {
+            case ROUTE_ADDED:
+                processRouteAddedInternal(routeEvent.alternatives());
+                break;
+            case ROUTE_REMOVED:
+                processRouteRemovedInternal(routeEvent.alternatives());
+                break;
+            case ROUTE_UPDATED:
+            case ALTERNATIVE_ROUTES_CHANGED:
+                processRouteUpdatedInternal(Sets.newHashSet(routeEvent.alternatives()),
+                        Sets.newHashSet(routeEvent.prevAlternatives()));
+                break;
+            default:
+                break;
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
new file mode 100644
index 0000000..f37caea
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -0,0 +1,1250 @@
+/*
+ * Copyright 2015-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;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.flowobjective.DefaultObjectiveContext;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.segmentrouting.DefaultRoutingHandler.PortFilterInfo;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
+import org.onosproject.segmentrouting.grouphandler.DestinationSet;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+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.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective.Builder;
+import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.packet.Ethernet.TYPE_ARP;
+import static org.onlab.packet.Ethernet.TYPE_IPV6;
+import static org.onlab.packet.ICMP6.NEIGHBOR_ADVERTISEMENT;
+import static org.onlab.packet.ICMP6.NEIGHBOR_SOLICITATION;
+import static org.onlab.packet.ICMP6.ROUTER_ADVERTISEMENT;
+import static org.onlab.packet.ICMP6.ROUTER_SOLICITATION;
+import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
+import static org.onosproject.segmentrouting.SegmentRoutingManager.INTERNAL_VLAN;
+
+/**
+ * Populator of segment routing flow rules.
+ */
+public class RoutingRulePopulator {
+    private static final Logger log = LoggerFactory.getLogger(RoutingRulePopulator.class);
+
+    private static final int ARP_NDP_PRIORITY = 30000;
+
+    private AtomicLong rulePopulationCounter;
+    private SegmentRoutingManager srManager;
+    private DeviceConfiguration config;
+
+    /**
+     * Creates a RoutingRulePopulator object.
+     *
+     * @param srManager segment routing manager reference
+     */
+    RoutingRulePopulator(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.deviceConfiguration);
+        this.rulePopulationCounter = new AtomicLong(0);
+    }
+
+    /**
+     * Resets the population counter.
+     */
+    void resetCounter() {
+        rulePopulationCounter.set(0);
+    }
+
+    /**
+     * Returns the number of rules populated.
+     *
+     * @return number of rules
+     */
+    long getCounter() {
+        return rulePopulationCounter.get();
+    }
+
+    /**
+     * Populates IP rules for a route that has direct connection to the
+     * switch.
+     *
+     * @param deviceId device ID of the device that next hop attaches to
+     * @param prefix IP prefix of the route
+     * @param hostMac MAC address of the next hop
+     * @param hostVlanId Vlan ID of the nexthop
+     * @param outPort port where the next hop attaches to
+     */
+    void populateRoute(DeviceId deviceId, IpPrefix prefix,
+                              MacAddress hostMac, VlanId hostVlanId, PortNumber outPort) {
+        log.debug("Populate direct routing entry for route {} at {}:{}",
+                prefix, deviceId, outPort);
+        ForwardingObjective.Builder fwdBuilder;
+        try {
+            fwdBuilder = routingFwdObjBuilder(deviceId, prefix, hostMac,
+                                              hostVlanId, outPort, false);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting direct populateRoute");
+            return;
+        }
+        if (fwdBuilder == null) {
+            log.warn("Aborting host routing table entry due "
+                    + "to error for dev:{} route:{}", deviceId, prefix);
+            return;
+        }
+
+        int nextId = fwdBuilder.add().nextId();
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("Direct routing rule for route {} populated. nextId={}",
+                                         prefix, nextId),
+                (objective, error) ->
+                        log.warn("Failed to populate direct routing rule for route {}: {}",
+                                 prefix, error));
+        srManager.flowObjectiveService.forward(deviceId, fwdBuilder.add(context));
+        rulePopulationCounter.incrementAndGet();
+    }
+
+    /**
+     * Removes IP rules for a route when the next hop is gone.
+     *
+     * @param deviceId device ID of the device that next hop attaches to
+     * @param prefix IP prefix of the route
+     * @param hostMac MAC address of the next hop
+     * @param hostVlanId Vlan ID of the nexthop
+     * @param outPort port that next hop attaches to
+     */
+    void revokeRoute(DeviceId deviceId, IpPrefix prefix,
+            MacAddress hostMac, VlanId hostVlanId, PortNumber outPort) {
+        log.debug("Revoke IP table entry for route {} at {}:{}",
+                prefix, deviceId, outPort);
+        ForwardingObjective.Builder fwdBuilder;
+        try {
+            fwdBuilder = routingFwdObjBuilder(deviceId, prefix, hostMac,
+                                              hostVlanId, outPort, true);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting revokeIpRuleForHost.");
+            return;
+        }
+        if (fwdBuilder == null) {
+            log.warn("Aborting host routing table entries due "
+                    + "to error for dev:{} route:{}", deviceId, prefix);
+            return;
+        }
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("IP rule for route {} revoked", prefix),
+                (objective, error) ->
+                        log.warn("Failed to revoke IP rule for route {}: {}", prefix, error));
+        srManager.flowObjectiveService.forward(deviceId, fwdBuilder.remove(context));
+    }
+
+    /**
+     * Returns a forwarding objective builder for routing rules.
+     * <p>
+     * The forwarding objective routes packets destined to a given prefix to
+     * given port on given device with given destination MAC.
+     *
+     * @param deviceId device ID
+     * @param prefix prefix that need to be routed
+     * @param hostMac MAC address of the nexthop
+     * @param hostVlanId Vlan ID of the nexthop
+     * @param outPort port where the nexthop attaches to
+     * @param revoke true if forwarding objective is meant to revoke forwarding rule
+     * @return forwarding objective builder
+     * @throws DeviceConfigNotFoundException if given device is not configured
+     */
+    private ForwardingObjective.Builder routingFwdObjBuilder(
+            DeviceId deviceId, IpPrefix prefix,
+            MacAddress hostMac, VlanId hostVlanId, PortNumber outPort,
+            boolean revoke)
+            throws DeviceConfigNotFoundException {
+        MacAddress deviceMac;
+        deviceMac = config.getDeviceMac(deviceId);
+
+        ConnectPoint connectPoint = new ConnectPoint(deviceId, outPort);
+        VlanId untaggedVlan = srManager.getUntaggedVlanId(connectPoint);
+        Set<VlanId> taggedVlans = srManager.getTaggedVlanId(connectPoint);
+        VlanId nativeVlan = srManager.getNativeVlanId(connectPoint);
+
+        // Create route selector
+        TrafficSelector.Builder sbuilder = buildIpSelectorFromIpPrefix(prefix);
+
+        // Create route treatment
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+        tbuilder.deferred()
+                .setEthDst(hostMac)
+                .setEthSrc(deviceMac)
+                .setOutput(outPort);
+
+        // Create route meta
+        TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
+
+        // Adjust the meta according to VLAN configuration
+        if (taggedVlans.contains(hostVlanId)) {
+            tbuilder.setVlanId(hostVlanId);
+        } else if (hostVlanId.equals(VlanId.NONE)) {
+            if (untaggedVlan != null) {
+                mbuilder.matchVlanId(untaggedVlan);
+            } else if (nativeVlan != null) {
+                mbuilder.matchVlanId(nativeVlan);
+            } else {
+                log.warn("Untagged nexthop {}/{} is not allowed on {} without untagged or native vlan",
+                        hostMac, hostVlanId, connectPoint);
+                return null;
+            }
+        } else {
+            log.warn("Tagged nexthop {}/{} is not allowed on {} without VLAN listed"
+                    + " in tagged vlan", hostMac, hostVlanId, connectPoint);
+            return null;
+        }
+        // if the objective is to revoke an existing rule, and for some reason
+        // the next-objective does not exist, then a new one should not be created
+        int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outPort,
+                                          tbuilder.build(), mbuilder.build(), !revoke);
+        if (portNextObjId == -1) {
+            // Warning log will come from getPortNextObjective method
+            return null;
+        }
+
+        return DefaultForwardingObjective.builder()
+                .withSelector(sbuilder.build())
+                .nextStep(portNextObjId)
+                .fromApp(srManager.appId).makePermanent()
+                .withPriority(getPriorityFromPrefix(prefix))
+                .withFlag(ForwardingObjective.Flag.SPECIFIC);
+    }
+
+    /**
+     * Populates IP flow rules for all the given prefixes reachable from the
+     * destination switch(es).
+     *
+     * @param targetSw switch where rules are to be programmed
+     * @param subnets subnets/prefixes being added
+     * @param destSw1 destination switch where the prefixes are reachable
+     * @param destSw2 paired destination switch if one exists for the subnets/prefixes.
+     *                Should be null if there is no paired destination switch (by config)
+     *                or if the given prefixes are reachable only via destSw1
+     * @param nextHops a map containing a set of next-hops for each destination switch.
+     *                 If destSw2 is not null, then this map must contain an
+     *                 entry for destSw2 with its next-hops from the targetSw
+     *                 (although the next-hop set may be empty in certain scenarios).
+     *                 If destSw2 is null, there should not be an entry in this
+     *                 map for destSw2.
+     * @return true if all rules are set successfully, false otherwise
+     */
+    boolean populateIpRuleForSubnet(DeviceId targetSw, Set<IpPrefix> subnets,
+            DeviceId destSw1, DeviceId destSw2, Map<DeviceId, Set<DeviceId>> nextHops) {
+        for (IpPrefix subnet : subnets) {
+            if (!populateIpRuleForRouter(targetSw, subnet, destSw1, destSw2, nextHops)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Revokes IP flow rules for the subnets in each edge switch.
+     *
+     * @param subnets subnet being removed
+     * @return true if all rules are removed successfully, false otherwise
+     */
+    boolean revokeIpRuleForSubnet(Set<IpPrefix> subnets) {
+        for (IpPrefix subnet : subnets) {
+            if (!revokeIpRuleForRouter(subnet)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Populates IP flow rules for an IP prefix in the target device. The prefix
+     * is reachable via destination device(s).
+     *
+     * @param targetSw target device ID to set the rules
+     * @param ipPrefix the IP prefix
+     * @param destSw1 destination switch where the prefixes are reachable
+     * @param destSw2 paired destination switch if one exists for the subnets/prefixes.
+     *                Should be null if there is no paired destination switch (by config)
+     *                or if the given prefixes are reachable only via destSw1
+     * @param nextHops map of destination switches and their next-hops.
+     *                  Should only contain destination switches that are
+     *                  actually meant to be routed to. If destSw2 is null, there
+     *                  should not be an entry for destSw2 in this map.
+     * @return true if all rules are set successfully, false otherwise
+     */
+    private boolean populateIpRuleForRouter(DeviceId targetSw,
+                                           IpPrefix ipPrefix, DeviceId destSw1,
+                                           DeviceId destSw2,
+                                           Map<DeviceId, Set<DeviceId>> nextHops) {
+        int segmentId1, segmentId2 = -1;
+        try {
+            if (ipPrefix.isIp4()) {
+                segmentId1 = config.getIPv4SegmentId(destSw1);
+                if (destSw2 != null) {
+                    segmentId2 = config.getIPv4SegmentId(destSw2);
+                }
+            } else {
+                segmentId1 = config.getIPv6SegmentId(destSw1);
+                if (destSw2 != null) {
+                    segmentId2 = config.getIPv6SegmentId(destSw2);
+                }
+            }
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateIpRuleForRouter.");
+            return false;
+        }
+
+        TrafficSelector.Builder sbuilder = buildIpSelectorFromIpPrefix(ipPrefix);
+        TrafficSelector selector = sbuilder.build();
+
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+        DestinationSet ds;
+        TrafficTreatment treatment;
+
+        // If the next hop is the same as the final destination, then MPLS label
+        // is not set.
+        /*if (nextHops.size() == 1 && nextHops.toArray()[0].equals(destSw)) {
+            tbuilder.immediate().decNwTtl();
+            ds = new DestinationSet(false, destSw);
+            treatment = tbuilder.build();
+        } else {
+            ds = new DestinationSet(false, segmentId, destSw);
+            treatment = null;
+        }*/
+        if (destSw2 == null) {
+            // single dst - create destination set based on next-hop
+            Set<DeviceId> nhd1 = nextHops.get(destSw1);
+            if (nhd1.size() == 1 && nhd1.iterator().next().equals(destSw1)) {
+                tbuilder.immediate().decNwTtl();
+                ds = new DestinationSet(false, destSw1);
+                treatment = tbuilder.build();
+            } else {
+                ds = new DestinationSet(false, segmentId1, destSw1);
+                treatment = null;
+            }
+        } else {
+            // dst pair - IP rules for dst-pairs are always from other edge nodes
+            // the destination set needs to have both destinations, even if there
+            // are no next hops to one of them
+            ds = new DestinationSet(false, segmentId1, destSw1, segmentId2, destSw2);
+            treatment = null;
+        }
+
+        // setup metadata to pass to nextObjective - indicate the vlan on egress
+        // if needed by the switch pipeline. Since neighbor sets are always to
+        // other neighboring routers, there is no subnet assigned on those ports.
+        TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder(selector);
+        metabuilder.matchVlanId(SegmentRoutingManager.INTERNAL_VLAN);
+        DefaultGroupHandler grpHandler = srManager.getGroupHandler(targetSw);
+        if (grpHandler == null) {
+            log.warn("populateIPRuleForRouter: groupHandler for device {} "
+                    + "not found", targetSw);
+            return false;
+        }
+
+        int nextId = grpHandler.getNextObjectiveId(ds, nextHops,
+                                                   metabuilder.build(), true);
+        if (nextId <= 0) {
+            log.warn("No next objective in {} for ds: {}", targetSw, ds);
+            return false;
+        }
+
+        ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
+                .builder()
+                .fromApp(srManager.appId)
+                .makePermanent()
+                .nextStep(nextId)
+                .withSelector(selector)
+                .withPriority(getPriorityFromPrefix(ipPrefix))
+                .withFlag(ForwardingObjective.Flag.SPECIFIC);
+        if (treatment != null) {
+            fwdBuilder.withTreatment(treatment);
+        }
+        log.debug("Installing IPv4 forwarding objective for router IP/subnet {} "
+                + "in switch {} with nextId: {}", ipPrefix, targetSw, nextId);
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("IP rule for router {} populated in dev:{}",
+                                         ipPrefix, targetSw),
+                (objective, error) ->
+                        log.warn("Failed to populate IP rule for router {}: {} in dev:{}",
+                                 ipPrefix, error, targetSw));
+        srManager.flowObjectiveService.forward(targetSw, fwdBuilder.add(context));
+        rulePopulationCounter.incrementAndGet();
+
+        return true;
+    }
+
+    /**
+     * Revokes IP flow rules for the router IP address.
+     *
+     * @param ipPrefix the IP address of the destination router
+     * @return true if all rules are removed successfully, false otherwise
+     */
+    private boolean revokeIpRuleForRouter(IpPrefix ipPrefix) {
+        TrafficSelector.Builder sbuilder = buildIpSelectorFromIpPrefix(ipPrefix);
+        TrafficSelector selector = sbuilder.build();
+        TrafficTreatment dummyTreatment = DefaultTrafficTreatment.builder().build();
+
+        ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
+                .builder()
+                .fromApp(srManager.appId)
+                .makePermanent()
+                .withSelector(selector)
+                .withTreatment(dummyTreatment)
+                .withPriority(getPriorityFromPrefix(ipPrefix))
+                .withFlag(ForwardingObjective.Flag.SPECIFIC);
+
+        srManager.deviceService.getAvailableDevices().forEach(device -> {
+            if (srManager.mastershipService.isLocalMaster(device.id())) {
+                ObjectiveContext context = new DefaultObjectiveContext(
+                        (objective) -> log.debug("IP rule for router {} revoked from {}", ipPrefix, device.id()),
+                        (objective, error) -> log.warn("Failed to revoke IP rule for router {} from {}: {}",
+                                ipPrefix, device.id(), error));
+                srManager.flowObjectiveService.forward(device.id(), fwdBuilder.remove(context));
+            } else {
+                log.debug("Not the master of {}. Abort route {} removal", device.id(), ipPrefix);
+            }
+        });
+
+        return true;
+    }
+
+    /**
+     * Deals with !MPLS Bos use case.
+     *
+     * @param targetSwId the target sw
+     * @param destSwId the destination sw
+     * @param nextHops the set of next hops
+     * @param segmentId the segmentId to match
+     * @param routerIp the router ip
+     * @return a collection of fwdobjective
+     */
+    private Collection<ForwardingObjective> handleMpls(
+                                        DeviceId targetSwId,
+                                        DeviceId destSwId,
+                                        Set<DeviceId> nextHops,
+                                        int segmentId,
+                                        IpAddress routerIp,
+                                        boolean isMplsBos) {
+
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        List<ForwardingObjective.Builder> fwdObjBuilders = Lists.newArrayList();
+        // For the transport of Pwaas we can use two or three MPLS label
+        sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
+        sbuilder.matchMplsLabel(MplsLabel.mplsLabel(segmentId));
+        sbuilder.matchMplsBos(isMplsBos);
+        TrafficSelector selector = sbuilder.build();
+
+        // setup metadata to pass to nextObjective - indicate the vlan on egress
+        // if needed by the switch pipeline. Since mpls next-hops are always to
+        // other neighboring routers, there is no subnet assigned on those ports.
+        TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder(selector);
+        metabuilder.matchVlanId(SegmentRoutingManager.INTERNAL_VLAN);
+
+        if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
+            // If the next hop is the destination router for the segment, do pop
+            log.debug("populateMplsRule: Installing MPLS forwarding objective for "
+                    + "label {} in switch {} with pop to next-hops {}",
+                    segmentId, targetSwId, nextHops);
+            // Not-bos pop case (php for the current label). If MPLS-ECMP
+            // has been configured, the application we will request the
+            // installation for an MPLS-ECMP group.
+            ForwardingObjective.Builder fwdObjNoBosBuilder =
+                    getMplsForwardingObjective(targetSwId,
+                                               nextHops,
+                                               true,
+                                               isMplsBos,
+                                               metabuilder.build(),
+                                               routerIp,
+                                               destSwId);
+            // Error case, we cannot handle, exit.
+            if (fwdObjNoBosBuilder == null) {
+                return Collections.emptyList();
+            }
+            fwdObjBuilders.add(fwdObjNoBosBuilder);
+
+        } else {
+            // next hop is not destination, SR CONTINUE case (swap with self)
+            log.debug("Installing MPLS forwarding objective for "
+                    + "label {} in switch {} without pop to next-hops {}",
+                    segmentId, targetSwId, nextHops);
+            // Not-bos pop case. If MPLS-ECMP has been configured, the
+            // application we will request the installation for an MPLS-ECMP
+            // group.
+            ForwardingObjective.Builder fwdObjNoBosBuilder =
+                    getMplsForwardingObjective(targetSwId,
+                                               nextHops,
+                                               false,
+                                               isMplsBos,
+                                               metabuilder.build(),
+                                               routerIp,
+                                               destSwId);
+            // Error case, we cannot handle, exit.
+            if (fwdObjNoBosBuilder == null) {
+                return Collections.emptyList();
+            }
+            fwdObjBuilders.add(fwdObjNoBosBuilder);
+
+        }
+
+        List<ForwardingObjective> fwdObjs = Lists.newArrayList();
+        // We add the final property to the fwdObjs.
+        for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) {
+
+            ((Builder) ((Builder) fwdObjBuilder
+                    .fromApp(srManager.appId)
+                    .makePermanent())
+                    .withSelector(selector)
+                    .withPriority(SegmentRoutingService.DEFAULT_PRIORITY))
+                    .withFlag(ForwardingObjective.Flag.SPECIFIC);
+
+            ObjectiveContext context = new DefaultObjectiveContext(
+                    (objective) ->
+                            log.debug("MPLS rule {} for SID {} populated in dev:{} ",
+                                      objective.id(), segmentId, targetSwId),
+                    (objective, error) ->
+                            log.warn("Failed to populate MPLS rule {} for SID {}: {} in dev:{}",
+                                     objective.id(), segmentId, error, targetSwId));
+
+            ForwardingObjective fob = fwdObjBuilder.add(context);
+            fwdObjs.add(fob);
+
+        }
+
+        return fwdObjs;
+    }
+
+    /**
+     * Populates MPLS flow rules in the target device to point towards the
+     * destination device.
+     *
+     * @param targetSwId target device ID of the switch to set the rules
+     * @param destSwId destination switch device ID
+     * @param nextHops next hops switch ID list
+     * @param routerIp the router ip
+     * @return true if all rules are set successfully, false otherwise
+     */
+    boolean populateMplsRule(DeviceId targetSwId, DeviceId destSwId,
+                                    Set<DeviceId> nextHops,
+                                    IpAddress routerIp) {
+
+        int segmentId;
+        try {
+            if (routerIp.isIp4()) {
+                segmentId = config.getIPv4SegmentId(destSwId);
+            } else {
+                segmentId = config.getIPv6SegmentId(destSwId);
+            }
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateMplsRule.");
+            return false;
+        }
+
+        List<ForwardingObjective> fwdObjs = new ArrayList<>();
+        Collection<ForwardingObjective> fwdObjsMpls;
+        // Generates the transit rules used by the standard "routing".
+        fwdObjsMpls = handleMpls(targetSwId, destSwId, nextHops, segmentId, routerIp, true);
+        if (fwdObjsMpls.isEmpty()) {
+            return false;
+        }
+        fwdObjs.addAll(fwdObjsMpls);
+
+        // Generates the transit rules used by the MPLS Pwaas.
+        int pwSrLabel;
+        try {
+            pwSrLabel = config.getPWRoutingLabel(destSwId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateMplsRule. No label for PseudoWire traffic.");
+            return false;
+        }
+        fwdObjsMpls = handleMpls(targetSwId, destSwId, nextHops, pwSrLabel, routerIp, false);
+        if (fwdObjsMpls.isEmpty()) {
+            return false;
+        }
+        fwdObjs.addAll(fwdObjsMpls);
+
+        for (ForwardingObjective fwdObj : fwdObjs) {
+            log.debug("Sending MPLS fwd obj {} for SID {}-> next {} in sw: {}",
+                      fwdObj.id(), segmentId, fwdObj.nextId(), targetSwId);
+            srManager.flowObjectiveService.forward(targetSwId, fwdObj);
+            rulePopulationCounter.incrementAndGet();
+        }
+
+        return true;
+    }
+
+    private ForwardingObjective.Builder getMplsForwardingObjective(
+                                             DeviceId targetSw,
+                                             Set<DeviceId> nextHops,
+                                             boolean phpRequired,
+                                             boolean isBos,
+                                             TrafficSelector meta,
+                                             IpAddress routerIp,
+                                             DeviceId destSw) {
+
+        ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
+                .builder().withFlag(ForwardingObjective.Flag.SPECIFIC);
+
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        if (phpRequired) {
+            // php case - pop should always be flow-action
+            log.debug("getMplsForwardingObjective: php required");
+            tbuilder.deferred().copyTtlIn();
+            if (isBos) {
+                if (routerIp.isIp4()) {
+                    tbuilder.deferred().popMpls(EthType.EtherType.IPV4.ethType());
+                } else {
+                    tbuilder.deferred().popMpls(EthType.EtherType.IPV6.ethType());
+                }
+                tbuilder.decNwTtl();
+            } else {
+                tbuilder.deferred().popMpls(EthType.EtherType.MPLS_UNICAST.ethType())
+                    .decMplsTtl();
+            }
+        } else {
+            // swap with self case - SR CONTINUE
+            log.debug("getMplsForwardingObjective: php not required");
+            tbuilder.deferred().decMplsTtl();
+        }
+
+        fwdBuilder.withTreatment(tbuilder.build());
+        // if MPLS-ECMP == True we will build a standard NeighborSet.
+        // Otherwise a RandomNeighborSet.
+        DestinationSet ns = DestinationSet.destinationSet(false, false, destSw);
+        if (!isBos && this.srManager.getMplsEcmp()) {
+            ns = DestinationSet.destinationSet(false, true, destSw);
+        } else if (!isBos && !this.srManager.getMplsEcmp()) {
+            ns = DestinationSet.destinationSet(true, true, destSw);
+        }
+
+        log.debug("Trying to get a nextObjId for mpls rule on device:{} to ns:{}",
+                  targetSw, ns);
+        DefaultGroupHandler gh = srManager.getGroupHandler(targetSw);
+        if (gh == null) {
+            log.warn("getNextObjectiveId query - groupHandler for device {} "
+                    + "not found", targetSw);
+            return null;
+        }
+        // If BoS == True, all forwarding is via L3 ECMP group.
+        // If Bos == False, the forwarding can be via MPLS-ECMP group or through
+        // MPLS-Interface group. This depends on the configuration of the option
+        // MPLS-ECMP.
+        // The metadata informs the driver that the next-Objective will be used
+        // by MPLS flows and if Bos == False the driver will use MPLS groups.
+        Map<DeviceId, Set<DeviceId>> dstNextHops = new HashMap<>();
+        dstNextHops.put(destSw, nextHops);
+        int nextId = gh.getNextObjectiveId(ns, dstNextHops, meta, isBos);
+        if (nextId <= 0) {
+            log.warn("No next objective in {} for ns: {}", targetSw, ns);
+            return null;
+        } else {
+            log.debug("nextObjId found:{} for mpls rule on device:{} to ns:{}",
+                      nextId, targetSw, ns);
+        }
+
+        fwdBuilder.nextStep(nextId);
+        return fwdBuilder;
+    }
+
+    /**
+     * Creates a filtering objective to permit all untagged packets with a
+     * dstMac corresponding to the router's MAC address. For those pipelines
+     * that need to internally assign vlans to untagged packets, this method
+     * provides per-subnet vlan-ids as metadata.
+     * <p>
+     * Note that the vlan assignment and filter programming should only be done by
+     * the master for a switch. This method is typically called at deviceAdd and
+     * programs filters only for the enabled ports of the device. For port-updates,
+     * that enable/disable ports after device add, singlePortFilter methods should
+     * be called.
+     *
+     * @param deviceId  the switch dpid for the router
+     * @return PortFilterInfo information about the processed ports
+     */
+    PortFilterInfo populateVlanMacFilters(DeviceId deviceId) {
+        log.debug("Installing per-port filtering objective for untagged "
+                + "packets in device {}", deviceId);
+
+        List<Port> devPorts = srManager.deviceService.getPorts(deviceId);
+        if (devPorts == null || devPorts.isEmpty()) {
+            log.warn("Device {} ports not available. Unable to add MacVlan filters",
+                     deviceId);
+            return null;
+        }
+        int disabledPorts = 0, errorPorts = 0, filteredPorts = 0;
+        for (Port port : devPorts) {
+            if (!port.isEnabled()) {
+                disabledPorts++;
+                continue;
+            }
+            if (processSinglePortFilters(deviceId, port.number(), true)) {
+                filteredPorts++;
+            } else {
+                errorPorts++;
+            }
+        }
+        log.debug("Filtering on dev:{}, disabledPorts:{}, errorPorts:{}, filteredPorts:{}",
+                  deviceId, disabledPorts, errorPorts, filteredPorts);
+        return srManager.defaultRoutingHandler.new PortFilterInfo(disabledPorts,
+                                                       errorPorts, filteredPorts);
+    }
+
+    /**
+     * Creates or removes filtering objectives for a single port. Should only be
+     * called by the master for a switch.
+     *
+     * @param deviceId device identifier
+     * @param portnum  port identifier for port to be filtered
+     * @param install true to install the filtering objective, false to remove
+     * @return true if no errors occurred during the build of the filtering objective
+     */
+    boolean processSinglePortFilters(DeviceId deviceId, PortNumber portnum, boolean install) {
+        ConnectPoint connectPoint = new ConnectPoint(deviceId, portnum);
+        VlanId untaggedVlan = srManager.getUntaggedVlanId(connectPoint);
+        Set<VlanId> taggedVlans = srManager.getTaggedVlanId(connectPoint);
+        VlanId nativeVlan = srManager.getNativeVlanId(connectPoint);
+
+        if (taggedVlans.size() != 0) {
+            // Filter for tagged vlans
+            if (!srManager.getTaggedVlanId(connectPoint).stream().allMatch(taggedVlanId ->
+                    processSinglePortFiltersInternal(deviceId, portnum, false, taggedVlanId, install))) {
+                return false;
+            }
+            if (nativeVlan != null) {
+                // Filter for native vlan
+                if (!processSinglePortFiltersInternal(deviceId, portnum, true, nativeVlan, install)) {
+                    return false;
+                }
+            }
+        } else if (untaggedVlan != null) {
+            // Filter for untagged vlan
+            if (!processSinglePortFiltersInternal(deviceId, portnum, true, untaggedVlan, install)) {
+                return false;
+            }
+        } else {
+            // Unconfigured port, use INTERNAL_VLAN
+            if (!processSinglePortFiltersInternal(deviceId, portnum, true, INTERNAL_VLAN, install)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Updates filtering objectives for a single port. Should only be called by
+     * the master for a switch
+     * @param deviceId device identifier
+     * @param portNum  port identifier for port to be filtered
+     * @param pushVlan true to push vlan, false otherwise
+     * @param vlanId vlan identifier
+     * @param install true to install the filtering objective, false to remove
+     */
+    void updateSinglePortFilters(DeviceId deviceId, PortNumber portNum,
+                                 boolean pushVlan, VlanId vlanId, boolean install) {
+        if (!processSinglePortFiltersInternal(deviceId, portNum, pushVlan, vlanId, install)) {
+            log.warn("Failed to update FilteringObjective for {}/{} with vlan {}",
+                     deviceId, portNum, vlanId);
+        }
+    }
+
+    private boolean processSinglePortFiltersInternal(DeviceId deviceId, PortNumber portnum,
+                                                      boolean pushVlan, VlanId vlanId, boolean install) {
+        FilteringObjective.Builder fob = buildFilteringObjective(deviceId, portnum, pushVlan, vlanId);
+        if (fob == null) {
+            // error encountered during build
+            return false;
+        }
+        log.debug("{} filtering objectives for dev/port: {}/{}",
+                 install ? "Installing" : "Removing", deviceId, portnum);
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("Filter for {}/{} {}", deviceId, portnum,
+                        install ? "installed" : "removed"),
+                (objective, error) -> log.warn("Failed to {} filter for {}/{}: {}",
+                        install ? "install" : "remove", deviceId, portnum, error));
+        if (install) {
+            srManager.flowObjectiveService.filter(deviceId, fob.add(context));
+        } else {
+            srManager.flowObjectiveService.filter(deviceId, fob.remove(context));
+        }
+        return true;
+    }
+
+    private FilteringObjective.Builder buildFilteringObjective(DeviceId deviceId, PortNumber portnum,
+                                                               boolean pushVlan, VlanId vlanId) {
+        MacAddress deviceMac;
+        try {
+            deviceMac = config.getDeviceMac(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Processing SinglePortFilters aborted");
+            return null;
+        }
+        FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
+        fob.withKey(Criteria.matchInPort(portnum))
+            .addCondition(Criteria.matchEthDst(deviceMac))
+            .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+        if (pushVlan) {
+            fob.addCondition(Criteria.matchVlanId(VlanId.NONE));
+            tBuilder.pushVlan().setVlanId(vlanId);
+        } else {
+            fob.addCondition(Criteria.matchVlanId(vlanId));
+        }
+
+        // NOTE: Some switch hardware share the same filtering flow among different ports.
+        //       We use this metadata to let the driver know that there is no more enabled port
+        //       within the same VLAN on this device.
+        boolean noMoreEnabledPort = srManager.interfaceService.getInterfaces().stream()
+                .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
+                .filter(intf -> intf.vlanTagged().contains(vlanId) ||
+                        intf.vlanUntagged().equals(vlanId) ||
+                        intf.vlanNative().equals(vlanId))
+                .noneMatch(intf -> {
+                    Port port = srManager.deviceService.getPort(intf.connectPoint());
+                    return port != null && port.isEnabled();
+                });
+        if (noMoreEnabledPort) {
+            tBuilder.wipeDeferred();
+        }
+
+        fob.withMeta(tBuilder.build());
+
+        fob.permit().fromApp(srManager.appId);
+        return fob;
+    }
+
+    /**
+     * Creates a forwarding objective to punt all IP packets, destined to the
+     * router's port IP addresses, to the controller. Note that the input
+     * port should not be matched on, as these packets can come from any input.
+     * Furthermore, these are applied only by the master instance.
+     *
+     * @param deviceId the switch dpid for the router
+     */
+    void populateIpPunts(DeviceId deviceId) {
+        Ip4Address routerIpv4, pairRouterIpv4 = null;
+        Ip6Address routerIpv6, routerLinkLocalIpv6, pairRouterIpv6 = null;
+        try {
+            routerIpv4 = config.getRouterIpv4(deviceId);
+            routerIpv6 = config.getRouterIpv6(deviceId);
+            routerLinkLocalIpv6 = Ip6Address.valueOf(
+                    IPv6.getLinkLocalAddress(config.getDeviceMac(deviceId).toBytes()));
+
+            if (config.isPairedEdge(deviceId)) {
+                pairRouterIpv4 = config.getRouterIpv4(config.getPairDeviceId(deviceId));
+                pairRouterIpv6 = config.getRouterIpv6(config.getPairDeviceId(deviceId));
+            }
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateIpPunts.");
+            return;
+        }
+
+        if (!srManager.mastershipService.isLocalMaster(deviceId)) {
+            log.debug("Not installing port-IP punts - not the master for dev:{} ",
+                      deviceId);
+            return;
+        }
+        Set<IpAddress> allIps = new HashSet<>(config.getPortIPs(deviceId));
+        allIps.add(routerIpv4);
+        allIps.add(routerLinkLocalIpv6);
+        if (routerIpv6 != null) {
+            allIps.add(routerIpv6);
+        }
+        if (pairRouterIpv4 != null) {
+            allIps.add(pairRouterIpv4);
+        }
+        if (pairRouterIpv6 != null) {
+            allIps.add(pairRouterIpv6);
+        }
+        for (IpAddress ipaddr : allIps) {
+            populateSingleIpPunts(deviceId, ipaddr);
+        }
+    }
+
+    /**
+     * Creates a forwarding objective to punt all IP packets, destined to the
+     * specified IP address, which should be router's port IP address.
+     *
+     * @param deviceId the switch dpid for the router
+     * @param ipAddress the IP address of the router's port
+     */
+    void populateSingleIpPunts(DeviceId deviceId, IpAddress ipAddress) {
+        TrafficSelector.Builder sbuilder = buildIpSelectorFromIpAddress(ipAddress);
+        Optional<DeviceId> optDeviceId = Optional.of(deviceId);
+
+        srManager.packetService.requestPackets(sbuilder.build(),
+                                               PacketPriority.CONTROL, srManager.appId, optDeviceId);
+    }
+
+    /**
+     * Removes a forwarding objective to punt all IP packets, destined to the
+     * specified IP address, which should be router's port IP address.
+     *
+     * @param deviceId the switch dpid for the router
+     * @param ipAddress the IP address of the router's port
+     */
+    void revokeSingleIpPunts(DeviceId deviceId, IpAddress ipAddress) {
+        TrafficSelector.Builder sbuilder = buildIpSelectorFromIpAddress(ipAddress);
+        Optional<DeviceId> optDeviceId = Optional.of(deviceId);
+
+        try {
+            if (!ipAddress.equals(config.getRouterIpv4(deviceId)) &&
+                    !ipAddress.equals(config.getRouterIpv6(deviceId))) {
+                srManager.packetService.cancelPackets(sbuilder.build(),
+                                                      PacketPriority.CONTROL, srManager.appId, optDeviceId);
+            }
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting revokeSingleIpPunts");
+        }
+    }
+
+    /**
+     * Method to build IPv4 or IPv6 selector.
+     *
+     * @param addressToMatch the address to match
+     */
+    private TrafficSelector.Builder buildIpSelectorFromIpAddress(IpAddress addressToMatch) {
+        return buildIpSelectorFromIpPrefix(addressToMatch.toIpPrefix());
+    }
+
+    /**
+     * Method to build IPv4 or IPv6 selector.
+     *
+     * @param prefixToMatch the prefix to match
+     */
+    private TrafficSelector.Builder buildIpSelectorFromIpPrefix(IpPrefix prefixToMatch) {
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+        // If the prefix is IPv4
+        if (prefixToMatch.isIp4()) {
+            selectorBuilder.matchEthType(Ethernet.TYPE_IPV4);
+            selectorBuilder.matchIPDst(prefixToMatch.getIp4Prefix());
+            return selectorBuilder;
+        }
+        // If the prefix is IPv6
+        selectorBuilder.matchEthType(Ethernet.TYPE_IPV6);
+        selectorBuilder.matchIPv6Dst(prefixToMatch.getIp6Prefix());
+        return selectorBuilder;
+    }
+
+    /**
+     * Creates forwarding objectives to punt ARP and NDP packets, to the controller.
+     * Furthermore, these are applied only by the master instance. Deferred actions
+     * are not cleared such that packets can be flooded in the cross connect use case
+     *
+     * @param deviceId the switch dpid for the router
+     */
+    void populateArpNdpPunts(DeviceId deviceId) {
+        // We are not the master just skip.
+        if (!srManager.mastershipService.isLocalMaster(deviceId)) {
+            log.debug("Not installing ARP/NDP punts - not the master for dev:{} ",
+                      deviceId);
+            return;
+        }
+
+        ForwardingObjective fwdObj;
+        // We punt all ARP packets towards the controller.
+        fwdObj = arpFwdObjective(null, true, ARP_NDP_PRIORITY)
+                .add(new ObjectiveContext() {
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.warn("Failed to install forwarding objective to punt ARP to {}: {}",
+                                 deviceId, error);
+                    }
+                });
+        srManager.flowObjectiveService.forward(deviceId, fwdObj);
+
+        // We punt all NDP packets towards the controller.
+        ndpFwdObjective(null, true, ARP_NDP_PRIORITY).forEach(builder -> {
+             ForwardingObjective obj = builder.add(new ObjectiveContext() {
+                @Override
+                public void onError(Objective objective, ObjectiveError error) {
+                    log.warn("Failed to install forwarding objective to punt NDP to {}: {}",
+                            deviceId, error);
+                }
+            });
+            srManager.flowObjectiveService.forward(deviceId, obj);
+        });
+
+        srManager.getPairLocalPorts(deviceId).ifPresent(port -> {
+            ForwardingObjective pairFwdObj;
+            // Do not punt ARP packets from pair port
+            pairFwdObj = arpFwdObjective(port, false, PacketPriority.CONTROL.priorityValue() + 1)
+                    .add(new ObjectiveContext() {
+                        @Override
+                        public void onError(Objective objective, ObjectiveError error) {
+                            log.warn("Failed to install forwarding objective to ignore ARP to {}: {}",
+                                    deviceId, error);
+                        }
+                    });
+            srManager.flowObjectiveService.forward(deviceId, pairFwdObj);
+
+            // Do not punt NDP packets from pair port
+            ndpFwdObjective(port, false, PacketPriority.CONTROL.priorityValue() + 1).forEach(builder -> {
+                ForwardingObjective obj = builder.add(new ObjectiveContext() {
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.warn("Failed to install forwarding objective to ignore ARP to {}: {}",
+                                deviceId, error);
+                    }
+                });
+                srManager.flowObjectiveService.forward(deviceId, obj);
+            });
+
+            // Do not forward DAD packets from pair port
+            pairFwdObj = dad6FwdObjective(port, PacketPriority.CONTROL.priorityValue() + 2)
+                    .add(new ObjectiveContext() {
+                        @Override
+                        public void onError(Objective objective, ObjectiveError error) {
+                            log.warn("Failed to install forwarding objective to drop DAD to {}: {}",
+                                    deviceId, error);
+                        }
+                    });
+            srManager.flowObjectiveService.forward(deviceId, pairFwdObj);
+        });
+    }
+
+    private ForwardingObjective.Builder fwdObjBuilder(TrafficSelector selector,
+                                                      TrafficTreatment treatment, int priority) {
+        return DefaultForwardingObjective.builder()
+                .withPriority(priority)
+                .withSelector(selector)
+                .fromApp(srManager.appId)
+                .withFlag(ForwardingObjective.Flag.VERSATILE)
+                .withTreatment(treatment)
+                .makePermanent();
+    }
+
+    private ForwardingObjective.Builder arpFwdObjective(PortNumber port, boolean punt, int priority) {
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        sBuilder.matchEthType(TYPE_ARP);
+        if (port != null) {
+            sBuilder.matchInPort(port);
+        }
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        if (punt) {
+            tBuilder.punt();
+        }
+        return fwdObjBuilder(sBuilder.build(), tBuilder.build(), priority);
+    }
+
+    private Set<ForwardingObjective.Builder> ndpFwdObjective(PortNumber port, boolean punt, int priority) {
+        Set<ForwardingObjective.Builder> result = Sets.newHashSet();
+
+        Lists.newArrayList(NEIGHBOR_SOLICITATION, NEIGHBOR_ADVERTISEMENT, ROUTER_SOLICITATION, ROUTER_ADVERTISEMENT)
+                .forEach(type -> {
+                    TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+                    sBuilder.matchEthType(TYPE_IPV6)
+                            .matchIPProtocol(PROTOCOL_ICMP6)
+                            .matchIcmpv6Type(type);
+                    if (port != null) {
+                        sBuilder.matchInPort(port);
+                    }
+
+                    TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+                    if (punt) {
+                        tBuilder.punt();
+                    }
+
+                    result.add(fwdObjBuilder(sBuilder.build(), tBuilder.build(), priority));
+                });
+
+        return result;
+    }
+
+    private ForwardingObjective.Builder dad6FwdObjective(PortNumber port, int priority) {
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        sBuilder.matchEthType(TYPE_IPV6)
+                .matchIPv6Src(Ip6Address.ZERO.toIpPrefix());
+                // TODO CORD-1672 Fix this when OFDPA can distinguish ::/0 and ::/128 correctly
+                // .matchIPProtocol(PROTOCOL_ICMP6)
+                // .matchIcmpv6Type(NEIGHBOR_SOLICITATION);
+        if (port != null) {
+            sBuilder.matchInPort(port);
+        }
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        tBuilder.wipeDeferred();
+        return fwdObjBuilder(sBuilder.build(), tBuilder.build(), priority);
+    }
+
+    /**
+     * Populates a forwarding objective to send packets that miss other high
+     * priority Bridging Table entries to a group that contains all ports of
+     * its subnet.
+     *
+     * @param deviceId switch ID to set the rules
+     */
+    void populateSubnetBroadcastRule(DeviceId deviceId) {
+        srManager.getVlanPortMap(deviceId).asMap().forEach((vlanId, ports) -> {
+            updateSubnetBroadcastRule(deviceId, vlanId, true);
+        });
+    }
+
+    /**
+     * Creates or removes a forwarding objective to broadcast packets to its subnet.
+     * @param deviceId switch ID to set the rule
+     * @param vlanId vlan ID to specify the subnet
+     * @param install true to install the rule, false to revoke the rule
+     */
+    void updateSubnetBroadcastRule(DeviceId deviceId, VlanId vlanId, boolean install) {
+        int nextId = srManager.getVlanNextObjectiveId(deviceId, vlanId);
+
+        if (nextId < 0) {
+            log.error("Cannot install vlan {} broadcast rule in dev:{} due"
+                              + " to vlanId:{} or nextId:{}", vlanId, deviceId, vlanId, nextId);
+            return;
+        }
+
+        // Driver should treat objective with MacAddress.NONE as the
+        // subnet broadcast rule
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        sbuilder.matchVlanId(vlanId);
+        sbuilder.matchEthDst(MacAddress.NONE);
+
+        ForwardingObjective.Builder fob = DefaultForwardingObjective.builder();
+        fob.withFlag(Flag.SPECIFIC)
+                .withSelector(sbuilder.build())
+                .nextStep(nextId)
+                .withPriority(SegmentRoutingService.FLOOD_PRIORITY)
+                .fromApp(srManager.appId)
+                .makePermanent();
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("Vlan broadcast rule for {} populated", vlanId),
+                (objective, error) ->
+                        log.warn("Failed to populate vlan broadcast rule for {}: {}", vlanId, error));
+
+        if (install) {
+            srManager.flowObjectiveService.forward(deviceId, fob.add(context));
+        } else {
+            srManager.flowObjectiveService.forward(deviceId, fob.remove(context));
+        }
+    }
+
+    private int getPriorityFromPrefix(IpPrefix prefix) {
+        return (prefix.isIp4()) ?
+                2000 * prefix.prefixLength() + SegmentRoutingService.MIN_IP_PRIORITY :
+                500 * prefix.prefixLength() + SegmentRoutingService.MIN_IP_PRIORITY;
+    }
+
+    /**
+     * Update Forwarding objective for each host and IP address connected to given port.
+     * And create corresponding Simple Next objective if it does not exist.
+     * Applied only when populating Forwarding objective
+     * @param deviceId switch ID to set the rule
+     * @param portNumber port number
+     * @param prefix IP prefix of the route
+     * @param hostMac MAC address of the next hop
+     * @param vlanId Vlan ID of the port
+     * @param popVlan true to pop vlan tag in TrafficTreatment
+     * @param install true to populate the forwarding objective, false to revoke
+     */
+    void updateFwdObj(DeviceId deviceId, PortNumber portNumber, IpPrefix prefix, MacAddress hostMac,
+                      VlanId vlanId, boolean popVlan, boolean install) {
+        ForwardingObjective.Builder fob;
+        TrafficSelector.Builder sbuilder = buildIpSelectorFromIpPrefix(prefix);
+        MacAddress deviceMac;
+        try {
+            deviceMac = config.getDeviceMac(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting updateFwdObj.");
+            return;
+        }
+
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+        tbuilder.deferred()
+                .setEthDst(hostMac)
+                .setEthSrc(deviceMac)
+                .setOutput(portNumber);
+
+        TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
+
+        if (!popVlan) {
+            tbuilder.setVlanId(vlanId);
+        } else {
+            mbuilder.matchVlanId(vlanId);
+        }
+
+        // if the objective is to revoke an existing rule, and for some reason
+        // the next-objective does not exist, then a new one should not be created
+        int portNextObjId = srManager.getPortNextObjectiveId(deviceId, portNumber,
+                                                             tbuilder.build(), mbuilder.build(), install);
+        if (portNextObjId == -1) {
+            // Warning log will come from getPortNextObjective method
+            return;
+        }
+
+        fob = DefaultForwardingObjective.builder().withSelector(sbuilder.build())
+                .nextStep(portNextObjId).fromApp(srManager.appId).makePermanent()
+                .withPriority(getPriorityFromPrefix(prefix)).withFlag(ForwardingObjective.Flag.SPECIFIC);
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("IP rule for route {} {}", prefix, install ? "installed" : "revoked"),
+                (objective, error) ->
+                        log.warn("Failed to {} IP rule for route {}: {}",
+                                 install ? "install" : "revoke", prefix, error));
+        srManager.flowObjectiveService.forward(deviceId, install ? fob.add(context) : fob.remove(context));
+
+        if (!install) {
+            DefaultGroupHandler grpHandler = srManager.getGroupHandler(deviceId);
+            if (grpHandler == null) {
+                log.warn("updateFwdObj: groupHandler for device {} not found", deviceId);
+            } else {
+                // Remove L3UG for the given port and host
+                grpHandler.removeGroupFromPort(portNumber, tbuilder.build(), mbuilder.build());
+            }
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
new file mode 100644
index 0000000..d951b53
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -0,0 +1,1727 @@
+/*
+ * Copyright 2015-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;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.VlanId;
+import org.onlab.util.KryoNamespace;
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.Event;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.ConfigException;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.basics.InterfaceConfig;
+import org.onosproject.net.config.basics.McastConfig;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.net.device.DeviceAdminService;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostLocationProbingService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceService;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.mcast.McastEvent;
+import org.onosproject.net.mcast.McastListener;
+import org.onosproject.net.mcast.MulticastRouteService;
+import org.onosproject.net.neighbour.NeighbourResolutionService;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.routeservice.ResolvedRoute;
+import org.onosproject.routeservice.RouteEvent;
+import org.onosproject.routeservice.RouteListener;
+import org.onosproject.routeservice.RouteService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.onosproject.segmentrouting.config.PwaasConfig;
+import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
+import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
+import org.onosproject.segmentrouting.config.XConnectConfig;
+import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
+import org.onosproject.segmentrouting.grouphandler.DestinationSet;
+import org.onosproject.segmentrouting.grouphandler.NextNeighbors;
+import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelHandler;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.L2Tunnel;
+import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
+import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
+import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;
+import org.onosproject.segmentrouting.storekey.McastStoreKey;
+import org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey;
+import org.onosproject.segmentrouting.storekey.VlanNextObjectiveStoreKey;
+import org.onosproject.segmentrouting.storekey.XConnectStoreKey;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.EventuallyConsistentMapBuilder;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkState;
+import static org.onlab.packet.Ethernet.TYPE_ARP;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_REGISTERED;
+import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UNREGISTERED;
+
+/**
+ * Segment routing manager.
+ */
+@Service
+@Component(immediate = true)
+public class SegmentRoutingManager implements SegmentRoutingService {
+
+    private static Logger log = LoggerFactory.getLogger(SegmentRoutingManager.class);
+    private static final String NOT_MASTER = "Current instance is not the master of {}. Ignore.";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private ComponentConfigService compCfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private NeighbourResolutionService neighbourResolutionService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    HostLocationProbingService probingService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    DeviceAdminService deviceAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    MulticastRouteService multicastRouteService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public TopologyService topologyService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    RouteService routeService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public NetworkConfigRegistry cfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public LeadershipService leadershipService;
+
+    @Property(name = "activeProbing", boolValue = true,
+            label = "Enable active probing to discover dual-homed hosts.")
+    boolean activeProbing = true;
+
+    ArpHandler arpHandler = null;
+    IcmpHandler icmpHandler = null;
+    IpHandler ipHandler = null;
+    RoutingRulePopulator routingRulePopulator = null;
+    ApplicationId appId;
+    DeviceConfiguration deviceConfiguration = null;
+
+    DefaultRoutingHandler defaultRoutingHandler = null;
+    private TunnelHandler tunnelHandler = null;
+    private PolicyHandler policyHandler = null;
+    private InternalPacketProcessor processor = null;
+    private InternalLinkListener linkListener = null;
+    private InternalDeviceListener deviceListener = null;
+    private AppConfigHandler appCfgHandler = null;
+    XConnectHandler xConnectHandler = null;
+    McastHandler mcastHandler = null;
+    HostHandler hostHandler = null;
+    private RouteHandler routeHandler = null;
+    LinkHandler linkHandler = null;
+    private SegmentRoutingNeighbourDispatcher neighbourHandler = null;
+    private L2TunnelHandler l2TunnelHandler = null;
+    private InternalEventHandler eventHandler = new InternalEventHandler();
+    private final InternalHostListener hostListener = new InternalHostListener();
+    private final InternalConfigListener cfgListener = new InternalConfigListener(this);
+    private final InternalMcastListener mcastListener = new InternalMcastListener();
+    private final InternalRouteEventListener routeListener = new InternalRouteEventListener();
+
+    private ScheduledExecutorService executorService = Executors
+            .newScheduledThreadPool(1, groupedThreads("SegmentRoutingManager", "event-%d", log));
+
+    @SuppressWarnings("unused")
+    private static ScheduledFuture<?> eventHandlerFuture = null;
+    @SuppressWarnings("rawtypes")
+    private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<>();
+    Map<DeviceId, DefaultGroupHandler> groupHandlerMap =
+            new ConcurrentHashMap<>();
+    /**
+     * Per device next objective ID store with (device id + destination set) as key.
+     * Used to keep track on MPLS group information.
+     */
+    private EventuallyConsistentMap<DestinationSetNextObjectiveStoreKey, NextNeighbors>
+            dsNextObjStore = null;
+    /**
+     * Per device next objective ID store with (device id + vlanid) as key.
+     * Used to keep track on L2 flood group information.
+     */
+    private EventuallyConsistentMap<VlanNextObjectiveStoreKey, Integer>
+            vlanNextObjStore = null;
+    /**
+     * Per device next objective ID store with (device id + port + treatment + meta) as key.
+     * Used to keep track on L2 interface group and L3 unicast group information.
+     */
+    private EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer>
+            portNextObjStore = null;
+
+    private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
+    private EventuallyConsistentMap<String, Policy> policyStore = null;
+
+    private AtomicBoolean programmingScheduled = new AtomicBoolean();
+
+    private final ConfigFactory<DeviceId, SegmentRoutingDeviceConfig> deviceConfigFactory =
+            new ConfigFactory<DeviceId, SegmentRoutingDeviceConfig>(
+                    SubjectFactories.DEVICE_SUBJECT_FACTORY,
+                    SegmentRoutingDeviceConfig.class, "segmentrouting") {
+                @Override
+                public SegmentRoutingDeviceConfig createConfig() {
+                    return new SegmentRoutingDeviceConfig();
+                }
+            };
+
+    private final ConfigFactory<ApplicationId, SegmentRoutingAppConfig> appConfigFactory =
+            new ConfigFactory<ApplicationId, SegmentRoutingAppConfig>(
+                    SubjectFactories.APP_SUBJECT_FACTORY,
+                    SegmentRoutingAppConfig.class, "segmentrouting") {
+                @Override
+                public SegmentRoutingAppConfig createConfig() {
+                    return new SegmentRoutingAppConfig();
+                }
+            };
+
+    private final ConfigFactory<ApplicationId, XConnectConfig> xConnectConfigFactory =
+            new ConfigFactory<ApplicationId, XConnectConfig>(
+                    SubjectFactories.APP_SUBJECT_FACTORY,
+                    XConnectConfig.class, "xconnect") {
+                @Override
+                public XConnectConfig createConfig() {
+                    return new XConnectConfig();
+                }
+            };
+
+    private ConfigFactory<ApplicationId, McastConfig> mcastConfigFactory =
+            new ConfigFactory<ApplicationId, McastConfig>(
+                    SubjectFactories.APP_SUBJECT_FACTORY,
+                    McastConfig.class, "multicast") {
+                @Override
+                public McastConfig createConfig() {
+                    return new McastConfig();
+                }
+            };
+
+    private final ConfigFactory<ApplicationId, PwaasConfig> pwaasConfigFactory =
+            new ConfigFactory<ApplicationId, PwaasConfig>(
+                    SubjectFactories.APP_SUBJECT_FACTORY,
+                    PwaasConfig.class, "pwaas") {
+                @Override
+                public PwaasConfig createConfig() {
+                    return new PwaasConfig();
+                }
+            };
+
+    private static final Object THREAD_SCHED_LOCK = new Object();
+    private static int numOfEventsQueued = 0;
+    private static int numOfEventsExecuted = 0;
+    private static int numOfHandlerExecution = 0;
+    private static int numOfHandlerScheduled = 0;
+
+    /**
+     * Segment Routing App ID.
+     */
+    public static final String APP_NAME = "org.onosproject.segmentrouting";
+
+    /**
+     * The default VLAN ID assigned to the interfaces without subnet config.
+     */
+    public static final VlanId INTERNAL_VLAN = VlanId.vlanId((short) 4094);
+
+    @Activate
+    protected void activate(ComponentContext context) {
+        appId = coreService.registerApplication(APP_NAME);
+
+        log.debug("Creating EC map nsnextobjectivestore");
+        EventuallyConsistentMapBuilder<DestinationSetNextObjectiveStoreKey, NextNeighbors>
+                nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
+        dsNextObjStore = nsNextObjMapBuilder
+                .withName("nsnextobjectivestore")
+                .withSerializer(createSerializer())
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        log.trace("Current size {}", dsNextObjStore.size());
+
+        log.debug("Creating EC map vlannextobjectivestore");
+        EventuallyConsistentMapBuilder<VlanNextObjectiveStoreKey, Integer>
+                vlanNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
+        vlanNextObjStore = vlanNextObjMapBuilder
+                .withName("vlannextobjectivestore")
+                .withSerializer(createSerializer())
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+
+        log.debug("Creating EC map subnetnextobjectivestore");
+        EventuallyConsistentMapBuilder<PortNextObjectiveStoreKey, Integer>
+                portNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
+        portNextObjStore = portNextObjMapBuilder
+                .withName("portnextobjectivestore")
+                .withSerializer(createSerializer())
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+
+        EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
+                storageService.eventuallyConsistentMapBuilder();
+        tunnelStore = tunnelMapBuilder
+                .withName("tunnelstore")
+                .withSerializer(createSerializer())
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+
+        EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder =
+                storageService.eventuallyConsistentMapBuilder();
+        policyStore = policyMapBuilder
+                .withName("policystore")
+                .withSerializer(createSerializer())
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+
+        compCfgService.preSetProperty("org.onosproject.net.group.impl.GroupManager",
+                                      "purgeOnDisconnection", "true");
+        compCfgService.preSetProperty("org.onosproject.net.flow.impl.FlowRuleManager",
+                                      "purgeOnDisconnection", "true");
+        compCfgService.preSetProperty("org.onosproject.provider.host.impl.HostLocationProvider",
+                                      "requestInterceptsEnabled", "false");
+        compCfgService.preSetProperty("org.onosproject.net.neighbour.impl.NeighbourResolutionManager",
+                                      "requestInterceptsEnabled", "false");
+        compCfgService.preSetProperty("org.onosproject.dhcprelay.DhcpRelayManager",
+                                      "arpEnabled", "false");
+        compCfgService.preSetProperty("org.onosproject.net.host.impl.HostManager",
+                                      "greedyLearningIpv6", "true");
+        compCfgService.preSetProperty("org.onosproject.routing.cpr.ControlPlaneRedirectManager",
+                                      "forceUnprovision", "true");
+        compCfgService.preSetProperty("org.onosproject.routeservice.store.RouteStoreImpl",
+                                      "distributed", "true");
+        compCfgService.preSetProperty("org.onosproject.provider.host.impl.HostLocationProvider",
+                                      "multihomingEnabled", "true");
+        compCfgService.preSetProperty("org.onosproject.provider.lldp.impl.LldpLinkProvider",
+                                      "staleLinkAge", "15000");
+        compCfgService.preSetProperty("org.onosproject.net.host.impl.HostManager",
+                                      "allowDuplicateIps", "false");
+        compCfgService.registerProperties(getClass());
+        modified(context);
+
+        processor = new InternalPacketProcessor();
+        linkListener = new InternalLinkListener();
+        deviceListener = new InternalDeviceListener();
+        appCfgHandler = new AppConfigHandler(this);
+        xConnectHandler = new XConnectHandler(this);
+        mcastHandler = new McastHandler(this);
+        hostHandler = new HostHandler(this);
+        linkHandler = new LinkHandler(this);
+        routeHandler = new RouteHandler(this);
+        neighbourHandler = new SegmentRoutingNeighbourDispatcher(this);
+        l2TunnelHandler = new DefaultL2TunnelHandler(this);
+
+        cfgService.addListener(cfgListener);
+        cfgService.registerConfigFactory(deviceConfigFactory);
+        cfgService.registerConfigFactory(appConfigFactory);
+        cfgService.registerConfigFactory(xConnectConfigFactory);
+        cfgService.registerConfigFactory(mcastConfigFactory);
+        cfgService.registerConfigFactory(pwaasConfigFactory);
+        log.info("Configuring network before adding listeners");
+        cfgListener.configureNetwork();
+
+        hostService.addListener(hostListener);
+        packetService.addProcessor(processor, PacketProcessor.director(2));
+        linkService.addListener(linkListener);
+        deviceService.addListener(deviceListener);
+        multicastRouteService.addListener(mcastListener);
+        routeService.addListener(routeListener);
+
+        l2TunnelHandler.init();
+
+        log.info("Started");
+    }
+
+    KryoNamespace.Builder createSerializer() {
+        return new KryoNamespace.Builder()
+                .register(KryoNamespaces.API)
+                .register(DestinationSetNextObjectiveStoreKey.class,
+                          VlanNextObjectiveStoreKey.class,
+                          DestinationSet.class,
+                          NextNeighbors.class,
+                          Tunnel.class,
+                          DefaultTunnel.class,
+                          Policy.class,
+                          TunnelPolicy.class,
+                          Policy.Type.class,
+                          PortNextObjectiveStoreKey.class,
+                          XConnectStoreKey.class,
+                          L2Tunnel.class,
+                          L2TunnelPolicy.class,
+                          DefaultL2Tunnel.class,
+                          DefaultL2TunnelPolicy.class
+                );
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        cfgService.removeListener(cfgListener);
+        cfgService.unregisterConfigFactory(deviceConfigFactory);
+        cfgService.unregisterConfigFactory(appConfigFactory);
+        cfgService.unregisterConfigFactory(xConnectConfigFactory);
+        cfgService.unregisterConfigFactory(mcastConfigFactory);
+        cfgService.unregisterConfigFactory(pwaasConfigFactory);
+        compCfgService.unregisterProperties(getClass(), false);
+
+        hostService.removeListener(hostListener);
+        packetService.removeProcessor(processor);
+        linkService.removeListener(linkListener);
+        deviceService.removeListener(deviceListener);
+        multicastRouteService.removeListener(mcastListener);
+        routeService.removeListener(routeListener);
+
+        neighbourResolutionService.unregisterNeighbourHandlers(appId);
+
+        processor = null;
+        linkListener = null;
+        deviceListener = null;
+        groupHandlerMap.clear();
+
+        dsNextObjStore.destroy();
+        vlanNextObjStore.destroy();
+        portNextObjStore.destroy();
+        tunnelStore.destroy();
+        policyStore.destroy();
+
+        mcastHandler.terminate();
+        log.info("Stopped");
+    }
+
+    @Modified
+    private void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+        if (properties == null) {
+            return;
+        }
+
+        String strActiveProving = Tools.get(properties, "activeProbing");
+        boolean expectActiveProbing = Boolean.parseBoolean(strActiveProving);
+
+        if (expectActiveProbing != activeProbing) {
+            activeProbing = expectActiveProbing;
+            log.info("{} active probing", activeProbing ? "Enabling" : "Disabling");
+        }
+    }
+
+    @Override
+    public List<Tunnel> getTunnels() {
+        return tunnelHandler.getTunnels();
+    }
+
+    @Override
+    public TunnelHandler.Result createTunnel(Tunnel tunnel) {
+        return tunnelHandler.createTunnel(tunnel);
+    }
+
+    @Override
+    public TunnelHandler.Result removeTunnel(Tunnel tunnel) {
+        for (Policy policy: policyHandler.getPolicies()) {
+            if (policy.type() == Policy.Type.TUNNEL_FLOW) {
+                TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
+                if (tunnelPolicy.tunnelId().equals(tunnel.id())) {
+                    log.warn("Cannot remove the tunnel used by a policy");
+                    return TunnelHandler.Result.TUNNEL_IN_USE;
+                }
+            }
+        }
+        return tunnelHandler.removeTunnel(tunnel);
+    }
+
+    @Override
+    public PolicyHandler.Result removePolicy(Policy policy) {
+        return policyHandler.removePolicy(policy);
+    }
+
+    @Override
+    public PolicyHandler.Result createPolicy(Policy policy) {
+        return policyHandler.createPolicy(policy);
+    }
+
+    @Override
+    public List<Policy> getPolicies() {
+        return policyHandler.getPolicies();
+    }
+
+    @Override
+    public List<L2Tunnel> getL2Tunnels() {
+        return l2TunnelHandler.getL2Tunnels();
+    }
+
+    @Override
+    public List<L2TunnelPolicy> getL2Policies() {
+        return l2TunnelHandler.getL2Policies();
+    }
+
+    @Override
+    public L2TunnelHandler.Result addPseudowire(String tunnelId, String pwLabel, String cP1,
+                                                 String cP1InnerVlan, String cP1OuterVlan, String cP2,
+                                                 String cP2InnerVlan, String cP2OuterVlan,
+                                                 String mode, String sdTag) {
+        // Try to inject an empty Pwaas config if it is not found for the first time
+        PwaasConfig config = cfgService.getConfig(appId(), PwaasConfig.class);
+        if (config == null) {
+            log.debug("Pwaas config not found. Try to create an empty one.");
+            cfgService.applyConfig(appId(), PwaasConfig.class, new ObjectMapper().createObjectNode());
+            config = cfgService.getConfig(appId(), PwaasConfig.class);
+        }
+
+        ObjectNode object = config.addPseudowire(tunnelId, pwLabel,
+                                                 cP1, cP1InnerVlan, cP1OuterVlan,
+                                                 cP2, cP2InnerVlan, cP2OuterVlan,
+                                                 mode, sdTag);
+        if (object == null) {
+            log.warn("Could not add pseudowire to the configuration!");
+            return L2TunnelHandler.Result.ADDITION_ERROR;
+        }
+
+        // inform everyone about the valid change in the pw configuration
+        cfgService.applyConfig(appId(), PwaasConfig.class, object);
+        return L2TunnelHandler.Result.SUCCESS;
+    }
+
+    @Override
+    public L2TunnelHandler.Result removePseudowire(String pwId) {
+
+        PwaasConfig config = cfgService.getConfig(appId(), PwaasConfig.class);
+        if (config == null) {
+            log.warn("Configuration for Pwaas class could not be found!");
+            return L2TunnelHandler.Result.CONFIG_NOT_FOUND;
+        }
+
+        ObjectNode object = config.removePseudowire(pwId);
+        if (object == null) {
+            log.warn("Could not delete pseudowire from configuration!");
+            return L2TunnelHandler.Result.REMOVAL_ERROR;
+        }
+
+        // sanity check, this should never fail since we removed a pw
+        // and we always check when we update the configuration
+        config.isValid();
+
+        // inform everyone
+        cfgService.applyConfig(appId(), PwaasConfig.class, object);
+
+        return L2TunnelHandler.Result.SUCCESS;
+    }
+
+    @Override
+    public void rerouteNetwork() {
+        cfgListener.configureNetwork();
+    }
+
+    @Override
+    public Map<DeviceId, Set<IpPrefix>> getDeviceSubnetMap() {
+        Map<DeviceId, Set<IpPrefix>> deviceSubnetMap = Maps.newHashMap();
+        deviceConfiguration.getRouters().forEach(device ->
+            deviceSubnetMap.put(device, deviceConfiguration.getSubnets(device)));
+        return deviceSubnetMap;
+    }
+
+
+    @Override
+    public ImmutableMap<DeviceId, EcmpShortestPathGraph> getCurrentEcmpSpg() {
+        if (defaultRoutingHandler != null) {
+            return defaultRoutingHandler.getCurrentEmcpSpgMap();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public ImmutableMap<DestinationSetNextObjectiveStoreKey, NextNeighbors> getDestinationSet() {
+        if (dsNextObjStore != null) {
+            return ImmutableMap.copyOf(dsNextObjStore.entrySet());
+        } else {
+            return ImmutableMap.of();
+        }
+    }
+
+    @Override
+    public void verifyGroups(DeviceId id) {
+        DefaultGroupHandler gh = groupHandlerMap.get(id);
+        if (gh != null) {
+            gh.triggerBucketCorrector();
+        }
+    }
+
+    @Override
+    public ImmutableMap<Link, Boolean> getSeenLinks() {
+        return linkHandler.getSeenLinks();
+    }
+
+    @Override
+    public ImmutableMap<DeviceId, Set<PortNumber>> getDownedPortState() {
+        return linkHandler.getDownedPorts();
+    }
+
+    @Override
+    public Map<McastStoreKey, Integer> getMcastNextIds(IpAddress mcastIp) {
+        return mcastHandler.getMcastNextIds(mcastIp);
+    }
+
+    @Override
+    public Map<McastStoreKey, McastHandler.McastRole> getMcastRoles(IpAddress mcastIp) {
+        return mcastHandler.getMcastRoles(mcastIp);
+    }
+
+    @Override
+    public Map<ConnectPoint, List<ConnectPoint>> getMcastPaths(IpAddress mcastIp) {
+        return mcastHandler.getMcastPaths(mcastIp);
+    }
+
+    /**
+     * Extracts the application ID from the manager.
+     *
+     * @return application ID
+     */
+    public ApplicationId appId() {
+        return appId;
+    }
+
+    /**
+     * Returns the device configuration.
+     *
+     * @return device configuration
+     */
+    public DeviceConfiguration deviceConfiguration() {
+        return deviceConfiguration;
+    }
+
+    /**
+     * Per device next objective ID store with (device id + destination set) as key.
+     * Used to keep track on MPLS group information.
+     *
+     * @return next objective ID store
+     */
+    public EventuallyConsistentMap<DestinationSetNextObjectiveStoreKey, NextNeighbors>
+                dsNextObjStore() {
+        return dsNextObjStore;
+    }
+
+    /**
+     * Per device next objective ID store with (device id + vlanid) as key.
+     * Used to keep track on L2 flood group information.
+     *
+     * @return vlan next object store
+     */
+    public EventuallyConsistentMap<VlanNextObjectiveStoreKey, Integer> vlanNextObjStore() {
+        return vlanNextObjStore;
+    }
+
+    /**
+     * Per device next objective ID store with (device id + port + treatment + meta) as key.
+     * Used to keep track on L2 interface group and L3 unicast group information.
+     *
+     * @return port next object store.
+     */
+    public EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer> portNextObjStore() {
+        return portNextObjStore;
+    }
+
+    /**
+     * Returns the MPLS-ECMP configuration which indicates whether ECMP on
+     * labeled packets should be programmed or not.
+     *
+     * @return MPLS-ECMP value
+     */
+    public boolean getMplsEcmp() {
+        SegmentRoutingAppConfig segmentRoutingAppConfig = cfgService
+                .getConfig(this.appId, SegmentRoutingAppConfig.class);
+        return segmentRoutingAppConfig != null && segmentRoutingAppConfig.mplsEcmp();
+    }
+
+    /**
+     * Returns the tunnel object with the tunnel ID.
+     *
+     * @param tunnelId Tunnel ID
+     * @return Tunnel reference
+     */
+    public Tunnel getTunnel(String tunnelId) {
+        return tunnelHandler.getTunnel(tunnelId);
+    }
+
+    // TODO Consider moving these to InterfaceService
+    /**
+     * Returns untagged VLAN configured on given connect point.
+     * <p>
+     * Only returns the first match if there are multiple untagged VLAN configured
+     * on the connect point.
+     *
+     * @param connectPoint connect point
+     * @return untagged VLAN or null if not configured
+     */
+    VlanId getUntaggedVlanId(ConnectPoint connectPoint) {
+        return interfaceService.getInterfacesByPort(connectPoint).stream()
+                .filter(intf -> !intf.vlanUntagged().equals(VlanId.NONE))
+                .map(Interface::vlanUntagged)
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Returns tagged VLAN configured on given connect point.
+     * <p>
+     * Returns all matches if there are multiple tagged VLAN configured
+     * on the connect point.
+     *
+     * @param connectPoint connect point
+     * @return tagged VLAN or empty set if not configured
+     */
+    Set<VlanId> getTaggedVlanId(ConnectPoint connectPoint) {
+        Set<Interface> interfaces = interfaceService.getInterfacesByPort(connectPoint);
+        return interfaces.stream()
+                .map(Interface::vlanTagged)
+                .flatMap(Set::stream)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Returns native VLAN configured on given connect point.
+     * <p>
+     * Only returns the first match if there are multiple native VLAN configured
+     * on the connect point.
+     *
+     * @param connectPoint connect point
+     * @return native VLAN or null if not configured
+     */
+    VlanId getNativeVlanId(ConnectPoint connectPoint) {
+        Set<Interface> interfaces = interfaceService.getInterfacesByPort(connectPoint);
+        return interfaces.stream()
+                .filter(intf -> !intf.vlanNative().equals(VlanId.NONE))
+                .map(Interface::vlanNative)
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Returns internal VLAN for untagged hosts on given connect point.
+     * <p>
+     * The internal VLAN is either vlan-untagged for an access port,
+     * or vlan-native for a trunk port.
+     *
+     * @param connectPoint connect point
+     * @return internal VLAN or null if both vlan-untagged and vlan-native are undefined
+     */
+    VlanId getInternalVlanId(ConnectPoint connectPoint) {
+        VlanId untaggedVlanId = getUntaggedVlanId(connectPoint);
+        VlanId nativeVlanId = getNativeVlanId(connectPoint);
+        return untaggedVlanId != null ? untaggedVlanId : nativeVlanId;
+    }
+
+    /**
+     * Returns optional pair device ID of given device.
+     *
+     * @param deviceId device ID
+     * @return optional pair device ID. Might be empty if pair device is not configured
+     */
+    Optional<DeviceId> getPairDeviceId(DeviceId deviceId) {
+        SegmentRoutingDeviceConfig deviceConfig =
+                cfgService.getConfig(deviceId, SegmentRoutingDeviceConfig.class);
+        return Optional.ofNullable(deviceConfig).map(SegmentRoutingDeviceConfig::pairDeviceId);
+    }
+    /**
+     * Returns optional pair device local port of given device.
+     *
+     * @param deviceId device ID
+     * @return optional pair device ID. Might be empty if pair device is not configured
+     */
+    Optional<PortNumber> getPairLocalPorts(DeviceId deviceId) {
+        SegmentRoutingDeviceConfig deviceConfig =
+                cfgService.getConfig(deviceId, SegmentRoutingDeviceConfig.class);
+        return Optional.ofNullable(deviceConfig).map(SegmentRoutingDeviceConfig::pairLocalPort);
+    }
+
+    /**
+     * Determine if current instance is the master of given connect point.
+     *
+     * @param cp connect point
+     * @return true if current instance is the master of given connect point
+     */
+    public boolean isMasterOf(ConnectPoint cp) {
+        boolean isMaster = mastershipService.isLocalMaster(cp.deviceId());
+        if (!isMaster) {
+            log.debug(NOT_MASTER, cp);
+        }
+        return isMaster;
+    }
+
+    /**
+     * Returns locations of given resolved route.
+     *
+     * @param resolvedRoute resolved route
+     * @return locations of nexthop. Might be empty if next hop is not found
+     */
+    Set<ConnectPoint> nextHopLocations(ResolvedRoute resolvedRoute) {
+        HostId hostId = HostId.hostId(resolvedRoute.nextHopMac(), resolvedRoute.nextHopVlan());
+        return Optional.ofNullable(hostService.getHost(hostId))
+                .map(Host::locations).orElse(Sets.newHashSet())
+                .stream().map(l -> (ConnectPoint) l).collect(Collectors.toSet());
+    }
+
+    /**
+     * Returns vlan port map of given device.
+     *
+     * @param deviceId device id
+     * @return vlan-port multimap
+     */
+    public Multimap<VlanId, PortNumber> getVlanPortMap(DeviceId deviceId) {
+        HashMultimap<VlanId, PortNumber> vlanPortMap = HashMultimap.create();
+
+        interfaceService.getInterfaces().stream()
+                .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
+                .forEach(intf -> {
+                    vlanPortMap.put(intf.vlanUntagged(), intf.connectPoint().port());
+                    intf.vlanTagged().forEach(vlanTagged ->
+                        vlanPortMap.put(vlanTagged, intf.connectPoint().port())
+                    );
+                    vlanPortMap.put(intf.vlanNative(), intf.connectPoint().port());
+                });
+        vlanPortMap.removeAll(VlanId.NONE);
+
+        return vlanPortMap;
+    }
+
+    /**
+     * Returns the next objective ID for the given vlan id. It is expected
+     * that the next-objective has been pre-created from configuration.
+     *
+     * @param deviceId Device ID
+     * @param vlanId VLAN ID
+     * @return next objective ID or -1 if it was not found
+     */
+    int getVlanNextObjectiveId(DeviceId deviceId, VlanId vlanId) {
+        if (groupHandlerMap.get(deviceId) != null) {
+            log.trace("getVlanNextObjectiveId query in device {}", deviceId);
+            return groupHandlerMap.get(deviceId).getVlanNextObjectiveId(vlanId);
+        } else {
+            log.warn("getVlanNextObjectiveId query - groupHandler for "
+                    + "device {} not found", deviceId);
+            return -1;
+        }
+    }
+
+    /**
+     * Returns the next objective ID for the given portNumber, given the treatment.
+     * There could be multiple different treatments to the same outport, which
+     * would result in different objectives. If the next object does not exist,
+     * and should be created, a new one is created and its id is returned.
+     *
+     * @param deviceId Device ID
+     * @param portNum port number on device for which NextObjective is queried
+     * @param treatment the actions to apply on the packets (should include outport)
+     * @param meta metadata passed into the creation of a Next Objective if necessary
+     * @param createIfMissing true if a next object should be created if not found
+     * @return next objective ID or -1 if an error occurred during retrieval or creation
+     */
+    public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum,
+                                      TrafficTreatment treatment,
+                                      TrafficSelector meta,
+                                      boolean createIfMissing) {
+        DefaultGroupHandler ghdlr = groupHandlerMap.get(deviceId);
+        if (ghdlr != null) {
+            return ghdlr.getPortNextObjectiveId(portNum, treatment, meta, createIfMissing);
+        } else {
+            log.warn("getPortNextObjectiveId query - groupHandler for device {}"
+                    + " not found", deviceId);
+            return -1;
+        }
+    }
+
+    /**
+     * Returns the group handler object for the specified device id.
+     *
+     * @param devId the device identifier
+     * @return the groupHandler object for the device id, or null if not found
+     */
+    DefaultGroupHandler getGroupHandler(DeviceId devId) {
+        return groupHandlerMap.get(devId);
+    }
+
+    /**
+     * Returns the default routing handler object.
+     *
+     * @return the default routing handler object
+     */
+    public DefaultRoutingHandler getRoutingHandler() {
+        return defaultRoutingHandler;
+    }
+
+    private class InternalPacketProcessor implements PacketProcessor {
+        @Override
+        public void process(PacketContext context) {
+
+            if (context.isHandled()) {
+                return;
+            }
+
+            InboundPacket pkt = context.inPacket();
+            Ethernet ethernet = pkt.parsed();
+
+            if (ethernet == null) {
+                return;
+            }
+
+            log.trace("Rcvd pktin from {}: {}", context.inPacket().receivedFrom(),
+                      ethernet);
+            if (ethernet.getEtherType() == TYPE_ARP) {
+                log.warn("Received unexpected ARP packet on {}",
+                         context.inPacket().receivedFrom());
+                log.trace("{}", ethernet);
+                return;
+            } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
+                IPv4 ipv4Packet = (IPv4) ethernet.getPayload();
+                //ipHandler.addToPacketBuffer(ipv4Packet);
+                if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_ICMP) {
+                    icmpHandler.processIcmp(ethernet, pkt.receivedFrom());
+                } else {
+                    // NOTE: We don't support IP learning at this moment so this
+                    //       is not necessary. Also it causes duplication of DHCP packets.
+                    // ipHandler.processPacketIn(ipv4Packet, pkt.receivedFrom());
+                }
+            } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV6) {
+                IPv6 ipv6Packet = (IPv6) ethernet.getPayload();
+                //ipHandler.addToPacketBuffer(ipv6Packet);
+                // We deal with the packet only if the packet is a ICMP6 ECHO/REPLY
+                if (ipv6Packet.getNextHeader() == IPv6.PROTOCOL_ICMP6) {
+                    ICMP6 icmp6Packet = (ICMP6) ipv6Packet.getPayload();
+                    if (icmp6Packet.getIcmpType() == ICMP6.ECHO_REQUEST ||
+                            icmp6Packet.getIcmpType() == ICMP6.ECHO_REPLY) {
+                        icmpHandler.processIcmpv6(ethernet, pkt.receivedFrom());
+                    } else {
+                        log.trace("Received ICMPv6 0x{} - not handled",
+                                Integer.toHexString(icmp6Packet.getIcmpType() & 0xff));
+                    }
+                } else {
+                   // NOTE: We don't support IP learning at this moment so this
+                   //       is not necessary. Also it causes duplication of DHCPv6 packets.
+                   // ipHandler.processPacketIn(ipv6Packet, pkt.receivedFrom());
+                }
+            }
+        }
+    }
+
+    private class InternalLinkListener implements LinkListener {
+        @Override
+        public void event(LinkEvent event) {
+            if (event.type() == LinkEvent.Type.LINK_ADDED ||
+                    event.type() == LinkEvent.Type.LINK_UPDATED ||
+                    event.type() == LinkEvent.Type.LINK_REMOVED) {
+                log.debug("Event {} received from Link Service", event.type());
+                scheduleEventHandlerIfNotScheduled(event);
+            }
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            switch (event.type()) {
+            case DEVICE_ADDED:
+            case PORT_UPDATED:
+            case PORT_ADDED:
+            case DEVICE_UPDATED:
+            case DEVICE_AVAILABILITY_CHANGED:
+                log.trace("Event {} received from Device Service", event.type());
+                scheduleEventHandlerIfNotScheduled(event);
+                break;
+            default:
+            }
+        }
+    }
+
+    @SuppressWarnings("rawtypes")
+    private void scheduleEventHandlerIfNotScheduled(Event event) {
+        synchronized (THREAD_SCHED_LOCK) {
+            eventQueue.add(event);
+            numOfEventsQueued++;
+
+            if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) {
+                //No pending scheduled event handling threads. So start a new one.
+                eventHandlerFuture = executorService
+                        .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
+                numOfHandlerScheduled++;
+            }
+            log.trace("numOfEventsQueued {}, numOfEventHandlerScheduled {}",
+                      numOfEventsQueued,
+                      numOfHandlerScheduled);
+        }
+    }
+
+    private class InternalEventHandler implements Runnable {
+        @Override
+        public void run() {
+            while (true) {
+                try {
+                    @SuppressWarnings("rawtypes")
+                    Event event;
+                    synchronized (THREAD_SCHED_LOCK) {
+                        if (!eventQueue.isEmpty()) {
+                            event = eventQueue.poll();
+                            numOfEventsExecuted++;
+                        } else {
+                            numOfHandlerExecution++;
+                            log.debug("numOfHandlerExecution {} numOfEventsExecuted {}",
+                                      numOfHandlerExecution, numOfEventsExecuted);
+                            break;
+                        }
+                    }
+                    if (event.type() == LinkEvent.Type.LINK_ADDED ||
+                            event.type() == LinkEvent.Type.LINK_UPDATED) {
+                        linkHandler.processLinkAdded((Link) event.subject());
+                    } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
+                        linkHandler.processLinkRemoved((Link) event.subject());
+                    } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
+                            event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
+                            event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
+                        DeviceId deviceId = ((Device) event.subject()).id();
+                        if (deviceService.isAvailable(deviceId)) {
+                            log.info("Processing device event {} for available device {}",
+                                     event.type(), ((Device) event.subject()).id());
+                            processDeviceAdded((Device) event.subject());
+                        } else {
+                            log.info("Processing device event {} for unavailable device {}",
+                                     event.type(), ((Device) event.subject()).id());
+                            processDeviceRemoved((Device) event.subject());
+                        }
+                    } else if (event.type() == DeviceEvent.Type.PORT_ADDED) {
+                        // typically these calls come when device is added first time
+                        // so port filtering rules are handled at the device_added event.
+                        // port added calls represent all ports on the device,
+                        // enabled or not.
+                        log.trace("** PORT ADDED {}/{} -> {}",
+                                  ((DeviceEvent) event).subject().id(),
+                                  ((DeviceEvent) event).port().number(),
+                                  event.type());
+                    } else if (event.type() == DeviceEvent.Type.PORT_UPDATED) {
+                        // these calls happen for every subsequent event
+                        // ports enabled, disabled, switch goes away, comes back
+                        log.info("** PORT UPDATED {}/{} -> {}",
+                                 event.subject(),
+                                 ((DeviceEvent) event).port(),
+                                 event.type());
+                        processPortUpdated(((Device) event.subject()),
+                                           ((DeviceEvent) event).port());
+                    } else {
+                        log.warn("Unhandled event type: {}", event.type());
+                    }
+                } catch (Exception e) {
+                    log.error("SegmentRouting event handler thread thrown an exception: {}",
+                              e.getMessage(), e);
+                }
+            }
+        }
+    }
+
+    void processDeviceAdded(Device device) {
+        log.info("** DEVICE ADDED with ID {}", device.id());
+
+        // NOTE: Punt ARP/NDP even when the device is not configured.
+        //       Host learning without network config is required for CORD config generator.
+        routingRulePopulator.populateIpPunts(device.id());
+        routingRulePopulator.populateArpNdpPunts(device.id());
+
+        if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) {
+            log.warn("Device configuration unavailable. Device {} will be "
+                    + "processed after configuration.", device.id());
+            return;
+        }
+        processDeviceAddedInternal(device.id());
+    }
+
+    private void processDeviceAddedInternal(DeviceId deviceId) {
+        // Irrespective of whether the local is a MASTER or not for this device,
+        // we need to create a SR-group-handler instance. This is because in a
+        // multi-instance setup, any instance can initiate forwarding/next-objectives
+        // for any switch (even if this instance is a SLAVE or not even connected
+        // to the switch). To handle this, a default-group-handler instance is necessary
+        // per switch.
+        log.debug("Current groupHandlerMap devs: {}", groupHandlerMap.keySet());
+        if (groupHandlerMap.get(deviceId) == null) {
+            DefaultGroupHandler groupHandler;
+            try {
+                groupHandler = DefaultGroupHandler.
+                        createGroupHandler(deviceId,
+                                appId,
+                                deviceConfiguration,
+                                linkService,
+                                flowObjectiveService,
+                                this);
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn(e.getMessage() + " Aborting processDeviceAdded.");
+                return;
+            }
+            log.debug("updating groupHandlerMap with new grpHdlr for device: {}",
+                    deviceId);
+            groupHandlerMap.put(deviceId, groupHandler);
+        }
+
+        if (mastershipService.isLocalMaster(deviceId)) {
+            defaultRoutingHandler.populatePortAddressingRules(deviceId);
+            hostHandler.init(deviceId);
+            xConnectHandler.init(deviceId);
+            DefaultGroupHandler groupHandler = groupHandlerMap.get(deviceId);
+            groupHandler.createGroupsFromVlanConfig();
+            routingRulePopulator.populateSubnetBroadcastRule(deviceId);
+        }
+
+        appCfgHandler.init(deviceId);
+        routeHandler.init(deviceId);
+    }
+
+    private void processDeviceRemoved(Device device) {
+        dsNextObjStore.entrySet().stream()
+                .filter(entry -> entry.getKey().deviceId().equals(device.id()))
+                .forEach(entry -> dsNextObjStore.remove(entry.getKey()));
+        vlanNextObjStore.entrySet().stream()
+                .filter(entry -> entry.getKey().deviceId().equals(device.id()))
+                .forEach(entry -> vlanNextObjStore.remove(entry.getKey()));
+        portNextObjStore.entrySet().stream()
+                .filter(entry -> entry.getKey().deviceId().equals(device.id()))
+                .forEach(entry -> portNextObjStore.remove(entry.getKey()));
+        linkHandler.processDeviceRemoved(device);
+
+        DefaultGroupHandler gh = groupHandlerMap.remove(device.id());
+        if (gh != null) {
+            gh.shutdown();
+        }
+        // Note that a switch going down is associated with all of its links
+        // going down as well, but it is treated as a single switch down event
+        // while the link-downs are ignored.
+        defaultRoutingHandler
+            .populateRoutingRulesForLinkStatusChange(null, null, device.id());
+        defaultRoutingHandler.purgeEcmpGraph(device.id());
+        mcastHandler.processDeviceDown(device.id());
+        xConnectHandler.removeDevice(device.id());
+    }
+
+    private void processPortUpdated(Device device, Port port) {
+        if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) {
+            log.warn("Device configuration uploading. Not handling port event for"
+                    + "dev: {} port: {}", device.id(), port.number());
+            return;
+        }
+
+        if (!mastershipService.isLocalMaster(device.id()))  {
+            log.debug("Not master for dev:{} .. not handling port updated event"
+                    + "for port {}", device.id(), port.number());
+            return;
+        }
+
+        // first we handle filtering rules associated with the port
+        if (port.isEnabled()) {
+            log.info("Switchport {}/{} enabled..programming filters",
+                     device.id(), port.number());
+            routingRulePopulator.processSinglePortFilters(device.id(), port.number(), true);
+        } else {
+            log.info("Switchport {}/{} disabled..removing filters",
+                     device.id(), port.number());
+            routingRulePopulator.processSinglePortFilters(device.id(), port.number(), false);
+        }
+
+        // portUpdated calls are for ports that have gone down or up. For switch
+        // to switch ports, link-events should take care of any re-routing or
+        // group editing necessary for port up/down. Here we only process edge ports
+        // that are already configured.
+        ConnectPoint cp = new ConnectPoint(device.id(), port.number());
+        VlanId untaggedVlan = getUntaggedVlanId(cp);
+        VlanId nativeVlan = getNativeVlanId(cp);
+        Set<VlanId> taggedVlans = getTaggedVlanId(cp);
+
+        if (untaggedVlan == null && nativeVlan == null && taggedVlans.isEmpty()) {
+            log.debug("Not handling port updated event for non-edge port (unconfigured) "
+                    + "dev/port: {}/{}", device.id(), port.number());
+            return;
+        }
+        if (untaggedVlan != null) {
+            processEdgePort(device, port, untaggedVlan, true);
+        }
+        if (nativeVlan != null) {
+            processEdgePort(device, port, nativeVlan, true);
+        }
+        if (!taggedVlans.isEmpty()) {
+            taggedVlans.forEach(tag -> processEdgePort(device, port, tag, false));
+        }
+    }
+
+    private void processEdgePort(Device device, Port port, VlanId vlanId,
+                                 boolean popVlan) {
+        boolean portUp = port.isEnabled();
+        if (portUp) {
+            log.info("Device:EdgePort {}:{} is enabled in vlan: {}", device.id(),
+                     port.number(), vlanId);
+            hostHandler.processPortUp(new ConnectPoint(device.id(), port.number()));
+        } else {
+            log.info("Device:EdgePort {}:{} is disabled in vlan: {}", device.id(),
+                     port.number(), vlanId);
+        }
+
+        DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
+        if (groupHandler != null) {
+            groupHandler.processEdgePort(port.number(), vlanId, popVlan, portUp);
+        } else {
+            log.warn("Group handler not found for dev:{}. Not handling edge port"
+                    + " {} event for port:{}", device.id(),
+                    (portUp) ? "UP" : "DOWN", port.number());
+        }
+    }
+
+    private void createOrUpdateDeviceConfiguration() {
+        if (deviceConfiguration == null) {
+            log.info("Creating new DeviceConfiguration");
+            deviceConfiguration = new DeviceConfiguration(this);
+        } else {
+            log.info("Updating DeviceConfiguration");
+            deviceConfiguration.updateConfig();
+        }
+    }
+
+    /**
+     * Registers the given connect point with the NRS, this is necessary
+     * to receive the NDP and ARP packets from the NRS.
+     *
+     * @param portToRegister connect point to register
+     */
+    public void registerConnectPoint(ConnectPoint portToRegister) {
+        neighbourResolutionService.registerNeighbourHandler(
+                portToRegister,
+                neighbourHandler,
+                appId
+        );
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+        private static final long PROGRAM_DELAY = 2;
+        SegmentRoutingManager srManager;
+
+        /**
+         * Constructs the internal network config listener.
+         *
+         * @param srManager segment routing manager
+         */
+        InternalConfigListener(SegmentRoutingManager srManager) {
+            this.srManager = srManager;
+        }
+
+        /**
+         * Reads network config and initializes related data structure accordingly.
+         */
+        void configureNetwork() {
+            log.info("Configuring network ...");
+            createOrUpdateDeviceConfiguration();
+
+            arpHandler = new ArpHandler(srManager);
+            icmpHandler = new IcmpHandler(srManager);
+            ipHandler = new IpHandler(srManager);
+            routingRulePopulator = new RoutingRulePopulator(srManager);
+            defaultRoutingHandler = new DefaultRoutingHandler(srManager);
+
+            tunnelHandler = new TunnelHandler(linkService, deviceConfiguration,
+                                              groupHandlerMap, tunnelStore);
+            policyHandler = new PolicyHandler(appId, deviceConfiguration,
+                                              flowObjectiveService,
+                                              tunnelHandler, policyStore);
+            // add a small delay to absorb multiple network config added notifications
+            if (!programmingScheduled.get()) {
+                log.info("Buffering config calls for {} secs", PROGRAM_DELAY);
+                programmingScheduled.set(true);
+                executorService.schedule(new ConfigChange(), PROGRAM_DELAY,
+                                         TimeUnit.SECONDS);
+            }
+            mcastHandler.init();
+        }
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            // TODO move this part to NetworkConfigEventHandler
+            if (event.configClass().equals(SegmentRoutingDeviceConfig.class)) {
+                switch (event.type()) {
+                    case CONFIG_ADDED:
+                        log.info("Segment Routing Device Config added for {}", event.subject());
+                        configureNetwork();
+                        break;
+                    case CONFIG_UPDATED:
+                        log.info("Segment Routing Config updated for {}", event.subject());
+                        createOrUpdateDeviceConfiguration();
+                        // TODO support dynamic configuration
+                        break;
+                    default:
+                        break;
+                }
+            } else if (event.configClass().equals(InterfaceConfig.class)) {
+                switch (event.type()) {
+                    case CONFIG_ADDED:
+                        log.info("Interface Config added for {}", event.subject());
+                        configureNetwork();
+                        break;
+                    case CONFIG_UPDATED:
+                        log.info("Interface Config updated for {}", event.subject());
+                        createOrUpdateDeviceConfiguration();
+
+                        // Following code will be uncommented when [CORD-634] is fully implemented.
+                        // [CORD-634] Add dynamic config support for interfaces
+                        updateInterface((InterfaceConfig) event.config().get(),
+                                        (InterfaceConfig) event.prevConfig().get());
+                        // TODO support dynamic configuration
+                        break;
+                    default:
+                        break;
+                }
+            } else if (event.configClass().equals(SegmentRoutingAppConfig.class)) {
+                checkState(appCfgHandler != null, "NetworkConfigEventHandler is not initialized");
+                switch (event.type()) {
+                    case CONFIG_ADDED:
+                        appCfgHandler.processAppConfigAdded(event);
+                        break;
+                    case CONFIG_UPDATED:
+                        appCfgHandler.processAppConfigUpdated(event);
+                        break;
+                    case CONFIG_REMOVED:
+                        appCfgHandler.processAppConfigRemoved(event);
+                        break;
+                    default:
+                        break;
+                }
+                log.info("App config event .. configuring network");
+                configureNetwork();
+            } else if (event.configClass().equals(XConnectConfig.class)) {
+                checkState(xConnectHandler != null, "XConnectHandler is not initialized");
+                switch (event.type()) {
+                    case CONFIG_ADDED:
+                        xConnectHandler.processXConnectConfigAdded(event);
+                        break;
+                    case CONFIG_UPDATED:
+                        xConnectHandler.processXConnectConfigUpdated(event);
+                        break;
+                    case CONFIG_REMOVED:
+                        xConnectHandler.processXConnectConfigRemoved(event);
+                        break;
+                    default:
+                        break;
+                }
+            } else if (event.configClass().equals(PwaasConfig.class)) {
+                checkState(l2TunnelHandler != null, "DefaultL2TunnelHandler is not initialized");
+                switch (event.type()) {
+                    case CONFIG_ADDED:
+                        l2TunnelHandler.processPwaasConfigAdded(event);
+                        break;
+                    case CONFIG_UPDATED:
+                        l2TunnelHandler.processPwaasConfigUpdated(event);
+                        break;
+                    case CONFIG_REMOVED:
+                        l2TunnelHandler.processPwaasConfigRemoved(event);
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+
+        @Override
+        public boolean isRelevant(NetworkConfigEvent event) {
+            if (event.type() == CONFIG_REGISTERED ||
+                    event.type() == CONFIG_UNREGISTERED) {
+                log.debug("Ignore event {} due to type mismatch", event);
+                return false;
+            }
+
+            if (!event.configClass().equals(SegmentRoutingDeviceConfig.class) &&
+                    !event.configClass().equals(SegmentRoutingAppConfig.class) &&
+                    !event.configClass().equals(InterfaceConfig.class) &&
+                    !event.configClass().equals(XConnectConfig.class) &&
+                    !event.configClass().equals(PwaasConfig.class)) {
+                log.debug("Ignore event {} due to class mismatch", event);
+                return false;
+            }
+
+            return true;
+        }
+
+        private final class ConfigChange implements Runnable {
+            @Override
+            public void run() {
+                programmingScheduled.set(false);
+                log.info("Reacting to config changes after buffer delay");
+                for (Device device : deviceService.getDevices()) {
+                    processDeviceAdded(device);
+                }
+                defaultRoutingHandler.startPopulationProcess();
+            }
+        }
+    }
+
+    private class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            switch (event.type()) {
+                case HOST_ADDED:
+                    hostHandler.processHostAddedEvent(event);
+                    break;
+                case HOST_MOVED:
+                    hostHandler.processHostMovedEvent(event);
+                    routeHandler.processHostMovedEvent(event);
+                    break;
+                case HOST_REMOVED:
+                    hostHandler.processHostRemovedEvent(event);
+                    break;
+                case HOST_UPDATED:
+                    hostHandler.processHostUpdatedEvent(event);
+                    break;
+                default:
+                    log.warn("Unsupported host event type: {}", event.type());
+                    break;
+            }
+        }
+    }
+
+    private class InternalMcastListener implements McastListener {
+        @Override
+        public void event(McastEvent event) {
+            switch (event.type()) {
+                case SOURCE_ADDED:
+                    mcastHandler.processSourceAdded(event);
+                    break;
+                case SINK_ADDED:
+                    mcastHandler.processSinkAdded(event);
+                    break;
+                case SINK_REMOVED:
+                    mcastHandler.processSinkRemoved(event);
+                    break;
+                case ROUTE_REMOVED:
+                    mcastHandler.processRouteRemoved(event);
+                    break;
+                case ROUTE_ADDED:
+                default:
+                    break;
+            }
+        }
+    }
+
+    private class InternalRouteEventListener implements RouteListener {
+        @Override
+        public void event(RouteEvent event) {
+            switch (event.type()) {
+                case ROUTE_ADDED:
+                    routeHandler.processRouteAdded(event);
+                    break;
+                case ROUTE_UPDATED:
+                    routeHandler.processRouteUpdated(event);
+                    break;
+                case ROUTE_REMOVED:
+                    routeHandler.processRouteRemoved(event);
+                    break;
+                case ALTERNATIVE_ROUTES_CHANGED:
+                    routeHandler.processAlternativeRoutesChanged(event);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    private void updateInterface(InterfaceConfig conf, InterfaceConfig prevConf) {
+        try {
+            Set<Interface> intfs = conf.getInterfaces();
+            Set<Interface> prevIntfs = prevConf.getInterfaces();
+
+            // Now we only handle one interface config at each port.
+            if (intfs.size() != 1 || prevIntfs.size() != 1) {
+                log.warn("Interface update aborted - one at a time is allowed, " +
+                                 "but {} / {}(prev) received.", intfs.size(), prevIntfs.size());
+                return;
+            }
+
+            Interface intf = intfs.stream().findFirst().get();
+            Interface prevIntf = prevIntfs.stream().findFirst().get();
+
+            DeviceId deviceId = intf.connectPoint().deviceId();
+            PortNumber portNum = intf.connectPoint().port();
+
+            if (!mastershipService.isLocalMaster(deviceId)) {
+                log.debug("CONFIG_UPDATED event for interfaces should be " +
+                                  "handled by master node for device {}", deviceId);
+                return;
+            }
+
+            removeSubnetConfig(prevIntf.connectPoint(),
+                               Sets.difference(new HashSet<>(prevIntf.ipAddressesList()),
+                                               new HashSet<>(intf.ipAddressesList())));
+
+            if (prevIntf.vlanNative() != VlanId.NONE && !intf.vlanNative().equals(prevIntf.vlanNative())) {
+                // RemoveVlanNative
+                updateVlanConfigInternal(deviceId, portNum, prevIntf.vlanNative(), true, false);
+            }
+
+            if (!prevIntf.vlanTagged().isEmpty() && !intf.vlanTagged().equals(prevIntf.vlanTagged())) {
+                // RemoveVlanTagged
+                prevIntf.vlanTagged().stream().filter(i -> !intf.vlanTagged().contains(i)).forEach(
+                        vlanId -> updateVlanConfigInternal(deviceId, portNum, vlanId, false, false)
+                );
+            }
+
+            if (prevIntf.vlanUntagged() != VlanId.NONE && !intf.vlanUntagged().equals(prevIntf.vlanUntagged())) {
+                // RemoveVlanUntagged
+                updateVlanConfigInternal(deviceId, portNum, prevIntf.vlanUntagged(), true, false);
+            }
+
+            if (intf.vlanNative() != VlanId.NONE && !prevIntf.vlanNative().equals(intf.vlanNative())) {
+                // AddVlanNative
+                updateVlanConfigInternal(deviceId, portNum, intf.vlanNative(), true, true);
+            }
+
+            if (!intf.vlanTagged().isEmpty() && !intf.vlanTagged().equals(prevIntf.vlanTagged())) {
+                // AddVlanTagged
+                intf.vlanTagged().stream().filter(i -> !prevIntf.vlanTagged().contains(i)).forEach(
+                        vlanId -> updateVlanConfigInternal(deviceId, portNum, vlanId, false, true)
+                );
+            }
+
+            if (intf.vlanUntagged() != VlanId.NONE && !prevIntf.vlanUntagged().equals(intf.vlanUntagged())) {
+                // AddVlanUntagged
+                updateVlanConfigInternal(deviceId, portNum, intf.vlanUntagged(), true, true);
+            }
+            addSubnetConfig(prevIntf.connectPoint(),
+                            Sets.difference(new HashSet<>(intf.ipAddressesList()),
+                                            new HashSet<>(prevIntf.ipAddressesList())));
+        } catch (ConfigException e) {
+            log.error("Error in configuration");
+        }
+    }
+
+    private void updateVlanConfigInternal(DeviceId deviceId, PortNumber portNum,
+                                          VlanId vlanId, boolean pushVlan, boolean install) {
+        DefaultGroupHandler grpHandler = getGroupHandler(deviceId);
+        if (grpHandler == null) {
+            log.warn("Failed to retrieve group handler for device {}", deviceId);
+            return;
+        }
+
+        // Update filtering objective for a single port
+        routingRulePopulator.updateSinglePortFilters(deviceId, portNum, pushVlan, vlanId, install);
+
+        // Update filtering objective for multicast ingress port
+        mcastHandler.updateFilterToDevice(deviceId, portNum, vlanId, install);
+
+        int nextId = getVlanNextObjectiveId(deviceId, vlanId);
+
+        if (nextId != -1 && !install) {
+            // Update next objective for a single port as an output port
+            // Remove a single port from L2FG
+            grpHandler.updateGroupFromVlanConfiguration(portNum, Collections.singleton(vlanId), nextId, install);
+            // Remove L2 Bridging rule and L3 Unicast rule to the host
+            hostHandler.processIntfVlanUpdatedEvent(deviceId, portNum, vlanId, pushVlan, install);
+            // Remove broadcast forwarding rule and corresponding L2FG for VLAN
+            // only if there is no port configured on that VLAN ID
+            if (!getVlanPortMap(deviceId).containsKey(vlanId)) {
+                // Remove broadcast forwarding rule for the VLAN
+                routingRulePopulator.updateSubnetBroadcastRule(deviceId, vlanId, install);
+                // Remove L2FG for VLAN
+                grpHandler.removeBcastGroupFromVlan(deviceId, portNum, vlanId, pushVlan);
+            } else {
+                // Remove L2IG of the port
+                grpHandler.removePortNextObjective(deviceId, portNum, vlanId, pushVlan);
+            }
+        } else if (install) {
+            if (nextId != -1) {
+                // Add a single port to L2FG
+                grpHandler.updateGroupFromVlanConfiguration(portNum, Collections.singleton(vlanId), nextId, install);
+            } else {
+                // Create L2FG for VLAN
+                grpHandler.createBcastGroupFromVlan(vlanId, Collections.singleton(portNum));
+                routingRulePopulator.updateSubnetBroadcastRule(deviceId, vlanId, install);
+            }
+            hostHandler.processIntfVlanUpdatedEvent(deviceId, portNum, vlanId, pushVlan, install);
+        } else {
+            log.warn("Failed to retrieve next objective for vlan {} in device {}:{}", vlanId, deviceId, portNum);
+        }
+    }
+
+    private void removeSubnetConfig(ConnectPoint cp, Set<InterfaceIpAddress> ipAddressSet) {
+        Set<IpPrefix> ipPrefixSet = ipAddressSet.stream().
+                map(InterfaceIpAddress::subnetAddress).collect(Collectors.toSet());
+
+        Set<InterfaceIpAddress> deviceIntfIpAddrs = interfaceService.getInterfaces().stream()
+                .filter(intf -> intf.connectPoint().deviceId().equals(cp.deviceId()))
+                .filter(intf -> !intf.connectPoint().equals(cp))
+                .flatMap(intf -> intf.ipAddressesList().stream())
+                .collect(Collectors.toSet());
+        // 1. Partial subnet population
+        // Remove routing rules for removed subnet from previous configuration,
+        // which does not also exist in other interfaces in the same device
+        Set<IpPrefix> deviceIpPrefixSet = deviceIntfIpAddrs.stream()
+                .map(InterfaceIpAddress::subnetAddress)
+                .collect(Collectors.toSet());
+
+        defaultRoutingHandler.revokeSubnet(
+                ipPrefixSet.stream()
+                        .filter(ipPrefix -> !deviceIpPrefixSet.contains(ipPrefix))
+                        .collect(Collectors.toSet()));
+
+        // 2. Interface IP punts
+        // Remove IP punts for old Intf address
+        Set<IpAddress> deviceIpAddrs = deviceIntfIpAddrs.stream()
+                .map(InterfaceIpAddress::ipAddress)
+                .collect(Collectors.toSet());
+        ipAddressSet.stream()
+                .map(InterfaceIpAddress::ipAddress)
+                .filter(interfaceIpAddress -> !deviceIpAddrs.contains(interfaceIpAddress))
+                .forEach(interfaceIpAddress ->
+                                 routingRulePopulator.revokeSingleIpPunts(
+                                         cp.deviceId(), interfaceIpAddress));
+
+        // 3. Host unicast routing rule
+        // Remove unicast routing rule
+        hostHandler.processIntfIpUpdatedEvent(cp, ipPrefixSet, false);
+    }
+
+    private void addSubnetConfig(ConnectPoint cp, Set<InterfaceIpAddress> ipAddressSet) {
+        Set<IpPrefix> ipPrefixSet = ipAddressSet.stream().
+                map(InterfaceIpAddress::subnetAddress).collect(Collectors.toSet());
+
+        Set<InterfaceIpAddress> deviceIntfIpAddrs = interfaceService.getInterfaces().stream()
+                .filter(intf -> intf.connectPoint().deviceId().equals(cp.deviceId()))
+                .filter(intf -> !intf.connectPoint().equals(cp))
+                .flatMap(intf -> intf.ipAddressesList().stream())
+                .collect(Collectors.toSet());
+        // 1. Partial subnet population
+        // Add routing rules for newly added subnet, which does not also exist in
+        // other interfaces in the same device
+        Set<IpPrefix> deviceIpPrefixSet = deviceIntfIpAddrs.stream()
+                .map(InterfaceIpAddress::subnetAddress)
+                .collect(Collectors.toSet());
+
+        defaultRoutingHandler.populateSubnet(
+                Collections.singleton(cp),
+                ipPrefixSet.stream()
+                        .filter(ipPrefix -> !deviceIpPrefixSet.contains(ipPrefix))
+                        .collect(Collectors.toSet()));
+
+        // 2. Interface IP punts
+        // Add IP punts for new Intf address
+        Set<IpAddress> deviceIpAddrs = deviceIntfIpAddrs.stream()
+                .map(InterfaceIpAddress::ipAddress)
+                .collect(Collectors.toSet());
+        ipAddressSet.stream()
+                .map(InterfaceIpAddress::ipAddress)
+                .filter(interfaceIpAddress -> !deviceIpAddrs.contains(interfaceIpAddress))
+                .forEach(interfaceIpAddress ->
+                                 routingRulePopulator.populateSingleIpPunts(
+                                         cp.deviceId(), interfaceIpAddress));
+
+        // 3. Host unicast routing rule
+        // Add unicast routing rule
+        hostHandler.processIntfIpUpdatedEvent(cp, ipPrefixSet, true);
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingNeighbourDispatcher.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingNeighbourDispatcher.java
new file mode 100644
index 0000000..f170fae
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingNeighbourDispatcher.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import org.onosproject.net.neighbour.NeighbourMessageContext;
+import org.onosproject.net.neighbour.NeighbourMessageHandler;
+import org.onosproject.net.host.HostService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This handler dispatches to the appropriate handlers the
+ * neighbour discovery protocols.
+ */
+public class SegmentRoutingNeighbourDispatcher implements NeighbourMessageHandler {
+
+    private static Logger log = LoggerFactory.getLogger(SegmentRoutingNeighbourDispatcher.class);
+    private SegmentRoutingManager manager;
+
+    /**
+     * Create a segment routing neighbour dispatcher.
+     *
+     * @param segmentRoutingManager the segment routing manager
+     */
+    public SegmentRoutingNeighbourDispatcher(SegmentRoutingManager segmentRoutingManager) {
+        this.manager = segmentRoutingManager;
+    }
+
+    @Override
+    public void handleMessage(NeighbourMessageContext context, HostService hostService) {
+        log.trace("Received {} packet on {}: {}", context.protocol(),
+                  context.inPort(), context.packet());
+        switch (context.protocol()) {
+            case ARP:
+                if (this.manager.arpHandler != null) {
+                    this.manager.arpHandler.processPacketIn(context, hostService);
+                }
+                break;
+            case NDP:
+                if (this.manager.icmpHandler != null) {
+                    this.manager.icmpHandler.processPacketIn(context, hostService);
+                }
+                break;
+            default:
+                log.warn("Unknown protocol", context.protocol());
+        }
+    }
+
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingNeighbourHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingNeighbourHandler.java
new file mode 100644
index 0000000..f03e0be
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingNeighbourHandler.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.neighbour.NeighbourMessageContext;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * This handler provides provides useful functions to the
+ * neighbour handlers (ARP, NDP).
+ */
+public class SegmentRoutingNeighbourHandler {
+
+    private static Logger log = LoggerFactory.getLogger(SegmentRoutingNeighbourHandler.class);
+
+    protected SegmentRoutingManager srManager;
+    protected DeviceConfiguration config;
+
+    /**
+     * Creates an SegmentRoutingNeighbourHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public SegmentRoutingNeighbourHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.deviceConfiguration);
+    }
+
+    /**
+     * Creates an SegmentRoutingNeighbourHandler object.
+     */
+    public SegmentRoutingNeighbourHandler() {
+        this.srManager = null;
+        this.config = null;
+    }
+
+    /**
+     * Retrieve router (device) info.
+     *
+     * @param mac where to copy the mac
+     * @param ip where to copy the ip
+     * @param deviceId the device id
+     * @param targetAddress the target address
+     * @return true if it was possible to get the necessary info.
+     * False for errors
+     */
+    protected boolean getSenderInfo(byte[] mac,
+                                 byte[] ip,
+                                 DeviceId deviceId,
+                                 IpAddress targetAddress) {
+        byte[] senderMacAddress;
+        byte[] senderIpAddress;
+        IpAddress sender;
+        try {
+            senderMacAddress = config.getDeviceMac(deviceId).toBytes();
+            if (targetAddress.isIp4()) {
+                sender = config.getRouterIpAddressForASubnetHost(targetAddress.getIp4Address());
+            } else {
+                sender = config.getRouterIpAddressForASubnetHost(targetAddress.getIp6Address());
+            }
+            // If sender is null we abort.
+            if (sender == null) {
+                log.warn("Sender ip is null. Aborting getSenderInfo");
+                return false;
+            }
+            senderIpAddress = sender.toOctets();
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting getSenderInfo");
+            return false;
+        }
+        System.arraycopy(senderMacAddress, 0, mac, 0, senderMacAddress.length);
+        System.arraycopy(senderIpAddress, 0, ip, 0, senderIpAddress.length);
+        return true;
+    }
+
+    /**
+     * Utility to send a ND reply using the supplied information.
+     *
+     * @param pkt the request
+     * @param targetMac the target mac
+     * @param hostService the host service
+     */
+    protected void sendResponse(NeighbourMessageContext pkt, MacAddress targetMac, HostService hostService) {
+        HostId dstId = HostId.hostId(pkt.srcMac(), pkt.vlan());
+        Host dst = hostService.getHost(dstId);
+        if (dst == null) {
+            log.warn("Cannot send {} response to host {} - does not exist in the store",
+                     pkt.protocol(), dstId);
+            return;
+        }
+        pkt.reply(targetMac);
+    }
+
+    /**
+     * Flood to all ports in the same subnet.
+     *
+     * @param packet packet to be flooded
+     * @param inPort where the packet comes from
+     * @param targetAddress the target address
+     */
+    protected void flood(Ethernet packet, ConnectPoint inPort, IpAddress targetAddress) {
+        try {
+            srManager.deviceConfiguration
+                    .getSubnetPortsMap(inPort.deviceId()).forEach((subnet, ports) -> {
+                if (subnet.contains(targetAddress)) {
+                    ports.stream()
+                            .filter(port -> port != inPort.port())
+                            .forEach(port -> {
+                                forward(packet, new ConnectPoint(inPort.deviceId(), port));
+                            });
+                }
+            });
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage()
+                             + " Cannot flood in subnet as device config not available"
+                             + " for device: " + inPort.deviceId());
+        }
+    }
+
+    /*
+     * Floods only on the port which have been configured with the subnet
+     * of the target address. The in port is excluded.
+     *
+     * @param pkt the ndp/arp packet and context information
+     */
+    protected void flood(NeighbourMessageContext pkt) {
+        try {
+            srManager.deviceConfiguration
+                    .getSubnetPortsMap(pkt.inPort().deviceId()).forEach((subnet, ports) -> {
+                if (subnet.contains(pkt.target())) {
+                    ports.stream()
+                            .filter(port -> port != pkt.inPort().port())
+                            .forEach(port -> {
+                                ConnectPoint outPoint = new ConnectPoint(
+                                        pkt.inPort().deviceId(),
+                                        port
+                                );
+                                pkt.forward(outPoint);
+                            });
+                }
+            });
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage()
+                             + " Cannot flood in subnet as device config not available"
+                             + " for device: " + pkt.inPort().deviceId());
+        }
+    }
+
+    /**
+     * Packet out to given port.
+     *
+     * Note: In current implementation, we expect all communication with
+     * end hosts within a subnet to be untagged.
+     * <p>
+     * For those pipelines that internally assigns a VLAN, the VLAN tag will be
+     * removed before egress.
+     * <p>
+     * For those pipelines that do not assign internal VLAN, the packet remains
+     * untagged.
+     *
+     * @param packet packet to be forwarded
+     * @param outPort where the packet should be forwarded
+     */
+    private void forward(Ethernet packet, ConnectPoint outPort) {
+        ByteBuffer buf = ByteBuffer.wrap(packet.serialize());
+
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+        tbuilder.setOutput(outPort.port());
+        srManager.packetService.emit(new DefaultOutboundPacket(outPort.deviceId(),
+                                                               tbuilder.build(), buf));
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
new file mode 100644
index 0000000..6f115e4
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2015-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;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.segmentrouting.grouphandler.NextNeighbors;
+import org.onosproject.segmentrouting.pwaas.L2Tunnel;
+import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
+import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
+import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.segmentrouting.storekey.McastStoreKey;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Segment Routing Service for REST API.
+ */
+public interface SegmentRoutingService {
+    /**
+     * VLAN cross-connect priority.
+     */
+    int XCONNECT_PRIORITY = 1000;
+
+    /**
+     * Default flow priority.
+     */
+    int DEFAULT_PRIORITY = 100;
+
+    /**
+     * Minimum IP priority.
+     *
+     * Should &lt; 0 such that priority of /0 will not conflict with lowest
+     * priority default entries.
+     */
+    int MIN_IP_PRIORITY = 10;
+
+    /**
+     * Subnet flooding flow priority.
+     */
+    int FLOOD_PRIORITY = 5;
+
+    /**
+     * Returns all tunnels.
+     *
+     * @return list of tunnels
+     */
+    List<Tunnel> getTunnels();
+
+    /**
+     * Creates a tunnel.
+     *
+     * @param tunnel tunnel reference to create
+     * @return WRONG_PATH if the tunnel path is wrong, ID_EXISTS if the tunnel ID
+     * exists already, TUNNEL_EXISTS if the same tunnel exists, INTERNAL_ERROR
+     * if the tunnel creation failed internally, SUCCESS if the tunnel is created
+     * successfully
+     */
+    TunnelHandler.Result createTunnel(Tunnel tunnel);
+
+    /**
+     * Returns all policies.
+     *
+     * @return list of policy
+     */
+    List<Policy> getPolicies();
+
+    /**
+     * Returns all l2 tunnels of pseudowires.
+     *
+     * @return list of l2 tunnels
+     */
+    List<L2Tunnel> getL2Tunnels();
+
+    /**
+     * Returns all l2 policie of pseudowires.
+     *
+     * @return list of l2 policies.
+     */
+    List<L2TunnelPolicy> getL2Policies();
+
+    /**
+     * Removes pw. Essentially updates configuration for PwaasConfig
+     * and sends event for removal. The rest are handled by DefaultL2TunnelHandler
+     *
+     * @param pwId The pseudowire id
+     * @return SUCCESS if operation successful or a descriptive error otherwise.
+     */
+    L2TunnelHandler.Result removePseudowire(String pwId);
+
+    /**
+     * Adds a Pseudowire to the configuration.
+     *
+     * @param tunnelId The pseudowire id
+     * @param pwLabel Pw label
+     * @param cP1 Connection Point 1 of pw
+     * @param cP1InnerVlan Outer vlan of cp2
+     * @param cP1OuterVlan Outer vlan of cp1
+     * @param cP2 Connection Point 2 of pw
+     * @param cP2InnerVlan Inner vlan of cp2
+     * @param cP2OuterVlan Outer vlan of cp1
+     * @param mode Mode of pw
+     * @param sdTag Service Delimiting tag of pw
+     * @return SUCCESS if operation is successful or a descriptive error otherwise.
+     */
+    L2TunnelHandler.Result addPseudowire(String tunnelId, String pwLabel, String cP1,
+                                          String cP1InnerVlan, String cP1OuterVlan, String cP2,
+                                          String cP2InnerVlan, String cP2OuterVlan,
+                                          String mode, String sdTag);
+
+    /**
+     * Creates a policy.
+     *
+     * @param policy policy reference to create
+     * @return ID_EXISTS if the same policy ID exists,
+     *  POLICY_EXISTS if the same policy exists, TUNNEL_NOT_FOUND if the tunnel
+     *  does not exists, UNSUPPORTED_TYPE if the policy type is not supported,
+     *  SUCCESS if the policy is created successfully.
+     */
+    PolicyHandler.Result createPolicy(Policy policy);
+
+    /**
+     * Removes a tunnel.
+     *
+     * @param tunnel tunnel reference to remove
+     * @return TUNNEL_NOT_FOUND if the tunnel to remove does not exists,
+     * INTERNAL_ERROR if the tunnel creation failed internally, SUCCESS
+     * if the tunnel is created successfully.
+     */
+    TunnelHandler.Result removeTunnel(Tunnel tunnel);
+
+    /**
+     * Removes a policy.
+     *
+     * @param policy policy reference to remove
+     * @return POLICY_NOT_FOUND if the policy to remove does not exists,
+     * SUCCESS if it is removed successfully
+     */
+    PolicyHandler.Result removePolicy(Policy policy);
+
+    /**
+     * Use current state of the network to repopulate forwarding rules.
+     *
+     */
+    void rerouteNetwork();
+
+    /**
+     * Returns device-subnet mapping.
+     *
+     * @return device-subnet mapping
+     */
+    Map<DeviceId, Set<IpPrefix>> getDeviceSubnetMap();
+
+    /**
+     * Returns the current ECMP shortest path graph in this controller instance.
+     *
+     * @return ECMP shortest path graph
+     */
+    ImmutableMap<DeviceId, EcmpShortestPathGraph> getCurrentEcmpSpg();
+
+    /**
+     * Returns the destinatiomSet-NextObjective store contents.
+     *
+     * @return current contents of the destinationSetNextObjectiveStore
+     */
+    ImmutableMap<DestinationSetNextObjectiveStoreKey, NextNeighbors> getDestinationSet();
+
+    /**
+     * Triggers the verification of all ECMP groups in the specified device.
+     * Adjusts the group buckets if verification finds that there are more or less
+     * buckets than what should be there.
+     *
+     * @param id the device identifier
+     */
+    void verifyGroups(DeviceId id);
+
+    /**
+     * Returns the internal link state as seen by this instance of the
+     * controller.
+     *
+     * @return the internal link state
+     */
+    ImmutableMap<Link, Boolean> getSeenLinks();
+
+    /**
+     * Returns the ports administratively disabled by the controller.
+     *
+     * @return a map of devices and port numbers for administratively disabled
+     *         ports. Does not include ports manually disabled by the operator.
+     */
+    ImmutableMap<DeviceId, Set<PortNumber>> getDownedPortState();
+
+   /**
+     * Returns the associated next ids to the mcast groups or to the single
+     * group if mcastIp is present.
+     *
+     * @param mcastIp the group ip
+     * @return the mapping mcastIp-device to next id
+     */
+    Map<McastStoreKey, Integer> getMcastNextIds(IpAddress mcastIp);
+
+    /**
+     * Returns the associated roles to the mcast groups or to the single
+     * group if mcastIp is present.
+     *
+     * @param mcastIp the group ip
+     * @return the mapping mcastIp-device to mcast role
+     */
+    Map<McastStoreKey, McastHandler.McastRole> getMcastRoles(IpAddress mcastIp);
+
+    /**
+     * Returns the associated paths to the mcast group.
+     *
+     * @param mcastIp the group ip
+     * @return the mapping egress point to mcast path
+     */
+    Map<ConnectPoint, List<ConnectPoint>> getMcastPaths(IpAddress mcastIp);
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/Tunnel.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/Tunnel.java
new file mode 100644
index 0000000..470662f
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/Tunnel.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015-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;
+
+import java.util.List;
+
+/**
+ * Tunnel interface.
+ */
+public interface Tunnel {
+
+    /**
+     * Returns the tunnel ID.
+     *
+     * @return tunnel ID
+     */
+    String id();
+
+    /**
+     * Returns Segment IDs for the tunnel including source and destination.
+     *
+     * @return List of Node ID
+     */
+    List<Integer> labelIds();
+
+    /**
+     * Returns the group ID for the tunnel.
+     *
+     * @return group ID
+     */
+    int groupId();
+
+    /**
+     * Sets group ID for the tunnel.
+     *
+     * @param groupId group identifier
+     */
+    void setGroupId(int groupId);
+
+    /**
+     * Sets the flag to allow to remove the group or not.
+     *
+     * @param ok the flag; true - allow to remove
+     */
+    void allowToRemoveGroup(boolean ok);
+
+    /**
+     * Checks if it is allowed to remove the group for the tunnel.
+     *
+     * @return true if allowed, false otherwise
+     */
+    boolean isAllowedToRemoveGroup();
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java
new file mode 100644
index 0000000..e18b920
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2015-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;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
+import org.onosproject.segmentrouting.grouphandler.DestinationSet;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Tunnel Handler.
+ */
+public class TunnelHandler {
+    protected final Logger log = getLogger(getClass());
+
+    private final DeviceConfiguration config;
+    private final EventuallyConsistentMap<String, Tunnel> tunnelStore;
+    private Map<DeviceId, DefaultGroupHandler> groupHandlerMap;
+    private LinkService linkService;
+
+    /**
+     * Result of tunnel creation or removal.
+     */
+    public enum Result {
+        /**
+         * Success.
+         */
+        SUCCESS,
+
+        /**
+         * More than one router needs to specified to created a tunnel.
+         */
+        WRONG_PATH,
+
+        /**
+         * The same tunnel exists already.
+         */
+        TUNNEL_EXISTS,
+
+        /**
+         * The same tunnel ID exists already.
+         */
+        ID_EXISTS,
+
+        /**
+         * Tunnel not found.
+         */
+        TUNNEL_NOT_FOUND,
+
+        /**
+         * Cannot remove the tunnel used by a policy.
+         */
+        TUNNEL_IN_USE,
+
+        /**
+         * Failed to create/remove groups for the tunnel.
+         */
+        INTERNAL_ERROR
+    }
+
+    /**
+     * Constructs tunnel handler.
+     *
+     * @param linkService link service
+     * @param deviceConfiguration device configuration
+     * @param groupHandlerMap group handler map
+     * @param tunnelStore tunnel store
+     */
+    public TunnelHandler(LinkService linkService,
+                         DeviceConfiguration deviceConfiguration,
+                         Map<DeviceId, DefaultGroupHandler> groupHandlerMap,
+                         EventuallyConsistentMap<String, Tunnel> tunnelStore) {
+        this.linkService = linkService;
+        this.config = deviceConfiguration;
+        this.groupHandlerMap = groupHandlerMap;
+        this.tunnelStore = tunnelStore;
+    }
+
+    /**
+     * Creates a tunnel.
+     *
+     * @param tunnel tunnel reference to create a tunnel
+     * @return WRONG_PATH if the tunnel path is wrong, ID_EXISTS if the tunnel ID
+     * exists already, TUNNEL_EXISTS if the same tunnel exists, INTERNAL_ERROR
+     * if the tunnel creation failed internally, SUCCESS if the tunnel is created
+     * successfully
+     */
+    public Result createTunnel(Tunnel tunnel) {
+
+        if (tunnel.labelIds().isEmpty() || tunnel.labelIds().size() < 3) {
+            log.error("More than one router needs to specified to created a tunnel");
+            return Result.WRONG_PATH;
+        }
+
+        if (tunnelStore.containsKey(tunnel.id())) {
+            log.warn("The same tunnel ID exists already");
+            return Result.ID_EXISTS;
+        }
+
+        if (tunnelStore.containsValue(tunnel)) {
+            log.warn("The same tunnel exists already");
+            return Result.TUNNEL_EXISTS;
+        }
+
+        int groupId = createGroupsForTunnel(tunnel);
+        if (groupId < 0) {
+            log.error("Failed to create groups for the tunnel");
+            return Result.INTERNAL_ERROR;
+        }
+
+        tunnel.setGroupId(groupId);
+        tunnelStore.put(tunnel.id(), tunnel);
+
+        return Result.SUCCESS;
+    }
+
+    /**
+     * Removes the tunnel with the tunnel ID given.
+     *
+     * @param tunnelInfo tunnel information to delete tunnels
+     * @return TUNNEL_NOT_FOUND if the tunnel to remove does not exists,
+     * INTERNAL_ERROR if the tunnel creation failed internally, SUCCESS
+     * if the tunnel is created successfully.
+     */
+    public Result removeTunnel(Tunnel tunnelInfo) {
+
+        Tunnel tunnel = tunnelStore.get(tunnelInfo.id());
+        if (tunnel != null) {
+            DeviceId deviceId = config.getDeviceId(tunnel.labelIds().get(0));
+            if (tunnel.isAllowedToRemoveGroup()) {
+                if (groupHandlerMap.get(deviceId).removeGroup(tunnel.groupId())) {
+                    tunnelStore.remove(tunnel.id());
+                } else {
+                    log.error("Failed to remove the tunnel {}", tunnelInfo.id());
+                    return Result.INTERNAL_ERROR;
+                }
+            } else {
+                log.debug("The group is not removed because it is being used.");
+                tunnelStore.remove(tunnel.id());
+            }
+        } else {
+            log.error("No tunnel found for tunnel ID {}", tunnelInfo.id());
+            return Result.TUNNEL_NOT_FOUND;
+        }
+
+        return Result.SUCCESS;
+    }
+
+    /**
+     * Returns the tunnel with the tunnel ID given.
+     *
+     * @param tid Tunnel ID
+     * @return Tunnel reference
+     */
+    public Tunnel getTunnel(String tid) {
+        return tunnelStore.get(tid);
+    }
+
+    /**
+     * Returns all tunnels.
+     *
+     * @return list of Tunnels
+     */
+    public List<Tunnel> getTunnels() {
+        List<Tunnel> tunnels = new ArrayList<>();
+        tunnelStore.values().forEach(tunnel -> tunnels.add(
+                new DefaultTunnel((DefaultTunnel) tunnel)));
+
+        return tunnels;
+    }
+
+    private int createGroupsForTunnel(Tunnel tunnel) {
+
+        Set<Integer> portNumbers;
+        final int groupError = -1;
+
+        DeviceId deviceId = config.getDeviceId(tunnel.labelIds().get(0));
+        if (deviceId == null) {
+            log.warn("No device found for SID {}", tunnel.labelIds().get(0));
+            return groupError;
+        } else if (groupHandlerMap.get(deviceId) == null) {
+            log.warn("group handler not found for {}", deviceId);
+            return groupError;
+        }
+        Set<DeviceId> deviceIds = new HashSet<>();
+        int sid = tunnel.labelIds().get(1);
+        if (config.isAdjacencySid(deviceId, sid)) {
+            portNumbers = config.getPortsForAdjacencySid(deviceId, sid);
+            for (Link link: linkService.getDeviceEgressLinks(deviceId)) {
+                for (Integer port: portNumbers) {
+                    if (link.src().port().toLong() == port) {
+                        deviceIds.add(link.dst().deviceId());
+                    }
+                }
+            }
+        } else {
+            deviceIds.add(config.getDeviceId(sid));
+        }
+        // For these NeighborSet isMpls is meaningless.
+        DestinationSet ns = new DestinationSet(false,
+                                         tunnel.labelIds().get(2),
+                                         DeviceId.NONE);
+
+        // If the tunnel reuses any existing groups, then tunnel handler
+        // should not remove the group.
+        if (groupHandlerMap.get(deviceId).hasNextObjectiveId(ns)) {
+            tunnel.allowToRemoveGroup(false);
+        } else {
+            tunnel.allowToRemoveGroup(true);
+        }
+
+        return groupHandlerMap.get(deviceId).getNextObjectiveId(ns, null, null, true);
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/TunnelPolicy.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/TunnelPolicy.java
new file mode 100644
index 0000000..5df82af
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/TunnelPolicy.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2015-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;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Tunnel Policy.
+ */
+public final class TunnelPolicy implements Policy {
+
+    private final Type type;
+    private final String id;
+    private final int priority;
+    private final String tunnelId;
+    private String dstIp;
+    private String srcIp;
+    private String ipProto;
+    private short srcPort;
+    private short dstPort;
+
+    private TunnelPolicy(String policyId, Type type, int priority, String tunnelId, String srcIp,
+                         String dstIp, String ipProto, short srcPort, short dstPort) {
+        this.id = checkNotNull(policyId);
+        this.type = type;
+        this.tunnelId = tunnelId;
+        this.priority = priority;
+        this.dstIp = dstIp;
+        this.srcIp = srcIp;
+        this.ipProto = ipProto;
+        this.srcPort = srcPort;
+        this.dstPort = dstPort;
+
+    }
+
+    /**
+     * Creates a TunnelPolicy reference.
+     *
+     * @param p TunnelPolicy reference
+     */
+    public TunnelPolicy(TunnelPolicy p) {
+        this.id = p.id;
+        this.type = p.type;
+        this.tunnelId = p.tunnelId;
+        this.priority = p.priority;
+        this.srcIp = p.srcIp;
+        this.dstIp = p.dstIp;
+        this.ipProto = p.ipProto;
+        this.srcPort = p.srcPort;
+        this.dstPort = p.dstPort;
+    }
+
+    /**
+     * Returns the TunnelPolicy builder reference.
+     *
+     * @return TunnelPolicy builder
+     */
+    public static TunnelPolicy.Builder builder() {
+        return new Builder();
+    }
+
+    @Override
+    public String id() {
+        return this.id;
+    }
+
+    @Override
+    public int priority() {
+        return priority;
+    }
+
+    @Override
+    public Type type() {
+        return type;
+    }
+
+    @Override
+    public String srcIp() {
+        return srcIp;
+    }
+
+    @Override
+    public String dstIp() {
+        return dstIp;
+    }
+
+    @Override
+    public String ipProto() {
+        return ipProto;
+    }
+
+    @Override
+    public short srcPort() {
+        return srcPort;
+    }
+
+    @Override
+    public short dstPort() {
+        return dstPort;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o instanceof TunnelPolicy) {
+            TunnelPolicy that = (TunnelPolicy) o;
+            // We do not compare the policy ID
+            if (this.type.equals(that.type) &&
+                    this.tunnelId.equals(that.tunnelId) &&
+                    this.priority == that.priority &&
+                    this.srcIp.equals(that.srcIp) &&
+                    this.dstIp.equals(that.dstIp) &&
+                    this.srcPort == that.srcPort &&
+                    this.dstPort == that.dstPort &&
+                    this.ipProto.equals(that.ipProto)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, tunnelId, srcIp, dstIp, ipProto,
+                srcPort, dstPort, priority);
+    }
+
+    /**
+     * Returns the tunnel ID of the policy.
+     *
+     * @return Tunnel ID
+     */
+    public String tunnelId() {
+        return this.tunnelId;
+    }
+
+
+    /**
+     * Tunnel Policy Builder.
+     */
+    public static final class Builder {
+
+        private String id;
+        private Type type;
+        private int priority;
+        private String tunnelId;
+        private String dstIp;
+        private String srcIp;
+        private String ipProto;
+        private short srcPort;
+        private short dstPort;
+
+        /**
+         * Sets the policy Id.
+         *
+         * @param id policy Id
+         * @return Builder object
+         */
+        public Builder setPolicyId(String id) {
+            this.id = id;
+
+            return this;
+        }
+
+        /**
+         * Sets the policy type.
+         *
+         * @param type policy type
+         * @return Builder object
+         */
+        public Builder setType(Type type) {
+            this.type = type;
+
+            return this;
+        }
+
+        /**
+         * Sets the source IP address.
+         *
+         * @param srcIp source IP address
+         * @return Builder object
+         */
+        public Builder setSrcIp(String srcIp) {
+            this.srcIp = srcIp;
+
+            return this;
+        }
+
+        /**
+         * Sets the destination IP address.
+         *
+         * @param dstIp destination IP address
+         * @return Builder object
+         */
+        public Builder setDstIp(String dstIp) {
+            this.dstIp = dstIp;
+
+            return this;
+        }
+
+        /**
+         * Sets the IP protocol.
+         *
+         * @param proto IP protocol
+         * @return Builder object
+         */
+        public Builder setIpProto(String proto) {
+            this.ipProto = proto;
+
+            return this;
+        }
+
+        /**
+         * Sets the source port.
+         *
+         * @param srcPort source port
+         * @return Builder object
+         */
+        public Builder setSrcPort(short srcPort) {
+            this.srcPort = srcPort;
+
+            return this;
+        }
+
+        /**
+         * Sets the destination port.
+         *
+         * @param dstPort destination port
+         * @return Builder object
+         */
+        public Builder setDstPort(short dstPort) {
+            this.dstPort = dstPort;
+
+            return this;
+        }
+
+        /**
+         * Sets the priority of the policy.
+         *
+         * @param p priority
+         * @return Builder object
+         */
+        public Builder setPriority(int p) {
+            this.priority = p;
+
+            return this;
+        }
+
+        /**
+         * Sets the tunnel Id.
+         *
+         * @param tunnelId tunnel Id
+         * @return Builder object
+         */
+        public Builder setTunnelId(String tunnelId) {
+            this.tunnelId = tunnelId;
+
+            return this;
+        }
+
+        /**
+         * Builds the policy.
+         *
+         * @return Tunnel Policy reference
+         */
+        public Policy build() {
+            return new TunnelPolicy(id, type, priority, tunnelId, srcIp, dstIp,
+                    ipProto, srcPort, dstPort);
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/XConnectHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/XConnectHandler.java
new file mode 100644
index 0000000..aa60684
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/XConnectHandler.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.MacAddress;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.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.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.segmentrouting.config.XConnectConfig;
+import org.onosproject.segmentrouting.storekey.XConnectStoreKey;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+/**
+ * Handles cross connect related events.
+ */
+public class XConnectHandler {
+    private static final Logger log = LoggerFactory.getLogger(XConnectHandler.class);
+    private static final String CONFIG_NOT_FOUND = "XConnect config not found";
+    private static final String NOT_MASTER = "Not master controller";
+    private final SegmentRoutingManager srManager;
+    private final StorageService storageService;
+    private final ConsistentMap<XConnectStoreKey, NextObjective> xConnectNextObjStore;
+    private final KryoNamespace.Builder xConnectKryo;
+
+    protected XConnectHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.storageService = srManager.storageService;
+        xConnectKryo = new KryoNamespace.Builder()
+                .register(KryoNamespaces.API)
+                .register(XConnectStoreKey.class)
+                .register(NextObjContext.class);
+        xConnectNextObjStore = storageService
+                .<XConnectStoreKey, NextObjective>consistentMapBuilder()
+                .withName("onos-xconnect-nextobj-store")
+                .withSerializer(Serializer.using(xConnectKryo.build()))
+                .build();
+    }
+
+    /**
+     * Read initial XConnect for given device.
+     *
+     * @param deviceId ID of the device to be initialized
+     */
+    public void init(DeviceId deviceId) {
+        // Try to read XConnect config
+        XConnectConfig config =
+                srManager.cfgService.getConfig(srManager.appId, XConnectConfig.class);
+        if (config == null) {
+            log.info("Skip XConnect initialization: {}", CONFIG_NOT_FOUND);
+            return;
+        }
+
+        config.getXconnects(deviceId).forEach(key -> {
+            populateXConnect(key, config.getPorts(key));
+        });
+    }
+
+    /**
+     * Processes Segment Routing App Config added event.
+     *
+     * @param event network config added event
+     */
+    protected void processXConnectConfigAdded(NetworkConfigEvent event) {
+        log.info("Processing XConnect CONFIG_ADDED");
+        XConnectConfig config = (XConnectConfig) event.config().get();
+        config.getXconnects().forEach(key -> {
+            populateXConnect(key, config.getPorts(key));
+        });
+    }
+
+    /**
+     * Processes Segment Routing App Config updated event.
+     *
+     * @param event network config updated event
+     */
+    protected void processXConnectConfigUpdated(NetworkConfigEvent event) {
+        log.info("Processing XConnect CONFIG_UPDATED");
+        XConnectConfig prevConfig = (XConnectConfig) event.prevConfig().get();
+        XConnectConfig config = (XConnectConfig) event.config().get();
+        Set<XConnectStoreKey> prevKeys = prevConfig.getXconnects();
+        Set<XConnectStoreKey> keys = config.getXconnects();
+
+        Set<XConnectStoreKey> pendingRemove = prevKeys.stream()
+                .filter(key -> !keys.contains(key)).collect(Collectors.toSet());
+        Set<XConnectStoreKey> pendingAdd = keys.stream()
+                .filter(key -> !prevKeys.contains(key)).collect(Collectors.toSet());
+        Set<XConnectStoreKey> pendingUpdate = keys.stream()
+                .filter(key -> prevKeys.contains(key) &&
+                        !config.getPorts(key).equals(prevConfig.getPorts(key)))
+                .collect(Collectors.toSet());
+
+        pendingRemove.forEach(key -> {
+            revokeXConnect(key, prevConfig.getPorts(key));
+        });
+        pendingAdd.forEach(key -> {
+            populateXConnect(key, config.getPorts(key));
+        });
+        pendingUpdate.forEach(key -> {
+            updateXConnect(key, prevConfig.getPorts(key), config.getPorts(key));
+        });
+    }
+
+    /**
+     * Processes Segment Routing App Config removed event.
+     *
+     * @param event network config removed event
+     */
+    protected void processXConnectConfigRemoved(NetworkConfigEvent event) {
+        log.info("Processing XConnect CONFIG_REMOVED");
+        XConnectConfig prevConfig = (XConnectConfig) event.prevConfig().get();
+        prevConfig.getXconnects().forEach(key -> {
+            revokeXConnect(key, prevConfig.getPorts(key));
+        });
+    }
+
+    /**
+     * Checks if there is any XConnect configured on given connect point.
+     *
+     * @param cp connect point
+     * @return true if there is XConnect configured on given connect point.
+     */
+    public boolean hasXConnect(ConnectPoint cp) {
+        // Try to read XConnect config
+        XConnectConfig config =
+                srManager.cfgService.getConfig(srManager.appId, XConnectConfig.class);
+        if (config == null) {
+            log.warn("Failed to read XConnect config: {}", CONFIG_NOT_FOUND);
+            return false;
+        }
+        return config.getXconnects(cp.deviceId()).stream()
+                .anyMatch(key -> config.getPorts(key).contains(cp.port()));
+    }
+
+    /**
+     * Populates XConnect groups and flows for given key.
+     *
+     * @param key XConnect key
+     * @param ports a set of ports to be cross-connected
+     */
+    private void populateXConnect(XConnectStoreKey key, Set<PortNumber> ports) {
+        if (!srManager.mastershipService.isLocalMaster(key.deviceId())) {
+            log.info("Abort populating XConnect {}: {}", key, NOT_MASTER);
+            return;
+        }
+        populateFilter(key, ports);
+        populateFwd(key, populateNext(key, ports));
+    }
+
+    /**
+     * Populates filtering objectives for given XConnect.
+     *
+     * @param key XConnect store key
+     * @param ports XConnect ports
+     */
+    private void populateFilter(XConnectStoreKey key, Set<PortNumber> ports) {
+        ports.forEach(port -> {
+            FilteringObjective.Builder filtObjBuilder = filterObjBuilder(key, port);
+            ObjectiveContext context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("XConnect FilterObj for {} on port {} populated",
+                            key, port),
+                    (objective, error) ->
+                            log.warn("Failed to populate XConnect FilterObj for {} on port {}: {}",
+                                    key, port, error));
+            srManager.flowObjectiveService.filter(key.deviceId(), filtObjBuilder.add(context));
+        });
+    }
+
+    /**
+     * Populates next objectives for given XConnect.
+     *
+     * @param key XConnect store key
+     * @param ports XConnect ports
+     */
+    private NextObjective populateNext(XConnectStoreKey key, Set<PortNumber> ports) {
+        NextObjective nextObj = null;
+        if (xConnectNextObjStore.containsKey(key)) {
+            nextObj = xConnectNextObjStore.get(key).value();
+            log.debug("NextObj for {} found, id={}", key, nextObj.id());
+        } else {
+            NextObjective.Builder nextObjBuilder = nextObjBuilder(key, ports);
+            ObjectiveContext nextContext = new NextObjContext(Objective.Operation.ADD, key);
+            nextObj = nextObjBuilder.add(nextContext);
+            srManager.flowObjectiveService.next(key.deviceId(), nextObj);
+            xConnectNextObjStore.put(key, nextObj);
+            log.debug("NextObj for {} not found. Creating new NextObj with id={}", key, nextObj.id());
+        }
+        return nextObj;
+    }
+
+    /**
+     * Populates forwarding objectives for given XConnect.
+     *
+     * @param key XConnect store key
+     * @param nextObj next objective
+     */
+    private void populateFwd(XConnectStoreKey key, NextObjective nextObj) {
+        ForwardingObjective.Builder fwdObjBuilder = fwdObjBuilder(key, nextObj.id());
+        ObjectiveContext fwdContext = new DefaultObjectiveContext(
+                (objective) -> log.debug("XConnect FwdObj for {} populated", key),
+                (objective, error) ->
+                        log.warn("Failed to populate XConnect FwdObj for {}: {}", key, error));
+        srManager.flowObjectiveService.forward(key.deviceId(), fwdObjBuilder.add(fwdContext));
+    }
+
+    /**
+     * Revokes XConnect groups and flows for given key.
+     *
+     * @param key XConnect key
+     * @param ports XConnect ports
+     */
+    private void revokeXConnect(XConnectStoreKey key, Set<PortNumber> ports) {
+        if (!srManager.mastershipService.isLocalMaster(key.deviceId())) {
+            log.info("Abort populating XConnect {}: {}", key, NOT_MASTER);
+            return;
+        }
+
+        revokeFilter(key, ports);
+        if (xConnectNextObjStore.containsKey(key)) {
+            NextObjective nextObj = xConnectNextObjStore.get(key).value();
+            revokeFwd(key, nextObj, null);
+            revokeNext(key, nextObj, null);
+        } else {
+            log.warn("NextObj for {} does not exist in the store.", key);
+        }
+    }
+
+    /**
+     * Revokes filtering objectives for given XConnect.
+     *
+     * @param key XConnect store key
+     * @param ports XConnect ports
+     */
+    private void revokeFilter(XConnectStoreKey key, Set<PortNumber> ports) {
+        ports.forEach(port -> {
+            FilteringObjective.Builder filtObjBuilder = filterObjBuilder(key, port);
+            ObjectiveContext context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("XConnect FilterObj for {} on port {} revoked",
+                            key, port),
+                    (objective, error) ->
+                            log.warn("Failed to revoke XConnect FilterObj for {} on port {}: {}",
+                                    key, port, error));
+            srManager.flowObjectiveService.filter(key.deviceId(), filtObjBuilder.remove(context));
+        });
+    }
+
+    /**
+     * Revokes next objectives for given XConnect.
+     *
+     * @param key XConnect store key
+     * @param nextObj next objective
+     * @param nextFuture completable future for this next objective operation
+     */
+    private void revokeNext(XConnectStoreKey key, NextObjective nextObj,
+            CompletableFuture<ObjectiveError> nextFuture) {
+        ObjectiveContext context = new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.debug("Previous NextObj for {} removed", key);
+                if (nextFuture != null) {
+                    nextFuture.complete(null);
+                }
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.warn("Failed to remove previous NextObj for {}: {}", key, error);
+                if (nextFuture != null) {
+                    nextFuture.complete(error);
+                }
+            }
+        };
+        srManager.flowObjectiveService.next(key.deviceId(),
+                (NextObjective) nextObj.copy().remove(context));
+        xConnectNextObjStore.remove(key);
+    }
+
+    /**
+     * Revokes forwarding objectives for given XConnect.
+     *
+     * @param key XConnect store key
+     * @param nextObj next objective
+     * @param fwdFuture completable future for this forwarding objective operation
+     */
+    private void revokeFwd(XConnectStoreKey key, NextObjective nextObj,
+            CompletableFuture<ObjectiveError> fwdFuture) {
+        ForwardingObjective.Builder fwdObjBuilder = fwdObjBuilder(key, nextObj.id());
+        ObjectiveContext context = new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.debug("Previous FwdObj for {} removed", key);
+                if (fwdFuture != null) {
+                    fwdFuture.complete(null);
+                }
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.warn("Failed to remove previous FwdObj for {}: {}", key, error);
+                if (fwdFuture != null) {
+                    fwdFuture.complete(error);
+                }
+            }
+        };
+        srManager.flowObjectiveService
+                .forward(key.deviceId(), fwdObjBuilder.remove(context));
+    }
+
+    /**
+     * Updates XConnect groups and flows for given key.
+     *
+     * @param key XConnect key
+     * @param prevPorts previous XConnect ports
+     * @param ports new XConnect ports
+     */
+    private void updateXConnect(XConnectStoreKey key, Set<PortNumber> prevPorts,
+            Set<PortNumber> ports) {
+        // remove old filter
+        prevPorts.stream().filter(port -> !ports.contains(port)).forEach(port -> {
+            revokeFilter(key, ImmutableSet.of(port));
+        });
+        // install new filter
+        ports.stream().filter(port -> !prevPorts.contains(port)).forEach(port -> {
+            populateFilter(key, ImmutableSet.of(port));
+        });
+
+        CompletableFuture<ObjectiveError> fwdFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> nextFuture = new CompletableFuture<>();
+
+        if (xConnectNextObjStore.containsKey(key)) {
+            NextObjective nextObj = xConnectNextObjStore.get(key).value();
+            revokeFwd(key, nextObj, fwdFuture);
+
+            fwdFuture.thenAcceptAsync(fwdStatus -> {
+                if (fwdStatus == null) {
+                    log.debug("Fwd removed. Now remove group {}", key);
+                    revokeNext(key, nextObj, nextFuture);
+                }
+            });
+
+            nextFuture.thenAcceptAsync(nextStatus -> {
+                if (nextStatus == null) {
+                    log.debug("Installing new group and flow for {}", key);
+                    populateFwd(key, populateNext(key, ports));
+                }
+            });
+        } else {
+            log.warn("NextObj for {} does not exist in the store.", key);
+        }
+    }
+
+    /**
+     * Remove all groups on given device.
+     *
+     * @param deviceId device ID
+     */
+    protected void removeDevice(DeviceId deviceId) {
+        xConnectNextObjStore.entrySet().stream()
+                .filter(entry -> entry.getKey().deviceId().equals(deviceId))
+                .forEach(entry -> {
+                    xConnectNextObjStore.remove(entry.getKey());
+                });
+        log.debug("{} is removed from xConnectNextObjStore", deviceId);
+    }
+
+    /**
+     * Creates a next objective builder for XConnect.
+     *
+     * @param key XConnect key
+     * @param ports set of XConnect ports
+     * @return next objective builder
+     */
+    private NextObjective.Builder nextObjBuilder(XConnectStoreKey key, Set<PortNumber> ports) {
+        int nextId = srManager.flowObjectiveService.allocateNextId();
+        TrafficSelector metadata =
+                DefaultTrafficSelector.builder().matchVlanId(key.vlanId()).build();
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder().withId(nextId)
+                .withType(NextObjective.Type.BROADCAST).fromApp(srManager.appId)
+                .withMeta(metadata);
+        ports.forEach(port -> {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(port);
+            nextObjBuilder.addTreatment(tBuilder.build());
+        });
+        return nextObjBuilder;
+    }
+
+    /**
+     * Creates a forwarding objective builder for XConnect.
+     *
+     * @param key XConnect key
+     * @param nextId next ID of the broadcast group for this XConnect key
+     * @return next objective builder
+     */
+    private ForwardingObjective.Builder fwdObjBuilder(XConnectStoreKey key, int nextId) {
+        /*
+         * Driver should treat objectives with MacAddress.NONE and !VlanId.NONE
+         * as the VLAN cross-connect broadcast rules
+         */
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        sbuilder.matchVlanId(key.vlanId());
+        sbuilder.matchEthDst(MacAddress.NONE);
+
+        ForwardingObjective.Builder fob = DefaultForwardingObjective.builder();
+        fob.withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .withSelector(sbuilder.build())
+                .nextStep(nextId)
+                .withPriority(SegmentRoutingService.XCONNECT_PRIORITY)
+                .fromApp(srManager.appId)
+                .makePermanent();
+        return fob;
+    }
+
+    /**
+     * Creates a filtering objective builder for XConnect.
+     *
+     * @param key XConnect key
+     * @param port XConnect ports
+     * @return next objective builder
+     */
+    private FilteringObjective.Builder filterObjBuilder(XConnectStoreKey key, PortNumber port) {
+        FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
+        fob.withKey(Criteria.matchInPort(port))
+                .addCondition(Criteria.matchVlanId(key.vlanId()))
+                .addCondition(Criteria.matchEthDst(MacAddress.NONE))
+                .withPriority(SegmentRoutingService.XCONNECT_PRIORITY);
+        return fob.permit().fromApp(srManager.appId);
+    }
+
+    // TODO: Lambda closure in DefaultObjectiveContext cannot be serialized properly
+    //       with Kryo 3.0.3. It will be fixed in 3.0.4. By then we can use
+    //       DefaultObjectiveContext again.
+    private final class NextObjContext implements ObjectiveContext {
+        Objective.Operation op;
+        XConnectStoreKey key;
+
+        private NextObjContext(Objective.Operation op, XConnectStoreKey key) {
+            this.op = op;
+            this.key = key;
+        }
+
+        @Override
+        public void onSuccess(Objective objective) {
+            log.debug("XConnect NextObj for {} {}ED", key, op);
+        }
+
+        @Override
+        public void onError(Objective objective, ObjectiveError error) {
+            log.warn("Failed to {} XConnect NextObj for {}: {}", op, key, error);
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/DeviceSubnetListCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/DeviceSubnetListCommand.java
new file mode 100644
index 0000000..a364b6e
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/DeviceSubnetListCommand.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Command to list device-subnet mapping in Segment Routing.
+ */
+@Command(scope = "onos", name = "sr-device-subnets",
+        description = "List device-subnet mapping in Segment Routing")
+public class DeviceSubnetListCommand extends AbstractShellCommand {
+    @Override
+    protected void execute() {
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+        printDeviceSubnetMap(srService.getDeviceSubnetMap());
+    }
+
+    private void printDeviceSubnetMap(Map<DeviceId, Set<IpPrefix>> deviceSubnetMap) {
+        deviceSubnetMap.forEach(((deviceId, ipPrefices) -> {
+            print("%s", deviceId);
+            ipPrefices.forEach(ipPrefix -> print("    %s", ipPrefix));
+        }));
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/EcmpGraphCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/EcmpGraphCommand.java
new file mode 100644
index 0000000..678114a
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/EcmpGraphCommand.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.cli;
+
+
+import java.util.Map;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.onosproject.segmentrouting.EcmpShortestPathGraph;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+
+/**
+ * Command to read the current state of the ECMP shortest-path graph.
+ *
+ */
+@Command(scope = "onos", name = "sr-ecmp-spg",
+        description = "Displays the current ecmp shortest-path-graph in this "
+                + "controller instance")
+public class EcmpGraphCommand extends AbstractShellCommand {
+
+    private static final String FORMAT_MAPPING = "  %s";
+
+    @Override
+    protected void execute() {
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+        printEcmpGraph(srService.getCurrentEcmpSpg());
+    }
+
+    private void printEcmpGraph(Map<DeviceId, EcmpShortestPathGraph> currentEcmpSpg) {
+        if (currentEcmpSpg == null) {
+            print(FORMAT_MAPPING, "No ECMP graph found");
+            return;
+        }
+        StringBuilder ecmp = new StringBuilder();
+        currentEcmpSpg.forEach((key, value) -> {
+            ecmp.append("\n\nRoot Device: " + key + " ECMP Paths: " + value);
+        });
+        print(FORMAT_MAPPING, ecmp.toString());
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/LinkStateCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/LinkStateCommand.java
new file mode 100644
index 0000000..ded4ae6
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/LinkStateCommand.java
@@ -0,0 +1,92 @@
+/*
+ * 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.cli;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+
+/**
+ * Command to read the current state of the DestinationSetNextObjectiveStore.
+ *
+ */
+@Command(scope = "onos", name = "sr-link-state", description = "Displays the current internal link state "
+        + "noted by this instance of the controller")
+public class LinkStateCommand extends AbstractShellCommand {
+    private static final String FORMAT_MAPPING = "  %s";
+
+    @Override
+    protected void execute() {
+        SegmentRoutingService srService = AbstractShellCommand
+                .get(SegmentRoutingService.class);
+        printLinkState(srService.getSeenLinks(),
+                       srService.getDownedPortState());
+    }
+
+    private void printLinkState(ImmutableMap<Link, Boolean> seenLinks,
+                                ImmutableMap<DeviceId, Set<PortNumber>> downedPortState) {
+        List<Link> a = Lists.newArrayList();
+        a.addAll(seenLinks.keySet());
+        a.sort(new CompLinks());
+
+        StringBuilder slbldr = new StringBuilder();
+        slbldr.append("\n Seen Links: ");
+        for (int i = 0; i < a.size(); i++) {
+            slbldr.append("\n "
+                    + (seenLinks.get(a.get(i)) == Boolean.TRUE ? "  up : "
+                                                               : "down : "));
+            slbldr.append(a.get(i).src() + " --> " + a.get(i).dst());
+        }
+        print(FORMAT_MAPPING, slbldr.toString());
+
+        StringBuilder dpbldr = new StringBuilder();
+        dpbldr.append("\n\n Administratively Disabled Ports: ");
+        downedPortState.entrySet().forEach(entry -> dpbldr
+                .append("\n " + entry.getKey() + entry.getValue()));
+        print(FORMAT_MAPPING, dpbldr.toString());
+    }
+
+    static class CompLinks implements Comparator<Link> {
+
+        @Override
+        public int compare(Link o1, Link o2) {
+            int res = o1.src().deviceId().toString()
+                    .compareTo(o2.src().deviceId().toString());
+            if (res < 0) {
+                return -1;
+            } else if (res > 0) {
+                return +1;
+            }
+            if (o1.src().port().toLong() < o2.src().port().toLong()) {
+                return -1;
+            }
+            return +1;
+        }
+
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/McastNextListCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/McastNextListCommand.java
new file mode 100644
index 0000000..341c87d
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/McastNextListCommand.java
@@ -0,0 +1,81 @@
+/*
+ * 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.cli;
+
+import com.google.common.collect.Maps;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.packet.IpAddress;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.storekey.McastStoreKey;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+
+/**
+ * Command to show the list of mcast nextids.
+ */
+@Command(scope = "onos", name = "sr-mcast-next",
+        description = "Lists all mcast nextids")
+public class McastNextListCommand extends AbstractShellCommand {
+
+    // Format for group line
+    private static final String FORMAT_MAPPING = "group=%s, deviceIds-nextIds=%s";
+
+    @Argument(index = 0, name = "mcastIp", description = "mcast Ip",
+            required = false, multiValued = false)
+    String mcastIp;
+
+    @Override
+    protected void execute() {
+        // Verify mcast group
+        IpAddress mcastGroup = null;
+        if (!isNullOrEmpty(mcastIp)) {
+            mcastGroup = IpAddress.valueOf(mcastIp);
+
+        }
+        // Get SR service
+        SegmentRoutingService srService = get(SegmentRoutingService.class);
+        // Get the mapping
+        Map<McastStoreKey, Integer> keyToNextId = srService.getMcastNextIds(mcastGroup);
+        // Reduce to the set of mcast groups
+        Set<IpAddress> mcastGroups = keyToNextId.keySet().stream()
+                .map(McastStoreKey::mcastIp)
+                .collect(Collectors.toSet());
+        // Print the nextids for each group
+        mcastGroups.forEach(group -> {
+            // Create a new map for the group
+            Map<DeviceId, Integer> deviceIdNextMap = Maps.newHashMap();
+            keyToNextId.entrySet()
+                    .stream()
+                    // Filter only the elements related to this group
+                    .filter(entry -> entry.getKey().mcastIp().equals(group))
+                    // For each create a new entry in the group related map
+                    .forEach(entry -> deviceIdNextMap.put(entry.getKey().deviceId(), entry.getValue()));
+            // Print the map
+            printMcastNext(group, deviceIdNextMap);
+        });
+    }
+
+    private void printMcastNext(IpAddress mcastGroup, Map<DeviceId, Integer> deviceIdNextMap) {
+        print(FORMAT_MAPPING, mcastGroup, deviceIdNextMap);
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/McastTreeListCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/McastTreeListCommand.java
new file mode 100644
index 0000000..73cbb1a
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/McastTreeListCommand.java
@@ -0,0 +1,107 @@
+/*
+ * 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.cli;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.packet.IpAddress;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.segmentrouting.McastHandler.McastRole;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.storekey.McastStoreKey;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.onosproject.segmentrouting.McastHandler.McastRole.EGRESS;
+import static org.onosproject.segmentrouting.McastHandler.McastRole.INGRESS;
+import static org.onosproject.segmentrouting.McastHandler.McastRole.TRANSIT;
+
+/**
+ * Command to show the list of mcast trees.
+ */
+@Command(scope = "onos", name = "sr-mcast-tree",
+        description = "Lists all mcast trees")
+public class McastTreeListCommand extends AbstractShellCommand {
+
+    // Format for group line
+    private static final String G_FORMAT_MAPPING = "group=%s, ingress=%s, transit=%s, egress=%s";
+    // Format for sink line
+    private static final String S_FORMAT_MAPPING = "\tsink=%s\tpath=%s";
+
+    @Argument(index = 0, name = "mcastIp", description = "mcast Ip",
+            required = false, multiValued = false)
+    String mcastIp;
+
+    @Override
+    protected void execute() {
+        // Verify mcast group
+        IpAddress mcastGroup = null;
+        if (!isNullOrEmpty(mcastIp)) {
+            mcastGroup = IpAddress.valueOf(mcastIp);
+
+        }
+        // Get SR service
+        SegmentRoutingService srService = get(SegmentRoutingService.class);
+        // Get the mapping
+        Map<McastStoreKey, McastRole> keyToRole = srService.getMcastRoles(mcastGroup);
+        // Reduce to the set of mcast groups
+        Set<IpAddress> mcastGroups = keyToRole.keySet().stream()
+                .map(McastStoreKey::mcastIp)
+                .collect(Collectors.toSet());
+        // Print the trees for each group
+        mcastGroups.forEach(group -> {
+            // Create a new map for the group
+            Multimap<McastRole, DeviceId> roleDeviceIdMap = ArrayListMultimap.create();
+            keyToRole.entrySet()
+                    .stream()
+                    // Filter only the elements related to this group
+                    .filter(entry -> entry.getKey().mcastIp().equals(group))
+                    // For each create a new entry in the group related map
+                    .forEach(entry -> roleDeviceIdMap.put(entry.getValue(), entry.getKey().deviceId()));
+            // Print the map
+            printMcastRole(group,
+                           roleDeviceIdMap.get(INGRESS),
+                           roleDeviceIdMap.get(TRANSIT),
+                           roleDeviceIdMap.get(EGRESS)
+            );
+            // Get sinks paths
+            Map<ConnectPoint, List<ConnectPoint>> mcastPaths = srService.getMcastPaths(group);
+            // Print the paths
+            mcastPaths.forEach(this::printMcastSink);
+        });
+    }
+
+    private void printMcastRole(IpAddress mcastGroup,
+                                Collection<DeviceId> ingress,
+                                Collection<DeviceId> transit,
+                                Collection<DeviceId> egress) {
+        print(G_FORMAT_MAPPING, mcastGroup, ingress, transit, egress);
+    }
+
+    private void printMcastSink(ConnectPoint sink, List<ConnectPoint> path) {
+        print(S_FORMAT_MAPPING, sink, path);
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/NextHopCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/NextHopCommand.java
new file mode 100644
index 0000000..2b43de5
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/NextHopCommand.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.cli;
+
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Map;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.grouphandler.NextNeighbors;
+import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;
+
+/**
+ * Command to read the current state of the DestinationSetNextObjectiveStore.
+ *
+ */
+@Command(scope = "onos", name = "sr-next-hops",
+        description = "Displays the current next-hops seen by each switch "
+                + "towards a set of destinations and the next-id it maps to")
+public class NextHopCommand extends AbstractShellCommand {
+
+    private static final String FORMAT_MAPPING = "  %s";
+
+    @Override
+    protected void execute() {
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+        printDestinationSet(srService.getDestinationSet());
+    }
+
+    private void printDestinationSet(Map<DestinationSetNextObjectiveStoreKey,
+                                      NextNeighbors> ds) {
+        ArrayList<DestinationSetNextObjectiveStoreKey> a = new ArrayList<>();
+        ds.keySet().forEach(key -> a.add(key));
+        a.sort(new Comp());
+
+        StringBuilder dsbldr = new StringBuilder();
+        for (int i = 0; i < a.size(); i++) {
+            dsbldr.append("\n " + a.get(i));
+            dsbldr.append(" --> via: " + ds.get(a.get(i)));
+        }
+        print(FORMAT_MAPPING, dsbldr.toString());
+    }
+
+    static class Comp implements Comparator<DestinationSetNextObjectiveStoreKey> {
+
+        @Override
+        public int compare(DestinationSetNextObjectiveStoreKey o1,
+                           DestinationSetNextObjectiveStoreKey o2) {
+            int res = o1.deviceId().toString().compareTo(o2.deviceId().toString());
+            if (res < 0) {
+                return -1;
+            } else if (res > 0) {
+                return +1;
+            }
+            return 0;
+        }
+
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PolicyAddCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PolicyAddCommand.java
new file mode 100644
index 0000000..605ba83
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PolicyAddCommand.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2015-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.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.Policy;
+import org.onosproject.segmentrouting.PolicyHandler;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.TunnelPolicy;
+
+/**
+ * Command to add a new policy.
+ */
+@Command(scope = "onos", name = "sr-policy-add",
+        description = "Create a new policy")
+public class PolicyAddCommand extends AbstractShellCommand {
+
+    // TODO: Need to support skipping some parameters
+
+    @Argument(index = 0, name = "ID",
+            description = "policy ID",
+            required = true, multiValued = false)
+    String policyId;
+
+    @Argument(index = 1, name = "priority",
+            description = "priority",
+            required = true, multiValued = false)
+    int priority;
+
+    @Argument(index = 2, name = "src_IP",
+            description = "src IP",
+            required = false, multiValued = false)
+    String srcIp;
+
+    @Argument(index = 3, name = "src_port",
+            description = "src port",
+            required = false, multiValued = false)
+    short srcPort;
+
+    @Argument(index = 4, name = "dst_IP",
+            description = "dst IP",
+            required = false, multiValued = false)
+    String dstIp;
+
+    @Argument(index = 5, name = "dst_port",
+            description = "dst port",
+            required = false, multiValued = false)
+    short dstPort;
+
+    @Argument(index = 6, name = "proto",
+            description = "IP protocol",
+            required = false, multiValued = false)
+    String proto;
+
+    @Argument(index = 7, name = "policy_type",
+            description = "policy type",
+            required = true, multiValued = false)
+    String policyType;
+
+    @Argument(index = 8, name = "tunnel_ID",
+            description = "tunnel ID",
+            required = false, multiValued = false)
+    String tunnelId;
+
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        TunnelPolicy.Builder tpb = TunnelPolicy.builder().setPolicyId(policyId);
+        tpb.setPriority(priority);
+        tpb.setType(Policy.Type.valueOf(policyType));
+
+        if (srcIp != null) {
+            tpb.setSrcIp(srcIp);
+        }
+        if (dstIp != null) {
+            tpb.setDstIp(dstIp);
+        }
+        if (srcPort != 0) {
+            tpb.setSrcPort(srcPort);
+        }
+        if (dstPort != 0) {
+            tpb.setDstPort(dstPort);
+        }
+        if (!"ip".equals(proto)) {
+            tpb.setIpProto(proto);
+        }
+        if (Policy.Type.valueOf(policyType) == Policy.Type.TUNNEL_FLOW) {
+            if (tunnelId == null) {
+                error("tunnel ID must be specified for TUNNEL_FLOW policy");
+                return;
+            }
+            tpb.setTunnelId(tunnelId);
+        }
+        PolicyHandler.Result result = srService.createPolicy(tpb.build());
+
+        switch (result) {
+            case POLICY_EXISTS:
+                error("the same policy exists");
+                break;
+            case ID_EXISTS:
+                error("the same policy ID exists");
+                break;
+            case TUNNEL_NOT_FOUND:
+                error("the tunnel is not found");
+                break;
+            case UNSUPPORTED_TYPE:
+                error("the policy type specified is not supported");
+                break;
+            default:
+                break;
+        }
+
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PolicyListCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PolicyListCommand.java
new file mode 100644
index 0000000..6c91b8b
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PolicyListCommand.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2015-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.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.Policy;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.TunnelPolicy;
+
+/**
+ * Command to show the list of policies.
+ */
+@Command(scope = "onos", name = "sr-policy-list",
+        description = "Lists all policies")
+public class PolicyListCommand extends AbstractShellCommand {
+
+    private static final String FORMAT_MAPPING_TUNNEL =
+            "  id=%s, type=%s,  prio=%d, src=%s, port=%d, dst=%s, port=%d, proto=%s, tunnel=%s";
+
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        srService.getPolicies().forEach(policy -> printPolicy(policy));
+    }
+
+    private void printPolicy(Policy policy) {
+        if (policy.type() == Policy.Type.TUNNEL_FLOW) {
+            print(FORMAT_MAPPING_TUNNEL, policy.id(), policy.type(), policy.priority(),
+                    policy.srcIp(), policy.srcPort(), policy.dstIp(), policy.dstPort(),
+                    (policy.ipProto() == null) ? "" : policy.ipProto(),
+                    ((TunnelPolicy) policy).tunnelId());
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PolicyRemoveCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PolicyRemoveCommand.java
new file mode 100644
index 0000000..cdc3034
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PolicyRemoveCommand.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2015-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.cli;
+
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.PolicyHandler;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.TunnelPolicy;
+
+/**
+ * Command to remove a policy.
+ */
+@Command(scope = "onos", name = "sr-policy-remove",
+        description = "Remove a policy")
+public class PolicyRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "policy ID",
+            description = "policy ID",
+            required = true, multiValued = false)
+    String policyId;
+
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        TunnelPolicy.Builder tpb = TunnelPolicy.builder().setPolicyId(policyId);
+        PolicyHandler.Result result = srService.removePolicy(tpb.build());
+        if (result == PolicyHandler.Result.POLICY_NOT_FOUND) {
+            print("ERROR: the policy is not found");
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java
new file mode 100644
index 0000000..d916823
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2017-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.cli;
+
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
+
+
+/**
+ * Command to add a pseuwodire.
+ */
+@Command(scope = "onos", name = "pseudowire-add",
+        description = "Add a pseudowire to the network configuration, if it already exists update it.")
+public class PseudowireAddCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "pwId",
+            description = "Pseudowire ID",
+            required = true, multiValued = false)
+    String pwId;
+
+    @Argument(index = 1, name = "pwLabel",
+            description = "Pseudowire Label",
+            required = true, multiValued = false)
+    String pwLabel;
+
+    @Argument(index = 2, name = "mode",
+            description = "Mode used for pseudowire",
+            required = true, multiValued = false)
+    String mode;
+
+    @Argument(index = 3, name = "sDTag",
+            description = "Service delimiting tag",
+            required = true, multiValued = false)
+    String sDTag;
+
+    @Argument(index = 4, name = "cP1",
+            description = "Connection Point 1",
+            required = true, multiValued = false)
+    String cP1;
+
+    @Argument(index = 5, name = "cP1InnerVlan",
+            description = "Inner Vlan of Connection Point 1",
+            required = true, multiValued = false)
+    String cP1InnerVlan;
+
+    @Argument(index = 6, name = "cP1OuterVlan",
+            description = "Outer Vlan of Connection Point 1",
+            required = true, multiValued = false)
+    String cP1OuterVlan;
+
+    @Argument(index = 7, name = "cP2",
+            description = "Connection Point 2",
+            required = true, multiValued = false)
+    String cP2;
+
+    @Argument(index = 8, name = "cP2InnerVlan",
+            description = "Inner Vlan of Connection Point 2",
+            required = true, multiValued = false)
+    String cP2InnerVlan;
+
+    @Argument(index = 9, name = "cP2OuterVlan",
+            description = "Outer Vlan of Connection Point 2",
+            required = true, multiValued = false)
+    String cP2OuterVlan;
+
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        L2TunnelHandler.Result res = srService.addPseudowire(pwId, pwLabel,
+                                                             cP1, cP1InnerVlan, cP1OuterVlan,
+                                                             cP2, cP2InnerVlan, cP2OuterVlan,
+                                                             mode, sDTag);
+        switch (res) {
+            case ADDITION_ERROR:
+                print("Pseudowire could not be added, error in configuration, please check logs for more details!");
+                break;
+            case CONFIG_NOT_FOUND:
+                print("Configuration for pwaas was not found! Initialize the configuration first through netcfg.");
+                break;
+            default:
+                break;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireIdCompleter.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireIdCompleter.java
new file mode 100644
index 0000000..b44ca76
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireIdCompleter.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2014-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.cli;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.pwaas.L2Tunnel;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.stream.Collectors;
+
+/**
+ * Device ID completer.
+ */
+public class PseudowireIdCompleter implements Completer {
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+        // Delegate string completer
+        StringsCompleter delegate = new StringsCompleter();
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+
+        List<L2Tunnel> tunnels = srService.getL2Tunnels();
+
+        // combine polices and tunnels to pseudowires
+        Iterator<String> pseudowires = tunnels.stream()
+                .map(l2Tunnel -> Long.toString(l2Tunnel.tunnelId()))
+                .collect(Collectors.toList()).iterator();
+
+        SortedSet<String> strings = delegate.getStrings();
+        while (pseudowires.hasNext()) {
+            strings.add(pseudowires.next());
+        }
+
+        // Now let the completer do the work for figuring out what to offer.
+        return delegate.complete(buffer, cursor, candidates);
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireListCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireListCommand.java
new file mode 100644
index 0000000..c48f633
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireListCommand.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2017-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.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.packet.VlanId;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
+import org.onosproject.segmentrouting.pwaas.L2Tunnel;
+import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
+import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Command to show the pseudowires.
+ */
+@Command(scope = "onos", name = "pseudowires",
+        description = "Lists all pseudowires")
+public class PseudowireListCommand extends AbstractShellCommand {
+
+    private static final String FORMAT_PSEUDOWIRE =
+            "Pseudowire id = %s \n" +
+                    "   mode : %s, sdTag : %s, pwLabel : %s \n" +
+                    "   cP1 : %s , cP1OuterTag : %s, cP1InnerTag : %s \n" +
+                    "   cP2 : %s , cP2OuterTag : %s, cP2InnerTag : %s \n" +
+                    "   transportVlan : %s";
+
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        List<L2Tunnel> tunnels = srService.getL2Tunnels();
+        List<L2TunnelPolicy> policies = srService.getL2Policies();
+
+        // combine polices and tunnels to pseudowires
+        List<L2TunnelDescription> pseudowires = tunnels.stream()
+                                    .map(l2Tunnel -> {
+                                            L2TunnelPolicy policy = null;
+                                            for (L2TunnelPolicy l2Policy : policies) {
+                                                if (l2Policy.tunnelId() == l2Tunnel.tunnelId()) {
+                                                    policy = l2Policy;
+                                                    break;
+                                                }
+                                            }
+
+                                            return new DefaultL2TunnelDescription(l2Tunnel, policy);
+                                    })
+                                    .collect(Collectors.toList());
+
+        pseudowires.forEach(pw -> printPseudowire(pw));
+    }
+
+    private void printPseudowire(L2TunnelDescription pseudowire) {
+
+
+        VlanId vlan = pseudowire.l2Tunnel().transportVlan().equals(VlanId.vlanId((short) 4094)) ?
+                VlanId.NONE : pseudowire.l2Tunnel().transportVlan();
+
+        print(FORMAT_PSEUDOWIRE, pseudowire.l2Tunnel().tunnelId(), pseudowire.l2Tunnel().pwMode(),
+              pseudowire.l2Tunnel().sdTag(), pseudowire.l2Tunnel().pwLabel(),
+              pseudowire.l2TunnelPolicy().cP1(), pseudowire.l2TunnelPolicy().cP1OuterTag(),
+              pseudowire.l2TunnelPolicy().cP1InnerTag(), pseudowire.l2TunnelPolicy().cP2(),
+              pseudowire.l2TunnelPolicy().cP2OuterTag(), pseudowire.l2TunnelPolicy().cP2InnerTag(),
+              vlan);
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java
new file mode 100644
index 0000000..098bbf9
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017-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.cli;
+
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
+
+
+/**
+ * Command to remove a pseudowire.
+ */
+@Command(scope = "onos", name = "pseudowire-remove",
+        description = "Remove a pseudowire")
+public class PseudowireRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "pwId",
+            description = "pseudowire ID",
+            required = true, multiValued = false)
+    String pwId;
+
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        // remove the pseudowire
+        SegmentRoutingManager mngr = (SegmentRoutingManager) srService;
+        L2TunnelHandler.Result res = mngr.removePseudowire(pwId);
+
+        switch (res) {
+            case REMOVAL_ERROR:
+                error("Error in deletion, pseudowire not found!");
+                break;
+            case CONFIG_NOT_FOUND:
+                error("Could not fetch pseudowire class configuration!");
+                break;
+            default:
+                break;
+            }
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/RerouteNetworkCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/RerouteNetworkCommand.java
new file mode 100644
index 0000000..40525f2
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/RerouteNetworkCommand.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.cli;
+
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+
+/**
+ * Command to manually trigger routing and rule-population in the network.
+ *
+ */
+@Command(scope = "onos", name = "sr-reroute-network",
+        description = "Repopulate routing rules given current network state")
+public class RerouteNetworkCommand extends AbstractShellCommand {
+
+    @Override
+    protected void execute() {
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+        srService.rerouteNetwork();
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/TunnelAddCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/TunnelAddCommand.java
new file mode 100644
index 0000000..6b3e1fc
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/TunnelAddCommand.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2015-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.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.DefaultTunnel;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.Tunnel;
+import org.onosproject.segmentrouting.TunnelHandler;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Command to add a new tunnel.
+ */
+@Command(scope = "onos", name = "sr-tunnel-add",
+        description = "Create a new tunnel")
+public class TunnelAddCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "tunnel ID",
+            description = "tunnel ID",
+            required = true, multiValued = false)
+    String tunnelId;
+
+    @Argument(index = 1, name = "label path",
+            description = "label path",
+            required = true, multiValued = false)
+    String labels;
+
+
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        List<Integer> labelIds = new ArrayList<>();
+        StringTokenizer strToken = new StringTokenizer(labels, ",");
+        while (strToken.hasMoreTokens()) {
+            labelIds.add(Integer.valueOf(strToken.nextToken()));
+        }
+        Tunnel tunnel = new DefaultTunnel(tunnelId, labelIds);
+
+        TunnelHandler.Result result = srService.createTunnel(tunnel);
+        switch (result) {
+            case ID_EXISTS:
+                print("ERROR: the same tunnel ID exists");
+                break;
+            case TUNNEL_EXISTS:
+                print("ERROR: the same tunnel exists");
+                break;
+            case INTERNAL_ERROR:
+                print("ERROR: internal tunnel creation error");
+                break;
+            case WRONG_PATH:
+                print("ERROR: the tunnel path is wrong");
+                break;
+            default:
+                break;
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/TunnelListCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/TunnelListCommand.java
new file mode 100644
index 0000000..7984eb4
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/TunnelListCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2015-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.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.Tunnel;
+
+/**
+ * Command to show the list of tunnels.
+ */
+@Command(scope = "onos", name = "sr-tunnel-list",
+        description = "Lists all tunnels")
+public class TunnelListCommand extends AbstractShellCommand {
+
+    private static final String FORMAT_MAPPING =
+            "  id=%s, path=%s";
+
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        srService.getTunnels().forEach(tunnel -> printTunnel(tunnel));
+    }
+
+    private void printTunnel(Tunnel tunnel) {
+        print(FORMAT_MAPPING, tunnel.id(), tunnel.labelIds());
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/TunnelRemoveCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/TunnelRemoveCommand.java
new file mode 100644
index 0000000..b9a7edb
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/TunnelRemoveCommand.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015-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.cli;
+
+
+import com.google.common.collect.Lists;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.DefaultTunnel;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.Tunnel;
+import org.onosproject.segmentrouting.TunnelHandler;
+
+/**
+ * Command to remove a tunnel.
+ */
+@Command(scope = "onos", name = "sr-tunnel-remove",
+        description = "Remove a tunnel")
+public class TunnelRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "tunnel ID",
+            description = "tunnel ID",
+            required = true, multiValued = false)
+    String tunnelId;
+
+    @Override
+    protected void execute() {
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        Tunnel tunnel = new DefaultTunnel(tunnelId, Lists.newArrayList());
+        TunnelHandler.Result result = srService.removeTunnel(tunnel);
+        switch (result) {
+            case TUNNEL_IN_USE:
+                print("ERROR: the tunnel is still in use");
+                break;
+            case TUNNEL_NOT_FOUND:
+                print("ERROR: the tunnel is not found");
+                break;
+            default:
+                break;
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/VerifyGroupsCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/VerifyGroupsCommand.java
new file mode 100644
index 0000000..3e89ca4
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/VerifyGroupsCommand.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2017-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.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+
+/**
+ * Triggers the verification of hashed group buckets in the specified device,
+ * and corrects the buckets if necessary. Outcome can be viewed in the 'groups'
+ * command.
+ */
+@Command(scope = "onos", name = "sr-verify-groups",
+        description = "Triggers the verification of hashed groups in the specified "
+                + "device. Does not return any output; users can query the results "
+                + "in the 'groups' command")
+public class VerifyGroupsCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "uri", description = "Device ID",
+            required = true, multiValued = false)
+    String uri = null;
+
+    @Override
+    protected void execute() {
+        DeviceService deviceService = get(DeviceService.class);
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        if (uri != null) {
+            Device dev = deviceService.getDevice(DeviceId.deviceId(uri));
+            if (dev != null) {
+                srService.verifyGroups(dev.id());
+            }
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/package-info.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/package-info.java
new file mode 100644
index 0000000..0f2cea6
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-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.
+ */
+
+/**
+ * Segment routing application CLI handlers.
+ */
+package org.onosproject.segmentrouting.cli;
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/BlockedPortsConfig.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/BlockedPortsConfig.java
new file mode 100644
index 0000000..a5c5557
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/BlockedPortsConfig.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2017-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.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Network config to describe ports that should be blocked until authenticated.
+ */
+public class BlockedPortsConfig extends Config<ApplicationId> {
+
+    /**
+     * Returns the top level keys to the config,
+     * which should be device ID strings.
+     *
+     * @return this list of top level keys
+     */
+    public List<String> deviceIds() {
+        List<String> devIds = new ArrayList<>();
+        if (object != null) {
+            Iterator<String> it = object.fieldNames();
+            if (it != null) {
+                it.forEachRemaining(devIds::add);
+            }
+        }
+        return devIds;
+    }
+
+    /**
+     * Returns the port range strings associated with the given device id key.
+     *
+     * @param deviceId the device id key
+     * @return the associated port range strings
+     */
+    public List<String> portRanges(String deviceId) {
+        List<String> portRanges = new ArrayList<>();
+        if (object != null) {
+            JsonNode jnode = object.get(deviceId);
+            if (ArrayNode.class.isInstance(jnode)) {
+                ArrayNode array = (ArrayNode) jnode;
+                array.forEach(pr -> portRanges.add(pr.asText()));
+            }
+        }
+        return portRanges;
+    }
+
+    /**
+     * Returns an iterator over the port numbers defined by the port ranges
+     * defined in the configuration, for the given device.
+     *
+     * @param deviceId the specific device
+     * @return an iterator over the configured ports
+     */
+    public Iterator<Long> portIterator(String deviceId) {
+        List<String> ranges = portRanges(deviceId);
+        return new PortIterator(ranges);
+    }
+
+    /**
+     * Private implementation of an iterator that aggregates several range
+     * iterators into a single iterator.
+     */
+    class PortIterator implements Iterator<Long> {
+        private final List<Range> ranges;
+        private final int nRanges;
+        private int currentRange = 0;
+        private Iterator<Long> iterator;
+
+        PortIterator(List<String> rangeSpecs) {
+            nRanges = rangeSpecs.size();
+            ranges = new ArrayList<>(nRanges);
+            if (nRanges > 0) {
+                for (String rs : rangeSpecs) {
+                    ranges.add(new Range(rs));
+                }
+                iterator = ranges.get(0).iterator();
+            }
+        }
+
+        @Override
+        public boolean hasNext() {
+            return nRanges > 0 &&
+                    (currentRange < nRanges - 1 ||
+                            (currentRange < nRanges && iterator.hasNext()));
+        }
+
+        @Override
+        public Long next() {
+            if (nRanges == 0) {
+                throw new NoSuchElementException();
+            }
+
+            Long value;
+            if (iterator.hasNext()) {
+                value = iterator.next();
+            } else {
+                currentRange++;
+                if (currentRange < nRanges) {
+                    iterator = ranges.get(currentRange).iterator();
+                    value = iterator.next();
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+            return value;
+        }
+    }
+
+    /**
+     * Private implementation of a "range" of long numbers, defined by a
+     * string of the form {@code "<lo>-<hi>"}, for example, "17-32".
+     */
+    static final class Range {
+        private static final Pattern RE_SINGLE = Pattern.compile("(\\d+)");
+        private static final Pattern RE_RANGE = Pattern.compile("(\\d+)-(\\d+)");
+        private static final String E_BAD_FORMAT = "Bad Range Format ";
+
+        private final long lo;
+        private final long hi;
+
+        /**
+         * Constructs a range from the given string definition.
+         * For example:
+         * <pre>
+         *     Range r = new Range("17-32");
+         * </pre>
+         *
+         * @param s the string representation of the range
+         * @throws IllegalArgumentException if the range string is malformed
+         */
+        Range(String s) {
+            String lohi = s;
+            Matcher m = RE_SINGLE.matcher(s);
+            if (m.matches()) {
+                lohi = s + "-" + s;
+            }
+            m = RE_RANGE.matcher(lohi);
+            if (!m.matches()) {
+                throw new IllegalArgumentException(E_BAD_FORMAT + s);
+            }
+            try {
+                lo = Long.parseLong(m.group(1));
+                hi = Long.parseLong(m.group(2));
+
+                if (hi < lo) {
+                    throw new IllegalArgumentException(E_BAD_FORMAT + s);
+                }
+            } catch (NumberFormatException nfe) {
+                // unlikely to be thrown, since the matcher will have failed first
+                throw new IllegalArgumentException(E_BAD_FORMAT + s, nfe);
+            }
+        }
+
+
+        /**
+         * Returns an iterator over this range, starting from the lowest value
+         * and iterating up to the highest value (inclusive).
+         *
+         * @return an iterator over this range
+         */
+        Iterator<Long> iterator() {
+            return new RangeIterator();
+        }
+
+        /**
+         * Private implementation of an iterator over the range.
+         */
+        class RangeIterator implements Iterator<Long> {
+            long current;
+
+            RangeIterator() {
+                current = lo - 1;
+            }
+
+            @Override
+            public boolean hasNext() {
+                return current < hi;
+            }
+
+            @Override
+            public Long next() {
+                if (!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+                return ++current;
+            }
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java
new file mode 100644
index 0000000..773c7f6
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015-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.config;
+
+/**
+ * Signals that an error occurred during reading device configuration.
+ */
+public class DeviceConfigNotFoundException extends Exception {
+
+    /**
+     * Creates a new ConfigNotFoundException with the given message.
+     *
+     * @param message exception message
+     */
+    public DeviceConfigNotFoundException(String message) {
+        super(message);
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
new file mode 100644
index 0000000..7ea430d
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
@@ -0,0 +1,728 @@
+/*
+ * Copyright 2015-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.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.SetMultimap;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.ConfigException;
+import org.onosproject.net.config.basics.InterfaceConfig;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Segment Routing configuration component that reads the
+ * segment routing related configuration from Network Configuration Manager
+ * component and organizes in more accessible formats.
+ */
+public class DeviceConfiguration implements DeviceProperties {
+
+    private static final String NO_SUBNET = "No subnet configured on {}";
+
+    private static final Logger log = LoggerFactory.getLogger(DeviceConfiguration.class);
+    private final List<Integer> allSegmentIds = new ArrayList<>();
+    private final Map<DeviceId, SegmentRouterInfo> deviceConfigMap = new ConcurrentHashMap<>();
+    private SegmentRoutingManager srManager;
+
+    private class SegmentRouterInfo {
+        int ipv4NodeSid;
+        int ipv6NodeSid;
+        DeviceId deviceId;
+        Ip4Address ipv4Loopback;
+        Ip6Address ipv6Loopback;
+        MacAddress mac;
+        boolean isEdge;
+        SetMultimap<PortNumber, IpAddress> gatewayIps;
+        SetMultimap<PortNumber, IpPrefix> subnets;
+        Map<Integer, Set<Integer>> adjacencySids;
+        DeviceId pairDeviceId;
+        PortNumber pairLocalPort;
+        int pwRoutingLabel;
+
+        public SegmentRouterInfo() {
+            gatewayIps = HashMultimap.create();
+            subnets = HashMultimap.create();
+        }
+    }
+
+    /**
+     * Constructs device configuration for all Segment Router devices,
+     * organizing the data into various maps for easier access.
+     *
+     * @param srManager Segment Routing Manager
+     */
+    public DeviceConfiguration(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        updateConfig();
+    }
+
+    public void updateConfig() {
+        // Read config from device subject, excluding gatewayIps and subnets.
+        Set<DeviceId> deviceSubjects =
+                srManager.cfgService.getSubjects(DeviceId.class, SegmentRoutingDeviceConfig.class);
+        deviceSubjects.forEach(subject -> {
+            SegmentRoutingDeviceConfig config =
+                    srManager.cfgService.getConfig(subject, SegmentRoutingDeviceConfig.class);
+            SegmentRouterInfo info = new SegmentRouterInfo();
+            info.deviceId = subject;
+            info.ipv4NodeSid = config.nodeSidIPv4();
+            info.ipv6NodeSid = config.nodeSidIPv6();
+            info.ipv4Loopback = config.routerIpv4();
+            info.ipv6Loopback = config.routerIpv6();
+            info.mac = config.routerMac();
+            info.isEdge = config.isEdgeRouter();
+            info.adjacencySids = config.adjacencySids();
+            info.pairDeviceId = config.pairDeviceId();
+            info.pairLocalPort = config.pairLocalPort();
+            info.pwRoutingLabel = info.ipv4NodeSid + 1000;
+            deviceConfigMap.put(info.deviceId, info);
+            log.debug("Read device config for device: {}", info.deviceId);
+            /*
+             * IPv6 sid is not inserted. this part of the code is not used for now.
+             */
+            allSegmentIds.add(info.ipv4NodeSid);
+        });
+
+        // Read gatewayIps and subnets from port subject. Ignore suppressed ports.
+        Set<ConnectPoint> portSubjects = srManager.cfgService
+                .getSubjects(ConnectPoint.class, InterfaceConfig.class);
+        portSubjects.stream()
+                .filter(subject -> deviceConfigMap.containsKey(subject.deviceId()))
+                .filter(subject -> !isSuppressedPort(subject)).forEach(subject -> {
+            InterfaceConfig config =
+                    srManager.cfgService.getConfig(subject, InterfaceConfig.class);
+            Set<Interface> networkInterfaces;
+            try {
+                networkInterfaces = config.getInterfaces();
+            } catch (ConfigException e) {
+                log.error("Error loading port configuration");
+                return;
+            }
+            networkInterfaces.forEach(networkInterface -> {
+                VlanId vlanId = networkInterface.vlan();
+                ConnectPoint connectPoint = networkInterface.connectPoint();
+                DeviceId dpid = connectPoint.deviceId();
+                PortNumber port = connectPoint.port();
+                MacAddress mac = networkInterface.mac();
+                SegmentRouterInfo info = deviceConfigMap.get(dpid);
+
+                // skip if there is no corresponding device for this ConenctPoint
+                if (info != null) {
+                    // Extract subnet information
+                    List<InterfaceIpAddress> interfaceAddresses = networkInterface.ipAddressesList();
+                    interfaceAddresses.forEach(interfaceAddress -> {
+                        // Do not add /0, /32 and /128 to gateway IP list
+                        int prefixLength = interfaceAddress.subnetAddress().prefixLength();
+                        IpPrefix ipPrefix = interfaceAddress.subnetAddress();
+                        if (ipPrefix.isIp4()) {
+                            if (prefixLength != 0 && prefixLength != IpPrefix.MAX_INET_MASK_LENGTH) {
+                                info.gatewayIps.put(port, interfaceAddress.ipAddress());
+                            }
+                            info.subnets.put(port, interfaceAddress.subnetAddress());
+                        } else {
+                            if (prefixLength != 0 && prefixLength != IpPrefix.MAX_INET6_MASK_LENGTH) {
+                                info.gatewayIps.put(port, interfaceAddress.ipAddress());
+                            }
+                            info.subnets.put(port, interfaceAddress.subnetAddress());
+                        }
+                    });
+
+                    // Override interface mac with router mac
+                    if (!mac.equals(info.mac)) {
+                        ArrayNode array = (ArrayNode) config.node();
+                        for (JsonNode intfNode : array) {
+                            ObjectNode objNode = (ObjectNode) intfNode;
+                            objNode.put(InterfaceConfig.MAC, info.mac.toString());
+                        }
+                        srManager.cfgService.applyConfig(connectPoint, InterfaceConfig.class, array);
+                    }
+                }
+            });
+            // We register the connect point with the NRS.
+            srManager.registerConnectPoint(subject);
+        });
+    }
+
+    public Collection<DeviceId> getRouters() {
+        return deviceConfigMap.keySet();
+    }
+
+    @Override
+    public boolean isConfigured(DeviceId deviceId) {
+        return deviceConfigMap.get(deviceId) != null;
+    }
+
+    @Override
+    public int getIPv4SegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        log.info("DEVICE MAP IS {}", deviceConfigMap);
+        if (srinfo != null) {
+            log.trace("getIPv4SegmentId for device{} is {}", deviceId, srinfo.ipv4NodeSid);
+            return srinfo.ipv4NodeSid;
+        } else {
+            String message = "getIPv4SegmentId fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+    }
+
+    @Override
+    public int getIPv6SegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            log.trace("getIPv6SegmentId for device{} is {}", deviceId, srinfo.ipv6NodeSid);
+            return srinfo.ipv6NodeSid;
+        } else {
+            String message = "getIPv6SegmentId fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+    }
+
+    @Override
+    public int getPWRoutingLabel(DeviceId deviceId) throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            log.trace("pwRoutingLabel for device{} is {}", deviceId, srinfo.pwRoutingLabel);
+            return srinfo.pwRoutingLabel;
+        } else {
+            String message = "getPWRoutingLabel fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+    }
+
+    /**
+     * Returns the IPv4 Node segment id of a segment router given its Router mac address.
+     *
+     * @param routerMac router mac address
+     * @return node segment id, or -1 if not found in config
+     */
+    public int getIPv4SegmentId(MacAddress routerMac) {
+        for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+                    deviceConfigMap.entrySet()) {
+            if (entry.getValue().mac.equals(routerMac)) {
+                return entry.getValue().ipv4NodeSid;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns the IPv6 Node segment id of a segment router given its Router mac address.
+     *
+     * @param routerMac router mac address
+     * @return node segment id, or -1 if not found in config
+     */
+    public int getIPv6SegmentId(MacAddress routerMac) {
+        for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+                deviceConfigMap.entrySet()) {
+            if (entry.getValue().mac.equals(routerMac)) {
+                return entry.getValue().ipv6NodeSid;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns the IPv4 Node segment id of a segment router given its Router ip address.
+     *
+     * @param routerAddress router ip address
+     * @return node segment id, or -1 if not found in config
+     */
+    public int getIPv4SegmentId(Ip4Address routerAddress) {
+        for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+            deviceConfigMap.entrySet()) {
+            if (entry.getValue().ipv4Loopback.equals(routerAddress)) {
+                return entry.getValue().ipv4NodeSid;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns the IPv6 Node segment id of a segment router given its Router ip address.
+     *
+     * @param routerAddress router ip address
+     * @return node segment id, or -1 if not found in config
+     */
+    public int getIPv6SegmentId(Ip6Address routerAddress) {
+        for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+                deviceConfigMap.entrySet()) {
+            if (entry.getValue().ipv6Loopback.equals(routerAddress)) {
+                return entry.getValue().ipv6NodeSid;
+            }
+        }
+
+        return -1;
+    }
+
+    @Override
+    public MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            return srinfo.mac;
+        } else {
+            String message = "getDeviceMac fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+    }
+
+    @Override
+    public Ip4Address getRouterIpv4(DeviceId deviceId) throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            log.trace("getRouterIpv4 for device{} is {}", deviceId, srinfo.ipv4Loopback);
+            return srinfo.ipv4Loopback;
+        } else {
+            String message = "getRouterIpv4 fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+    }
+
+    @Override
+    public Ip6Address getRouterIpv6(DeviceId deviceId) throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            log.trace("getRouterIpv6 for device{} is {}", deviceId, srinfo.ipv6Loopback);
+            return srinfo.ipv6Loopback;
+        } else {
+            String message = "getRouterIpv6 fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+    }
+
+    @Override
+    public boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            log.trace("isEdgeDevice for device{} is {}", deviceId, srinfo.isEdge);
+            return srinfo.isEdge;
+        } else {
+            String message = "isEdgeDevice fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+    }
+
+    @Override
+    public List<Integer> getAllDeviceSegmentIds() {
+        return allSegmentIds;
+    }
+
+    @Override
+    public Map<IpPrefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId)
+            throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo == null) {
+            String message = "getSubnetPortsMap fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+        // Construct subnet-port mapping from port-subnet mapping
+        SetMultimap<PortNumber, IpPrefix> portSubnetMap = srinfo.subnets;
+        Map<IpPrefix, List<PortNumber>> subnetPortMap = new HashMap<>();
+
+        portSubnetMap.entries().forEach(entry -> {
+            PortNumber port = entry.getKey();
+            IpPrefix subnet = entry.getValue();
+
+            if (subnet.prefixLength() == IpPrefix.MAX_INET_MASK_LENGTH ||
+                    subnet.prefixLength() == IpPrefix.MAX_INET6_MASK_LENGTH) {
+                return;
+            }
+
+            if (subnetPortMap.containsKey(subnet)) {
+                subnetPortMap.get(subnet).add(port);
+            } else {
+                ArrayList<PortNumber> ports = new ArrayList<>();
+                ports.add(port);
+                subnetPortMap.put(subnet, ports);
+            }
+        });
+        return subnetPortMap;
+    }
+
+    /**
+     * Returns the device identifier or data plane identifier (dpid)
+     * of a segment router given its segment id.
+     *
+     * @param sid segment id
+     * @return deviceId device identifier
+     */
+    public DeviceId getDeviceId(int sid) {
+        for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+            deviceConfigMap.entrySet()) {
+            if (entry.getValue().ipv4NodeSid == sid ||
+                    entry.getValue().ipv6NodeSid == sid) {
+                return entry.getValue().deviceId;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the device identifier or data plane identifier (dpid)
+     * of a segment router given its router ip address.
+     *
+     * @param ipAddress router ip address
+     * @return deviceId device identifier
+     */
+    public DeviceId getDeviceId(Ip4Address ipAddress) {
+        for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+            deviceConfigMap.entrySet()) {
+            if (entry.getValue().ipv4Loopback.equals(ipAddress)) {
+                return entry.getValue().deviceId;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the device identifier or data plane identifier (dpid)
+     * of a segment router given its router ipv6 address.
+     *
+     * @param ipAddress router ipv6 address
+     * @return deviceId device identifier
+     */
+    public DeviceId getDeviceId(Ip6Address ipAddress) {
+        for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+                deviceConfigMap.entrySet()) {
+            if (entry.getValue().ipv6Loopback.equals(ipAddress)) {
+                return entry.getValue().deviceId;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the configured port ip addresses for a segment router.
+     * These addresses serve as gateway IP addresses for the subnets configured
+     * on those ports.
+     *
+     * @param deviceId device identifier
+     * @return immutable set of ip addresses configured on the ports or null if not found
+     */
+    public Set<IpAddress> getPortIPs(DeviceId deviceId) {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            log.trace("getSubnetGatewayIps for device{} is {}", deviceId,
+                      srinfo.gatewayIps.values());
+            return ImmutableSet.copyOf(srinfo.gatewayIps.values());
+        }
+        return null;
+    }
+
+    /**
+     * Returns the configured subnet prefixes for a segment router.
+     *
+     * @param deviceId device identifier
+     * @return list of ip prefixes or null if not found
+     */
+    public Set<IpPrefix> getSubnets(DeviceId deviceId) {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            ImmutableSet.Builder<IpPrefix> builder = ImmutableSet.builder();
+            return builder.addAll(srinfo.subnets.values()).build();
+        }
+        return null;
+    }
+
+
+    /**
+     * Returns the subnet configuration of given device and port.
+     *
+     * @param deviceId Device ID
+     * @param port Port number
+     * @return The subnets configured on given port or empty set if
+     *         the port is unconfigured or suppressed.
+     */
+    public Set<IpPrefix> getPortSubnets(DeviceId deviceId, PortNumber port) {
+        ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
+
+        if (isSuppressedPort(connectPoint)) {
+            return Collections.emptySet();
+        }
+
+        Set<IpPrefix> subnets =
+                srManager.interfaceService.getInterfacesByPort(connectPoint).stream()
+                        .flatMap(intf -> intf.ipAddressesList().stream())
+                        .map(InterfaceIpAddress::subnetAddress)
+                        .collect(Collectors.toSet());
+
+        if (subnets.isEmpty()) {
+            log.debug(NO_SUBNET, connectPoint);
+            return Collections.emptySet();
+        }
+
+        return subnets;
+    }
+
+    /**
+     * Returns all ports that has a subnet that contains any of the given IP addresses.
+     *
+     * @param ips a set of IP addresses
+     * @return a set of connect point that has a subnet that contains any of the given IP addresses
+     */
+    public Set<ConnectPoint> getPortByIps(Set<IpAddress> ips) {
+        return srManager.interfaceService.getInterfaces().stream()
+                .filter(intf -> intf.ipAddressesList().stream().anyMatch(intfAddress ->
+                            ips.stream().anyMatch(ip -> intfAddress.subnetAddress().contains(ip))))
+                .map(Interface::connectPoint)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Returns the router ip address of segment router that has the
+     * specified ip address in its subnets.
+     *
+     * @param destIpAddress target ip address
+     * @return router ip address
+     */
+    public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) {
+        Interface matchIntf = srManager.interfaceService.getMatchingInterface(destIpAddress);
+
+        if (matchIntf == null) {
+            log.debug("No router was found for {}", destIpAddress);
+            return null;
+        }
+
+        DeviceId routerDeviceId = matchIntf.connectPoint().deviceId();
+        SegmentRouterInfo srInfo = deviceConfigMap.get(routerDeviceId);
+        if (srInfo == null) {
+            log.debug("No device config was found for {}", routerDeviceId);
+            return null;
+        }
+
+        return srInfo.ipv4Loopback;
+    }
+
+    /**
+     * Returns the router ipv6 address of segment router that has the
+     * specified ip address in its subnets.
+     *
+     * @param destIpAddress target ip address
+     * @return router ip address
+     */
+    public Ip6Address getRouterIpAddressForASubnetHost(Ip6Address destIpAddress) {
+        Interface matchIntf = srManager.interfaceService.getMatchingInterface(destIpAddress);
+
+        if (matchIntf == null) {
+            log.debug("No router was found for {}", destIpAddress);
+            return null;
+        }
+
+        DeviceId routerDeviceId = matchIntf.connectPoint().deviceId();
+        SegmentRouterInfo srInfo = deviceConfigMap.get(routerDeviceId);
+        if (srInfo == null) {
+            log.debug("No device config was found for {}", routerDeviceId);
+            return null;
+        }
+
+        return srInfo.ipv6Loopback;
+    }
+
+    /**
+     * Returns the router mac address of segment router that has the
+     * specified ip address as one of its subnet gateway ip address.
+     *
+     * @param gatewayIpAddress router gateway ip address
+     * @return router mac address or null if not found
+     */
+    public MacAddress getRouterMacForAGatewayIp(IpAddress gatewayIpAddress) {
+        for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+                deviceConfigMap.entrySet()) {
+            if (entry.getValue().gatewayIps.
+                    values().contains(gatewayIpAddress)) {
+                return entry.getValue().mac;
+            }
+        }
+
+        log.debug("Cannot find a router for {}", gatewayIpAddress);
+        return null;
+    }
+
+    /**
+     * Checks if the host IP is in any of the subnet defined in the router with the
+     * device ID given.
+     *
+     * @param deviceId device identification of the router
+     * @param hostIp   host IP address to check
+     * @return true if the given IP is within any of the subnet defined in the router,
+     * false if no subnet is defined in the router or if the host is not
+     * within any subnet defined in the router
+     */
+    public boolean inSameSubnet(DeviceId deviceId, IpAddress hostIp) {
+
+        Set<IpPrefix> subnets = getSubnets(deviceId);
+        if (subnets == null) {
+            return false;
+        }
+
+        for (IpPrefix subnet: subnets) {
+            // Exclude /0 since it is a special case used for default route
+            if (subnet.prefixLength() != 0 && subnet.contains(hostIp)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if the IP is in the subnet defined on given connect point.
+     *
+     * @param connectPoint Connect point
+     * @param ip The IP address to check
+     * @return True if the IP belongs to the subnet.
+     *         False if the IP does not belong to the subnet, or
+     *         there is no subnet configuration on given connect point.
+     */
+    public boolean inSameSubnet(ConnectPoint connectPoint, IpAddress ip) {
+        return getPortSubnets(connectPoint.deviceId(), connectPoint.port()).stream()
+                .anyMatch(ipPrefix -> ipPrefix.contains(ip));
+    }
+
+    /**
+     * Returns the ports corresponding to the adjacency Sid given.
+     *
+     * @param deviceId device identification of the router
+     * @param sid adjacency Sid
+     * @return set of port numbers
+     */
+    public Set<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        return srinfo != null ?
+                ImmutableSet.copyOf(srinfo.adjacencySids.get(sid)) :
+                ImmutableSet.copyOf(new HashSet<>());
+    }
+
+    /**
+     * Check if the Sid given is whether adjacency Sid of the router device or not.
+     *
+     * @param deviceId device identification of the router
+     * @param sid Sid to check
+     * @return true if the Sid given is the adjacency Sid of the device,
+     * otherwise false
+     */
+    public boolean isAdjacencySid(DeviceId deviceId, int sid) {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        return srinfo != null && srinfo.adjacencySids.containsKey(sid);
+    }
+
+    /**
+     * Add subnet to specific connect point.
+     *
+     * @param cp connect point
+     * @param ipPrefix subnet being added to the device
+     */
+    public void addSubnet(ConnectPoint cp, IpPrefix ipPrefix) {
+        checkNotNull(cp);
+        checkNotNull(ipPrefix);
+        SegmentRouterInfo srinfo = deviceConfigMap.get(cp.deviceId());
+        if (srinfo == null) {
+            log.warn("Device {} is not configured. Abort.", cp.deviceId());
+            return;
+        }
+        srinfo.subnets.put(cp.port(), ipPrefix);
+    }
+
+    /**
+     * Remove subnet from specific connect point.
+     *
+     * @param cp connect point
+     * @param ipPrefix subnet being removed to the device
+     */
+    public void removeSubnet(ConnectPoint cp, IpPrefix ipPrefix) {
+        checkNotNull(cp);
+        checkNotNull(ipPrefix);
+        SegmentRouterInfo srinfo = deviceConfigMap.get(cp.deviceId());
+        if (srinfo == null) {
+            log.warn("Device {} is not configured. Abort.", cp.deviceId());
+            return;
+        }
+        srinfo.subnets.remove(cp.port(), ipPrefix);
+    }
+
+    private boolean isSuppressedPort(ConnectPoint connectPoint) {
+        SegmentRoutingAppConfig appConfig = srManager.cfgService
+                .getConfig(srManager.appId(), SegmentRoutingAppConfig.class);
+        if (appConfig != null && appConfig.suppressSubnet().contains(connectPoint)) {
+            log.info("Interface configuration on port {} is ignored", connectPoint);
+            return true;
+        }
+        return false;
+    }
+
+    public boolean isPairedEdge(DeviceId deviceId) throws DeviceConfigNotFoundException {
+        if (!isEdgeDevice(deviceId)) {
+            return false;
+        }
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        return (srinfo.pairDeviceId == null) ? false : true;
+    }
+
+    public DeviceId getPairDeviceId(DeviceId deviceId) throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            return srinfo.pairDeviceId;
+        } else {
+            String message = "getPairDeviceId fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+    }
+
+    public PortNumber getPairLocalPort(DeviceId deviceId)
+            throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            return srinfo.pairLocalPort;
+        } else {
+            String message = "getPairLocalPort fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java
new file mode 100644
index 0000000..2d0bbd2
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2015-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.config;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Mechanism through which group handler module retrieves
+ * the device specific attributes such as segment ID,
+ * Mac address...etc from group handler applications.
+ */
+public interface DeviceProperties {
+    /**
+     * Checks if the device is configured.
+     *
+     * @param deviceId device identifier
+     * @return true if the device is configured
+     */
+    boolean isConfigured(DeviceId deviceId);
+
+    /**
+     * Returns the IPv4 segment id of a device to be used in group creation.
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return segment id of a device
+     */
+    int getIPv4SegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException;
+
+    /**
+     * Returns the IPv6 segment id of a device to be used in group creation.
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return segment id of a device
+     */
+    int getIPv6SegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException;
+
+    /**
+     * Returns the Mac address of a device to be used in group creation.
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return mac address of a device
+     */
+    MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException;
+
+    /**
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return the pseudowire routing label for a leaf node
+     */
+    int getPWRoutingLabel(DeviceId deviceId) throws DeviceConfigNotFoundException;
+
+    /**
+     * Returns the router ipv4 address of a segment router.
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return router ip address
+     */
+    IpAddress getRouterIpv4(DeviceId deviceId) throws DeviceConfigNotFoundException;
+
+    /**
+     * Returns the router ipv6 address of a segment router.
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return router ip address
+     */
+    IpAddress getRouterIpv6(DeviceId deviceId) throws DeviceConfigNotFoundException;
+
+    /**
+     * Indicates whether a device is edge device or transit/core device.
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return boolean
+     */
+    boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException;
+
+    /**
+     * Returns all segment IDs to be considered in building auto
+     *
+     * created groups.
+     * @return list of segment IDs
+     */
+    List<Integer> getAllDeviceSegmentIds();
+
+    /**
+     * Returns subnet-to-ports mapping of given device.
+     *
+     * For each entry of the map
+     * Key: a subnet
+     * Value: a list of ports, which are bound to the subnet
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return a map that contains all subnet-to-ports mapping of given device
+     */
+    Map<IpPrefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId)
+            throws DeviceConfigNotFoundException;
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java
new file mode 100644
index 0000000..31cad7e
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java
@@ -0,0 +1,671 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.intf.InterfaceService;
+import org.onosproject.segmentrouting.pwaas.L2Tunnel;
+import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
+import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.L2Mode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * App configuration object for Pwaas.
+ */
+public class PwaasConfig extends Config<ApplicationId> {
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public InterfaceService intfService;
+
+    private static Logger log = LoggerFactory
+            .getLogger(PwaasConfig.class);
+
+    private static final String SRC_CP = "cP1";
+    private static final String DST_CP = "cP2";
+    private static final String SRC_OUTER_TAG = "cP1OuterTag";
+    private static final String DST_OUTER_TAG = "cP2OuterTag";
+    private static final String SRC_INNER_TAG = "cP1InnerTag";
+    private static final String DST_INNER_TAG = "cP2InnerTag";
+    private static final String MODE = "mode";
+    private static final String SD_TAG = "sdTag";
+    private static final String PW_LABEL = "pwLabel";
+
+    public PwaasConfig(DeviceService devS, InterfaceService intfS) {
+
+        super();
+
+        deviceService = devS;
+        intfService = intfS;
+    }
+
+    public PwaasConfig() {
+
+        super();
+
+        deviceService = AbstractShellCommand.get(DeviceService.class);
+        intfService = AbstractShellCommand.get(InterfaceService.class);
+    }
+    /**
+     * Error message for missing parameters.
+     */
+    private static final String MISSING_PARAMS = "Missing parameters in pseudo wire description";
+
+    /**
+     * Error message for invalid l2 mode.
+     */
+    private static final String INVALID_L2_MODE = "Invalid pseudo wire mode";
+
+    /**
+     * Error message for invalid VLAN.
+     */
+    private static final String INVALID_VLAN = "Vlan should be either int or */-";
+
+    /**
+     * Error message for invalid PW label.
+     */
+    private static final String INVALID_PW_LABEL = "Pseudowire label should be an integer";
+
+    /**
+     * Verify if the pwaas configuration block is valid.
+     *
+     * Here we try to ensure that the provided pseudowires will get instantiated
+     * correctly in the network. We also check for any collisions with already used
+     * interfaces and also between different pseudowires. Most of the restrictions stem
+     * from the fact that all vlan matching is done in table 10 of ofdpa.
+     *
+     * @return true, if the configuration block is valid.
+     *         False otherwise.
+     */
+    @Override
+    public boolean isValid() {
+
+        Set<L2TunnelDescription> pseudowires;
+        try {
+            pseudowires = getPwIds().stream()
+                    .map(this::getPwDescription)
+                    .collect(Collectors.toSet());
+
+            // check semantics now and return
+            return configurationValidity(pseudowires);
+
+        } catch (IllegalArgumentException e) {
+            log.warn("{}", e.getMessage());
+            return false;
+        }
+    }
+
+    /**
+     * Helper method to verify if the tunnel is whether or not
+     * supported.
+     *
+     * @param l2Tunnel the tunnel to verify
+     * @return the result of the verification
+     */
+    private void verifyTunnel(L2Tunnel l2Tunnel) {
+
+        // Service delimiting tag not supported yet.
+        if (!l2Tunnel.sdTag().equals(VlanId.NONE)) {
+            throw new IllegalArgumentException(String.format("Service delimiting tag not supported yet for " +
+                                                             "pseudowire %d.", l2Tunnel.tunnelId()));
+        }
+
+        // Tag mode not supported yet.
+        if (l2Tunnel.pwMode() == L2Mode.TAGGED) {
+            throw new IllegalArgumentException(String.format("Tagged mode not supported yet for pseudowire %d.",
+                                                                            l2Tunnel.tunnelId()));
+        }
+
+        // Raw mode without service delimiting tag
+        // is the only mode supported for now.
+    }
+
+    /**
+     * Helper method to verify if the policy is whether or not
+     * supported and if policy will be successfully instantiated in the
+     * network.
+     *
+     * @param ingressInner the ingress inner tag
+     * @param ingressOuter the ingress outer tag
+     * @param egressInner the egress inner tag
+     * @param egressOuter the egress outer tag
+     * @return the result of verification
+     */
+    private void verifyPolicy(ConnectPoint cP1,
+                              ConnectPoint cP2,
+                              VlanId ingressInner,
+                              VlanId ingressOuter,
+                              VlanId egressInner,
+                              VlanId egressOuter,
+                              Long tunnelId) {
+
+        if (cP1.deviceId().equals(cP2.deviceId())) {
+            throw new IllegalArgumentException(String.format("Pseudowire connection points can not reside in the " +
+                                                             "same node, in pseudowire %d.", tunnelId));
+        }
+
+        // We can have multiple tags, all of them can be NONE,
+        // indicating untagged traffic, however, the outer tag can
+        // not have value if the inner tag is None
+        if (ingressInner.equals(VlanId.NONE) && !ingressOuter.equals(VlanId.NONE)) {
+            throw new IllegalArgumentException(String.format("Inner tag should not be empty when " +
+                                                             "outer tag is set for pseudowire %d for cP1.",
+                                                              tunnelId));
+        }
+
+        if (egressInner.equals(VlanId.NONE) && !egressOuter.equals(VlanId.NONE)) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Inner tag should not be empty when" +
+                                                                            " outer tag is set for pseudowire %d " +
+                                                                            "for cP2.", tunnelId)));
+        }
+
+        if (ingressInner.equals(VlanId.ANY) ||
+                ingressOuter.equals(VlanId.ANY) ||
+                egressInner.equals(VlanId.ANY) ||
+                egressOuter.equals(VlanId.ANY)) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Wildcard VLAN matching not yet " +
+                                                                            "supported for pseudowire %d.",
+                                                                            tunnelId)));
+        }
+
+        if (((!ingressOuter.equals(VlanId.NONE) && !ingressInner.equals(VlanId.NONE)) &&
+                (egressOuter.equals(VlanId.NONE) && egressInner.equals(VlanId.NONE)))
+                || ((ingressOuter.equals(VlanId.NONE) && ingressInner.equals(VlanId.NONE)) &&
+                (!egressOuter.equals(VlanId.NONE) && !egressInner.equals(VlanId.NONE)))) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Support for double tag <-> untag is not" +
+                                                                                    "supported for pseudowire %d.",
+                                                                            tunnelId)));
+        }
+        if ((!ingressInner.equals(VlanId.NONE) &&
+                ingressOuter.equals(VlanId.NONE) &&
+                !egressOuter.equals(VlanId.NONE))
+           || (egressOuter.equals(VlanId.NONE) &&
+                !egressInner.equals(VlanId.NONE) &&
+                !ingressOuter.equals(VlanId.NONE))) {
+                throw new IllegalArgumentException(String.valueOf(String.format("Support for double-tag<->" +
+                                                                                "single-tag is not supported" +
+                                                                                " for pseudowire %d.", tunnelId)));
+        }
+
+        if ((ingressInner.equals(VlanId.NONE) && !egressInner.equals(VlanId.NONE))
+                || (!ingressInner.equals(VlanId.NONE) && egressInner.equals(VlanId.NONE))) {
+            throw new IllegalArgumentException(String.valueOf(String.format("single-tag <-> untag is not supported" +
+                                                                            " for pseudowire %d.", tunnelId)));
+        }
+
+
+        if (!ingressInner.equals(egressInner) && !ingressOuter.equals(egressOuter)) {
+            throw new IllegalArgumentException(String.valueOf(String.format("We do not support changing both tags " +
+                                                                             "in double tagged pws, only the outer," +
+                                                                             " for pseudowire %d.", tunnelId)));
+        }
+
+        // check if cp1 and port of cp1 exist
+        if (deviceService.getDevice(cP1.deviceId()) == null) {
+            throw new IllegalArgumentException(String.valueOf(String.format("cP1 device %s does not exist for" +
+                                                                            " pseudowire %d.", cP1.deviceId(),
+                                                                            tunnelId)));
+        }
+
+        if (deviceService.getPort(cP1) == null) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Port %s for cP1 device %s does not" +
+                                                                            " exist for pseudowire %d.", cP1.port(),
+                                                                            cP1.deviceId(), tunnelId)));
+        }
+
+        // check if cp2 and port of cp2 exist
+        if (deviceService.getDevice(cP2.deviceId()) == null) {
+            throw new IllegalArgumentException(String.valueOf(String.format("cP2 device %s does not exist for" +
+                                                                            " pseudowire %d.", cP2.deviceId(),
+                                                                            tunnelId)));
+        }
+
+        if (deviceService.getPort(cP2) == null) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Port %s for cP2 device %s does " +
+                                                                            "not exist for pseudowire %d.",
+                                                                            cP2.port(), cP2.deviceId(), tunnelId)));
+        }
+    }
+
+    /**
+     * Verifies that the pseudowires will not conflict with each other.
+     *
+     * Further, check if vlans for connect points are already used.
+     *
+     * @param tunnel Tunnel for pw
+     * @param policy Policy for pw
+     * @param labelSet Label set used so far with this configuration
+     * @param vlanSet Vlan set used with this configuration
+     * @param tunnelSet Tunnel set used with this configuration
+     */
+    private void verifyGlobalValidity(L2Tunnel tunnel,
+                                      L2TunnelPolicy policy,
+                                      Set<MplsLabel> labelSet,
+                                      Map<ConnectPoint, Set<VlanId>> vlanSet,
+                                      Set<Long> tunnelSet) {
+
+        if (tunnelSet.contains(tunnel.tunnelId())) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Tunnel Id %d already used by" +
+                                                                           " another pseudowire, in " +
+                                                                           "pseudowire %d!", tunnel.tunnelId(),
+                                                                            tunnel.tunnelId())));
+        }
+        tunnelSet.add(tunnel.tunnelId());
+
+        // check if tunnel id is used again
+        ConnectPoint cP1 = policy.cP1();
+        ConnectPoint cP2 = policy.cP2();
+
+        // insert cps to hashmap if this is the first time seen
+        if (!vlanSet.containsKey(cP1)) {
+            vlanSet.put(cP1, new HashSet<VlanId>());
+        }
+        if (!vlanSet.containsKey(cP2)) {
+            vlanSet.put(cP2, new HashSet<VlanId>());
+        }
+
+        // if single tagged or untagged vlan is the inner
+        // if double tagged vlan is the outer
+        VlanId vlanToCheckCP1;
+        if (policy.cP1OuterTag().equals(VlanId.NONE)) {
+            vlanToCheckCP1 = policy.cP1InnerTag();
+        } else {
+            vlanToCheckCP1 = policy.cP1OuterTag();
+        }
+
+        VlanId vlanToCheckCP2;
+        if (policy.cP2OuterTag().equals(VlanId.NONE)) {
+            vlanToCheckCP2 = policy.cP2InnerTag();
+        } else {
+            vlanToCheckCP2 = policy.cP2OuterTag();
+        }
+
+        if (labelSet.contains(tunnel.pwLabel())) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Label %s already used by another" +
+                                                                            " pseudowire, in pseudowire %d!",
+                                                                            tunnel.pwLabel(), tunnel.tunnelId())));
+        }
+        labelSet.add(tunnel.pwLabel());
+
+        if (vlanSet.get(cP1).contains(vlanToCheckCP1)) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP1 %s already used " +
+                                                                            "by another pseudowire, in pseudowire" +
+                                                                            " %d!", vlanToCheckCP1,  cP1,
+                                                                            tunnel.tunnelId())));
+        }
+        vlanSet.get(cP1).add(vlanToCheckCP1);
+
+        if (vlanSet.get(cP2).contains(vlanToCheckCP2)) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP2 %s already used" +
+                                                                            " by another pseudowire, in" +
+                                                                            " pseudowire %d!", vlanToCheckCP2, cP2,
+                                                                            tunnel.tunnelId())));
+        }
+        vlanSet.get(cP2).add(vlanToCheckCP2);
+
+        // check that vlans for the connect points are not used
+        intfService.getInterfacesByPort(cP1).stream()
+                .forEach(intf -> {
+
+                    // check if tagged pw affects tagged interface
+                    if (intf.vlanTagged().contains(vlanToCheckCP1)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP1 %s already" +
+                                                                                        " used for this interface, in" +
+                                                                                        " pseudowire %d!",
+                                                                                        vlanToCheckCP1, cP1,
+                                                                                        tunnel.tunnelId())));
+                    }
+
+                    // if vlanNative != null this interface is configured with untagged traffic also
+                    // check if it collides with untagged interface
+                    if ((intf.vlanNative() != null) && vlanToCheckCP1.equals(VlanId.NONE)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP1 " +
+                                                                                         "%s already used for this " +
+                                                                                         "interface, in pseudowire " +
+                                                                                         "%d!", cP1,
+                                                                                         tunnel.tunnelId())));
+                    }
+
+                    // if vlanUntagged != null this interface is configured only with untagged traffic
+                    // check if it collides with untagged interface
+                    if ((intf.vlanUntagged() != null) && vlanToCheckCP1.equals(VlanId.NONE)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for " +
+                                                                                         "cP1 %s already" +
+                                                                                         " used for this interface," +
+                                                                                         " in pseudowire %d!",
+                                                                                         cP1, tunnel.tunnelId())));
+                    }
+                });
+
+        intfService.getInterfacesByPort(cP2).stream()
+                .forEach(intf -> {
+                    if (intf.vlanTagged().contains(vlanToCheckCP2)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP2 %s already" +
+                                                                                        " used for  this interface, " +
+                                                                                        "in pseudowire %d!",
+                                                                                        vlanToCheckCP2, cP2,
+                                                                                        tunnel.tunnelId())));
+                    }
+
+                    // if vlanNative != null this interface is configured with untagged traffic also
+                    // check if it collides with untagged interface
+                    if ((intf.vlanNative() != null) && vlanToCheckCP2.equals(VlanId.NONE)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP2 %s " +
+                                                                                        "already used for this" +
+                                                                                        " interface, " +
+                                                                                        "in pseudowire %d!",
+                                                                                        cP2, tunnel.tunnelId())));
+                    }
+
+                    // if vlanUntagged != null this interface is configured only with untagged traffic
+                    // check if it collides with untagged interface
+                    if ((intf.vlanUntagged() != null) && vlanToCheckCP2.equals(VlanId.NONE)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP2 %s" +
+                                                                                        " already" +
+                                                                                        " used for this interface, " +
+                                                                                        "in pseudowire %d!",
+                                                                                        cP2, tunnel.tunnelId())));
+                    }
+                });
+
+    }
+
+    /**
+     * Helper method to verify the integrity of the pseudo wire.
+     *
+     * @param l2TunnelDescription the pseudo wire description
+     * @return the result of the check
+     */
+    private void verifyPseudoWire(L2TunnelDescription l2TunnelDescription,
+                                  Set<MplsLabel> labelSet,
+                                  Map<ConnectPoint, Set<VlanId>> vlanset,
+                                  Set<Long> tunnelSet) {
+
+        L2Tunnel l2Tunnel = l2TunnelDescription.l2Tunnel();
+        L2TunnelPolicy l2TunnelPolicy = l2TunnelDescription.l2TunnelPolicy();
+
+        verifyTunnel(l2Tunnel);
+
+        verifyPolicy(
+                l2TunnelPolicy.cP1(),
+                l2TunnelPolicy.cP2(),
+                l2TunnelPolicy.cP1InnerTag(),
+                l2TunnelPolicy.cP1OuterTag(),
+                l2TunnelPolicy.cP2InnerTag(),
+                l2TunnelPolicy.cP2OuterTag(),
+                l2Tunnel.tunnelId()
+        );
+
+        verifyGlobalValidity(l2Tunnel,
+                             l2TunnelPolicy,
+                             labelSet,
+                             vlanset,
+                             tunnelSet);
+
+    }
+
+    /**
+     * Checks if the configured pseudowires will create problems in the network.
+     * If yes, then no pseudowires is deployed from this configuration.
+     *
+     * @param pseudowires Set of pseudowries to validate
+     * @return returns true if everything goes well.
+     */
+    public boolean configurationValidity(Set<L2TunnelDescription> pseudowires) {
+
+        // structures to keep pw information
+        // in order to see if instantiating them will create
+        // problems
+        Set<Long> tunIds = new HashSet<>();
+        Set<MplsLabel> labelsUsed = new HashSet<>();
+        Map<ConnectPoint, Set<VlanId>> vlanIds = new HashMap<>();
+
+        // check that pseudowires can be instantiated in the network
+        // we try to guarantee that all the pws will work before
+        // instantiating any of them
+        for (L2TunnelDescription pw : pseudowires) {
+            verifyPseudoWire(pw, labelsUsed, vlanIds, tunIds);
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns all pseudo wire keys.
+     *
+     * @return all keys (tunnels id)
+     * @throws IllegalArgumentException if wrong format
+     */
+    public Set<Long> getPwIds() {
+        ImmutableSet.Builder<Long> builder = ImmutableSet.builder();
+        object.fields().forEachRemaining(entry -> {
+            Long tunnelId = Long.parseLong(entry.getKey());
+            builder.add(tunnelId);
+        });
+        return builder.build();
+    }
+
+    /**
+     * Parses a vlan as a string. Returns the VlanId if
+     * provided String can be parsed as an integer or is '' / '*'
+     *
+     * @param vlan string as read from configuration
+     * @return VlanId
+     * @throws IllegalArgumentException if wrong format of vlan
+     */
+    public VlanId parseVlan(String vlan) {
+
+        if (vlan.equals("*") || vlan.equals("Any")) {
+            return VlanId.vlanId("Any");
+        } else if (vlan.equals("") || vlan.equals("None")) {
+            return VlanId.vlanId("None");
+        } else {
+            try {
+                VlanId newVlan = VlanId.vlanId(vlan);
+                return newVlan;
+            } catch (IllegalArgumentException e) {
+                throw new IllegalArgumentException(INVALID_VLAN);
+            }
+        }
+    }
+
+    /**
+     *
+     * @param mode RAW or TAGGED
+     * @return the L2Mode if input is correct
+     * @throws  IllegalArgumentException if not supported mode
+     */
+    public L2Mode parseMode(String mode) {
+
+        if (!mode.equals("RAW") && !mode.equals("TAGGED")) {
+            throw  new IllegalArgumentException(INVALID_L2_MODE);
+        }
+
+        return L2Mode.valueOf(mode);
+    }
+
+    /**
+     *
+     * @param label the mpls label of the pseudowire
+     * @return the MplsLabel
+     * @throws IllegalArgumentException if label is invalid
+     */
+    public MplsLabel parsePWLabel(String label) {
+
+        try {
+            MplsLabel pwLabel = MplsLabel.mplsLabel(label);
+            return pwLabel;
+        } catch (Exception e) {
+            throw new IllegalArgumentException(INVALID_PW_LABEL);
+        }
+    }
+
+    /**
+     * Returns pw description of given pseudo wire id.
+     *
+     * @param tunnelId pseudo wire key
+     * @return set of l2 tunnel descriptions
+     * @throws IllegalArgumentException if wrong format
+     */
+    public L2TunnelDescription getPwDescription(Long tunnelId) {
+        JsonNode pwDescription = object.get(tunnelId.toString());
+        if (!hasFields((ObjectNode) pwDescription,
+                      SRC_CP, SRC_INNER_TAG, SRC_OUTER_TAG,
+                      DST_CP, DST_INNER_TAG, DST_OUTER_TAG,
+                      MODE, SD_TAG, PW_LABEL)) {
+            throw new IllegalArgumentException(MISSING_PARAMS);
+        }
+        String tempString;
+
+        tempString = pwDescription.get(SRC_CP).asText();
+        ConnectPoint srcCp = ConnectPoint.deviceConnectPoint(tempString);
+
+        tempString = pwDescription.get(DST_CP).asText();
+        ConnectPoint dstCp = ConnectPoint.deviceConnectPoint(tempString);
+
+        tempString = pwDescription.get(SRC_INNER_TAG).asText();
+        VlanId srcInnerTag = parseVlan(tempString);
+
+        tempString = pwDescription.get(SRC_OUTER_TAG).asText();
+        VlanId srcOuterTag = parseVlan(tempString);
+
+        tempString = pwDescription.get(DST_INNER_TAG).asText();
+        VlanId dstInnerTag = parseVlan(tempString);
+
+        tempString = pwDescription.get(DST_OUTER_TAG).asText();
+        VlanId dstOuterTag = parseVlan(tempString);
+
+        tempString = pwDescription.get(MODE).asText();
+        L2Mode l2Mode = parseMode(tempString);
+
+        tempString = pwDescription.get(SD_TAG).asText();
+        VlanId sdTag = parseVlan(tempString);
+
+        tempString = pwDescription.get(PW_LABEL).asText();
+        MplsLabel pwLabel = parsePWLabel(tempString);
+
+        L2Tunnel l2Tunnel = new DefaultL2Tunnel(
+                l2Mode,
+                sdTag,
+                tunnelId,
+                pwLabel
+        );
+
+        L2TunnelPolicy l2TunnelPolicy = new DefaultL2TunnelPolicy(
+                tunnelId,
+                srcCp,
+                srcInnerTag,
+                srcOuterTag,
+                dstCp,
+                dstInnerTag,
+                dstOuterTag
+        );
+
+        return new DefaultL2TunnelDescription(l2Tunnel, l2TunnelPolicy);
+    }
+
+    /**
+     * Removes a pseudowire from the configuration tree.
+     * @param pwId Pseudowire id
+     * @return null if pwId did not exist, or the object representing the
+     * udpated configuration tree
+     */
+    public ObjectNode removePseudowire(String pwId) {
+
+        JsonNode value = object.remove(pwId);
+        if (value == null) {
+            return (ObjectNode) value;
+        } else {
+            return object;
+        }
+    }
+
+    /**
+     * Adds a pseudowire to the configuration tree of pwwas. It also checks
+     * if the configuration is valid, if not return null and does not add the node,
+     * if yes return the new configuration. Caller will propagate update events.
+     *
+     * If the pseudowire already exists in the configuration it gets updated.
+     *
+     * @param tunnelId Id of tunnel
+     * @param pwLabel PW label of tunnel
+     * @param cP1 Connection point 1
+     * @param cP1InnerVlan Inner vlan of cp1
+     * @param cP1OuterVlan Outer vlan of cp2
+     * @param cP2 Connection point 2
+     * @param cP2InnerVlan Inner vlan of cp2
+     * @param cP2OuterVlan Outer vlan of cp2
+     * @param mode Mode for the pw
+     * @param sdTag Service delimiting tag for the pw
+     * @return The ObjectNode config if configuration is valid with the new pseudowire
+     * or null.
+     */
+    public ObjectNode addPseudowire(String tunnelId, String pwLabel, String cP1,
+                                    String cP1InnerVlan, String cP1OuterVlan, String cP2,
+                                    String cP2InnerVlan, String cP2OuterVlan,
+                                    String mode, String sdTag) {
+
+
+        ObjectNode newPw = new ObjectNode(JsonNodeFactory.instance);
+
+        // add fields for pseudowire
+        newPw.put(SRC_CP, cP1);
+        newPw.put(DST_CP, cP2);
+        newPw.put(PW_LABEL, pwLabel);
+        newPw.put(SRC_INNER_TAG, cP1InnerVlan);
+        newPw.put(SRC_OUTER_TAG, cP1OuterVlan);
+        newPw.put(DST_INNER_TAG, cP2InnerVlan);
+        newPw.put(DST_OUTER_TAG, cP2OuterVlan);
+        newPw.put(SD_TAG, sdTag);
+        newPw.put(MODE, mode);
+
+        object.set(tunnelId, newPw);
+
+        if (!isValid()) {
+            log.info("Pseudowire could not be created : {}");
+            object.remove(tunnelId);
+            return null;
+        }
+
+        return object;
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfig.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfig.java
new file mode 100644
index 0000000..3e4d17c
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfig.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.MacAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.Config;
+
+import java.util.Set;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * App configuration object for Segment Routing.
+ */
+public class SegmentRoutingAppConfig extends Config<ApplicationId> {
+    private static final String VROUTER_MACS = "vRouterMacs";
+    private static final String SUPPRESS_SUBNET = "suppressSubnet";
+    private static final String SUPPRESS_HOST_BY_PORT = "suppressHostByPort";
+    // TODO We might want to move SUPPRESS_HOST_BY_PROVIDER to Component Config
+    private static final String SUPPRESS_HOST_BY_PROVIDER = "suppressHostByProvider";
+    private static final String MPLS_ECMP = "MPLS-ECMP";
+
+    @Override
+    public boolean isValid() {
+        return hasOnlyFields(VROUTER_MACS, SUPPRESS_SUBNET,
+                SUPPRESS_HOST_BY_PORT, SUPPRESS_HOST_BY_PROVIDER, MPLS_ECMP) &&
+                vRouterMacs() != null &&
+                suppressSubnet() != null && suppressHostByPort() != null &&
+                suppressHostByProvider() != null;
+    }
+
+    /**
+     * Gets MPLS-ECMP configuration from the config.
+     *
+     * @return the configuration of MPLS-ECMP. If it is not
+     *         specified, the default behavior is false.
+     */
+    public boolean mplsEcmp() {
+        return get(MPLS_ECMP, false);
+    }
+
+    /**
+     * Sets MPLS-ECMP to the config.
+     *
+     * @param mplsEcmp the MPLS-ECMP configuration
+     * @return this {@link SegmentRoutingAppConfig}
+     */
+    public SegmentRoutingAppConfig setMplsEcmp(boolean mplsEcmp) {
+        object.put(MPLS_ECMP, mplsEcmp);
+        return this;
+    }
+
+    /**
+     * Gets vRouters from the config.
+     *
+     * @return Set of vRouter MAC addresses, empty is not specified,
+     *         or null if not valid
+     */
+    public Set<MacAddress> vRouterMacs() {
+        if (!object.has(VROUTER_MACS)) {
+            return ImmutableSet.of();
+        }
+
+        ImmutableSet.Builder<MacAddress> builder = ImmutableSet.builder();
+        ArrayNode arrayNode = (ArrayNode) object.path(VROUTER_MACS);
+        for (JsonNode jsonNode : arrayNode) {
+            MacAddress mac;
+
+            String macStr = jsonNode.asText(null);
+            if (macStr == null) {
+                return null;
+            }
+            try {
+                mac = MacAddress.valueOf(macStr);
+            } catch (IllegalArgumentException e) {
+                return null;
+            }
+
+            builder.add(mac);
+        }
+        return builder.build();
+    }
+
+    /**
+     * Sets vRouters to the config.
+     *
+     * @param vRouterMacs a set of vRouter MAC addresses
+     * @return this {@link SegmentRoutingAppConfig}
+     */
+    public SegmentRoutingAppConfig setVRouterMacs(Set<MacAddress> vRouterMacs) {
+        if (vRouterMacs == null) {
+            object.remove(VROUTER_MACS);
+        } else {
+            ArrayNode arrayNode = mapper.createArrayNode();
+
+            vRouterMacs.forEach(mac -> {
+                arrayNode.add(mac.toString());
+            });
+
+            object.set(VROUTER_MACS, arrayNode);
+        }
+        return this;
+    }
+
+    /**
+     * Gets names of ports to which SegmentRouting does not push subnet rules.
+     *
+     * @return Set of port names, empty if not specified, or null
+     *         if not valid
+     */
+    public Set<ConnectPoint> suppressSubnet() {
+        if (!object.has(SUPPRESS_SUBNET)) {
+            return ImmutableSet.of();
+        }
+
+        ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
+        ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_SUBNET);
+        for (JsonNode jsonNode : arrayNode) {
+            String portName = jsonNode.asText(null);
+            if (portName == null) {
+                return null;
+            }
+            try {
+                builder.add(ConnectPoint.deviceConnectPoint(portName));
+            } catch (IllegalArgumentException e) {
+                return null;
+            }
+        }
+        return builder.build();
+    }
+
+    /**
+     * Sets names of ports to which SegmentRouting does not push subnet rules.
+     *
+     * @param suppressSubnet names of ports to which SegmentRouting does not push
+     *                     subnet rules
+     * @return this {@link SegmentRoutingAppConfig}
+     */
+    public SegmentRoutingAppConfig setSuppressSubnet(Set<ConnectPoint> suppressSubnet) {
+        if (suppressSubnet == null) {
+            object.remove(SUPPRESS_SUBNET);
+        } else {
+            ArrayNode arrayNode = mapper.createArrayNode();
+            suppressSubnet.forEach(connectPoint -> {
+                arrayNode.add(connectPoint.deviceId() + "/" + connectPoint.port());
+            });
+            object.set(SUPPRESS_SUBNET, arrayNode);
+        }
+        return this;
+    }
+
+    /**
+     * Gets connect points to which SegmentRouting does not push host rules.
+     *
+     * @return Set of connect points, empty if not specified, or null
+     *         if not valid
+     */
+    public Set<ConnectPoint> suppressHostByPort() {
+        if (!object.has(SUPPRESS_HOST_BY_PORT)) {
+            return ImmutableSet.of();
+        }
+
+        ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
+        ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST_BY_PORT);
+        for (JsonNode jsonNode : arrayNode) {
+            String portName = jsonNode.asText(null);
+            if (portName == null) {
+                return null;
+            }
+            try {
+                builder.add(ConnectPoint.deviceConnectPoint(portName));
+            } catch (IllegalArgumentException e) {
+                return null;
+            }
+        }
+        return builder.build();
+    }
+
+    /**
+     * Sets connect points to which SegmentRouting does not push host rules.
+     *
+     * @param connectPoints connect points to which SegmentRouting does not push
+     *                     host rules
+     * @return this {@link SegmentRoutingAppConfig}
+     */
+    public SegmentRoutingAppConfig setSuppressHostByPort(Set<ConnectPoint> connectPoints) {
+        if (connectPoints == null) {
+            object.remove(SUPPRESS_HOST_BY_PORT);
+        } else {
+            ArrayNode arrayNode = mapper.createArrayNode();
+            connectPoints.forEach(connectPoint -> {
+                arrayNode.add(connectPoint.deviceId() + "/" + connectPoint.port());
+            });
+            object.set(SUPPRESS_HOST_BY_PORT, arrayNode);
+        }
+        return this;
+    }
+
+    /**
+     * Gets provider names from which SegmentRouting does not learn host info.
+     *
+     * @return array of provider names that need to be ignored
+     */
+    public Set<String> suppressHostByProvider() {
+        if (!object.has(SUPPRESS_HOST_BY_PROVIDER)) {
+            return ImmutableSet.of();
+        }
+
+        ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+        ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST_BY_PROVIDER);
+        for (JsonNode jsonNode : arrayNode) {
+            String providerName = jsonNode.asText(null);
+            if (providerName == null) {
+                return null;
+            }
+            builder.add(providerName);
+        }
+        return builder.build();
+    }
+
+    /**
+     * Sets provider names from which SegmentRouting does not learn host info.
+     *
+     * @param providers set of provider names
+     * @return this {@link SegmentRoutingAppConfig}
+     */
+    public SegmentRoutingAppConfig setSuppressHostByProvider(Set<String> providers) {
+        if (providers == null) {
+            object.remove(SUPPRESS_HOST_BY_PROVIDER);
+        } else {
+            ArrayNode arrayNode = mapper.createArrayNode();
+            providers.forEach(arrayNode::add);
+            object.set(SUPPRESS_HOST_BY_PROVIDER, arrayNode);
+        }
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("vRouterMacs", vRouterMacs())
+                .add("suppressSubnet", suppressSubnet())
+                .add("suppressHostByPort", suppressHostByPort())
+                .add("suppressHostByProvider", suppressHostByProvider())
+                .add("mplsEcmp", mplsEcmp())
+                .toString();
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingDeviceConfig.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingDeviceConfig.java
new file mode 100644
index 0000000..7959df6
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingDeviceConfig.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableMap;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.Config;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * Configuration object for Segment Routing Application.
+ */
+public class SegmentRoutingDeviceConfig extends Config<DeviceId> {
+    private static final String NAME = "name";
+    private static final String IP4 = "ipv4Loopback";
+    private static final String IP6 = "ipv6Loopback";
+    private static final String MAC = "routerMac";
+    private static final String IP4_SID = "ipv4NodeSid";
+    private static final String IP6_SID = "ipv6NodeSid";
+    private static final String EDGE = "isEdgeRouter";
+    /**
+     * Adjancency SIDs config.
+     *
+     * @deprecated in Loon (1.11). We are not using and do not plan to use it.
+     */
+    @Deprecated
+    private static final String ADJSIDS = "adjacencySids";
+
+    /**
+     * Adjancency SID config.
+     *
+     * @deprecated in Loon (1.11). We are not using and do not plan to use it.
+     */
+    @Deprecated
+    private static final String ADJSID = "adjSid";
+
+    /**
+     * Adjancency port config.
+     *
+     * @deprecated in Loon (1.11). We are not using and do not plan to use it.
+     */
+    @Deprecated
+    private static final String PORTS = "ports";
+
+    private static final String PAIR_DEVICE_ID = "pairDeviceId";
+    private static final String PAIR_LOCAL_PORT = "pairLocalPort";
+
+    @Override
+    public boolean isValid() {
+        return hasOnlyFields(NAME, IP4, IP6, MAC, IP4_SID, IP6_SID, EDGE, ADJSIDS, ADJSID, PORTS,
+                             PAIR_DEVICE_ID, PAIR_LOCAL_PORT) &&
+                name() != null &&
+                routerIpv4() != null && (!hasField(IP6) || routerIpv6() != null) &&
+                routerMac() != null &&
+                nodeSidIPv4() != -1 && (!hasField(IP6_SID) || nodeSidIPv6() != -1) &&
+                isEdgeRouter() != null &&
+                adjacencySids() != null &&
+                // pairDeviceId and pairLocalPort must be both configured or both omitted
+                (hasField(PAIR_DEVICE_ID) == hasField(PAIR_LOCAL_PORT)) &&
+                (!hasField(PAIR_DEVICE_ID) || pairDeviceId() != null) &&
+                (!hasField(PAIR_LOCAL_PORT) || pairLocalPort() != null);
+    }
+
+    /**
+     * Gets the name of the router.
+     *
+     * @return Optional name of the router. May be empty if not configured.
+     */
+    public Optional<String> name() {
+        String name = get(NAME, null);
+        return name != null ? Optional.of(name) : Optional.empty();
+    }
+
+    /**
+     * Sets the name of the router.
+     *
+     * @param name name of the router.
+     * @return the config of the router.
+     */
+    public SegmentRoutingDeviceConfig setName(String name) {
+        return (SegmentRoutingDeviceConfig) setOrClear(NAME, name);
+    }
+
+    /**
+     * Gets the IPv4 address of the router.
+     *
+     * @return IP address of the router. Or null if not configured.
+     */
+    public Ip4Address routerIpv4() {
+        String ip = get(IP4, null);
+        return ip != null ? Ip4Address.valueOf(ip) : null;
+    }
+
+    /**
+     * Gets the IPv6 address of the router.
+     *
+     * @return IP address of the router. Or null if not configured.
+     */
+    public Ip6Address routerIpv6() {
+        String ip = get(IP6, null);
+        return ip != null ? Ip6Address.valueOf(ip) : null;
+    }
+
+    /**
+     * Sets the IPv4 address of the router.
+     *
+     * @param ip IPv4 address of the router.
+     * @return the config of the router.
+     */
+    public SegmentRoutingDeviceConfig setRouterIpv4(String ip) {
+        return (SegmentRoutingDeviceConfig) setOrClear(IP4, ip);
+    }
+
+    /**
+     * Sets the IPv6 address of the router.
+     *
+     * @param ip IPv6 address of the router.
+     * @return the config of the router.
+     */
+    public SegmentRoutingDeviceConfig setRouterIpv6(String ip) {
+        return (SegmentRoutingDeviceConfig) setOrClear(IP6, ip);
+    }
+
+    /**
+     * Gets the MAC address of the router.
+     *
+     * @return MAC address of the router. Or null if not configured.
+     */
+    public MacAddress routerMac() {
+        String mac = get(MAC, null);
+        return mac != null ? MacAddress.valueOf(mac) : null;
+    }
+
+    /**
+     * Sets the MAC address of the router.
+     *
+     * @param mac MAC address of the router.
+     * @return the config of the router.
+     */
+    public SegmentRoutingDeviceConfig setRouterMac(String mac) {
+        return (SegmentRoutingDeviceConfig) setOrClear(MAC, mac);
+    }
+
+    /**
+     * Gets the IPv4 node SID of the router.
+     *
+     * @return node SID of the router. Or -1 if not configured.
+     */
+    public int nodeSidIPv4() {
+        return get(IP4_SID, -1);
+    }
+
+    /**
+     * Gets the IPv6 node SID of the router.
+     *
+     * @return node SID of the router. Or -1 if not configured.
+     */
+    public int nodeSidIPv6() {
+        return get(IP6_SID, -1);
+    }
+
+    /**
+     * Sets the node IPv4 node SID of the router.
+     *
+     * @param sid node SID of the router.
+     * @return the config of the router.
+     */
+    public SegmentRoutingDeviceConfig setNodeSidIPv4(int sid) {
+        return (SegmentRoutingDeviceConfig) setOrClear(IP4_SID, sid);
+    }
+
+    /**
+     * Sets the node IPv6 node SID of the router.
+     *
+     * @param sid node SID of the router.
+     * @return the config of the router.
+     */
+    public SegmentRoutingDeviceConfig setNodeSidIPv6(int sid) {
+        return (SegmentRoutingDeviceConfig) setOrClear(IP6_SID, sid);
+    }
+
+    /**
+     * Checks if the router is an edge router.
+     *
+     * @return true if the router is an edge router.
+     *         false if the router is not an edge router.
+     *         null if the value is not configured.
+     */
+    public Boolean isEdgeRouter() {
+        String isEdgeRouter = get(EDGE, null);
+        return isEdgeRouter != null ?
+                Boolean.valueOf(isEdgeRouter) :
+                null;
+    }
+
+    /**
+     * Specifies if the router is an edge router.
+     *
+     * @param isEdgeRouter true if the router is an edge router.
+     * @return the config of the router.
+     */
+    public SegmentRoutingDeviceConfig setIsEdgeRouter(boolean isEdgeRouter) {
+        return (SegmentRoutingDeviceConfig) setOrClear(EDGE, isEdgeRouter);
+    }
+
+    /**
+     * Gets the adjacency SIDs of the router.
+     *
+     * @return adjacency SIDs of the router. Or null if not configured.
+     */
+    public Map<Integer, Set<Integer>> adjacencySids() {
+        if (!object.has(ADJSIDS)) {
+            return null;
+        }
+
+        Map<Integer, Set<Integer>> adjacencySids = new HashMap<>();
+        ArrayNode adjacencySidsNode = (ArrayNode) object.path(ADJSIDS);
+        for (JsonNode adjacencySidNode : adjacencySidsNode) {
+            int asid = adjacencySidNode.path(ADJSID).asInt(-1);
+            if (asid == -1) {
+                return null;
+            }
+
+            HashSet<Integer> ports = new HashSet<>();
+            ArrayNode portsNode = (ArrayNode) adjacencySidNode.path(PORTS);
+            for (JsonNode portNode : portsNode) {
+                int port = portNode.asInt(-1);
+                if (port == -1) {
+                    return null;
+                }
+                ports.add(port);
+            }
+            adjacencySids.put(asid, ports);
+        }
+
+        return ImmutableMap.copyOf(adjacencySids);
+    }
+
+    /**
+     * Sets the adjacency SIDs of the router.
+     *
+     * @param adjacencySids adjacency SIDs of the router.
+     * @return the config of the router.
+     */
+    public SegmentRoutingDeviceConfig setAdjacencySids(Map<Integer, Set<Integer>> adjacencySids) {
+        if (adjacencySids == null) {
+            object.remove(ADJSIDS);
+        } else {
+            ArrayNode adjacencySidsNode = mapper.createArrayNode();
+
+            adjacencySids.forEach((sid, ports) -> {
+                ObjectNode adjacencySidNode = mapper.createObjectNode();
+
+                adjacencySidNode.put(ADJSID, sid);
+
+                ArrayNode portsNode = mapper.createArrayNode();
+                ports.forEach(port -> {
+                    portsNode.add(port.toString());
+                });
+                adjacencySidNode.set(PORTS, portsNode);
+
+                adjacencySidsNode.add(adjacencySidNode);
+            });
+
+            object.set(ADJSIDS, adjacencySidsNode);
+        }
+
+        return this;
+    }
+
+    /**
+     * Gets the pair device id.
+     *
+     * @return pair device id; Or null if not configured.
+     */
+    public DeviceId pairDeviceId() {
+        String pairDeviceId = get(PAIR_DEVICE_ID, null);
+        return pairDeviceId != null ? DeviceId.deviceId(pairDeviceId) : null;
+    }
+
+    /**
+     * Sets the pair device id.
+     *
+     * @param deviceId pair device id
+     * @return this configuration
+     */
+    public SegmentRoutingDeviceConfig setPairDeviceId(DeviceId deviceId) {
+        return (SegmentRoutingDeviceConfig) setOrClear(PAIR_DEVICE_ID, deviceId.toString());
+    }
+
+    /**
+     * Gets the pair local port.
+     *
+     * @return pair local port; Or null if not configured.
+     */
+    public PortNumber pairLocalPort() {
+        long pairLocalPort = get(PAIR_LOCAL_PORT, -1L);
+        return pairLocalPort != -1L ? PortNumber.portNumber(pairLocalPort) : null;
+    }
+
+    /**
+     * Sets the pair local port.
+     *
+     * @param portNumber pair local port
+     * @return this configuration
+     */
+    public SegmentRoutingDeviceConfig setPairLocalPort(PortNumber portNumber) {
+        return (SegmentRoutingDeviceConfig) setOrClear(PAIR_LOCAL_PORT, portNumber.toLong());
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/XConnectConfig.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/XConnectConfig.java
new file mode 100644
index 0000000..76a3917
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/XConnectConfig.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.Config;
+import org.onosproject.segmentrouting.storekey.XConnectStoreKey;
+
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Configuration object for cross-connect.
+ */
+public class XConnectConfig extends Config<ApplicationId> {
+    private static final String VLAN = "vlan";
+    private static final String PORTS = "ports";
+    private static final String NAME = "name"; // dummy field for naming
+
+    private static final String UNEXPECTED_FIELD_NAME = "Unexpected field name";
+
+    @Override
+    public boolean isValid() {
+        try {
+            getXconnects().forEach(this::getPorts);
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns all xconnect keys.
+     *
+     * @return all keys (device/vlan pairs)
+     * @throws IllegalArgumentException if wrong format
+     */
+    public Set<XConnectStoreKey> getXconnects() {
+        ImmutableSet.Builder<XConnectStoreKey> builder = ImmutableSet.builder();
+        object.fields().forEachRemaining(entry -> {
+            DeviceId deviceId = DeviceId.deviceId(entry.getKey());
+            builder.addAll(getXconnects(deviceId));
+        });
+        return builder.build();
+    }
+
+    /**
+     * Returns xconnect keys of given device.
+     *
+     * @param deviceId ID of the device from which we want to get XConnect info
+     * @return xconnect keys (device/vlan pairs) of given device
+     * @throws IllegalArgumentException if wrong format
+     */
+    public Set<XConnectStoreKey> getXconnects(DeviceId deviceId) {
+        ImmutableSet.Builder<XConnectStoreKey> builder = ImmutableSet.builder();
+        JsonNode vlanPortPair = object.get(deviceId.toString());
+        if (vlanPortPair != null) {
+            vlanPortPair.forEach(jsonNode -> {
+                if (!hasOnlyFields((ObjectNode) jsonNode, VLAN, PORTS, NAME)) {
+                    throw new IllegalArgumentException(UNEXPECTED_FIELD_NAME);
+                }
+                VlanId vlanId = VlanId.vlanId((short) jsonNode.get(VLAN).asInt());
+                builder.add(new XConnectStoreKey(deviceId, vlanId));
+            });
+        }
+        return builder.build();
+    }
+
+    /**
+     * Returns ports of given xconnect key.
+     *
+     * @param xconnect xconnect key
+     * @return set of two ports associated with given xconnect key
+     * @throws IllegalArgumentException if wrong format
+     */
+    public Set<PortNumber> getPorts(XConnectStoreKey xconnect) {
+        ImmutableSet.Builder<PortNumber> builder = ImmutableSet.builder();
+        object.get(xconnect.deviceId().toString()).forEach(vlanPortsPair -> {
+            if (xconnect.vlanId().toShort() == vlanPortsPair.get(VLAN).asInt()) {
+                int portCount = vlanPortsPair.get(PORTS).size();
+                checkArgument(portCount == 2,
+                        "Expect 2 ports but found " + portCount + " on " + xconnect);
+                vlanPortsPair.get(PORTS).forEach(portNode -> {
+                    builder.add(PortNumber.portNumber(portNode.asInt()));
+                });
+            }
+        });
+        return builder.build();
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/package-info.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/package-info.java
new file mode 100644
index 0000000..a664a8f
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-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.
+ */
+
+/**
+ * Segment routing network configuration mechanism.
+ */
+package org.onosproject.segmentrouting.config;
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
new file mode 100644
index 0000000..75cab32
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
@@ -0,0 +1,1424 @@
+/*
+ * Copyright 2015-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.grouphandler;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import org.apache.commons.lang3.RandomUtils;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+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.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.DefaultObjectiveContext;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.DefaultRoutingHandler;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceProperties;
+import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;
+import org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey;
+import org.onosproject.segmentrouting.storekey.VlanNextObjectiveStoreKey;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.slf4j.Logger;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newScheduledThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.segmentrouting.SegmentRoutingManager.INTERNAL_VLAN;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Default ECMP group handler creation module. This component creates a set of
+ * ECMP groups for every neighbor that this device is connected to based on
+ * whether the current device is an edge device or a transit device.
+ */
+public class DefaultGroupHandler {
+    private static final Logger log = getLogger(DefaultGroupHandler.class);
+
+    private static final long VERIFY_INTERVAL = 30; // secs
+
+    protected final DeviceId deviceId;
+    protected final ApplicationId appId;
+    protected final DeviceProperties deviceConfig;
+    protected final List<Integer> allSegmentIds;
+    protected int ipv4NodeSegmentId = -1;
+    protected int ipv6NodeSegmentId = -1;
+    protected boolean isEdgeRouter = false;
+    protected MacAddress nodeMacAddr = null;
+    protected LinkService linkService;
+    protected FlowObjectiveService flowObjectiveService;
+    /**
+     * local store for neighbor-device-ids and the set of ports on this device
+     * that connect to the same neighbor.
+     */
+    protected ConcurrentHashMap<DeviceId, Set<PortNumber>> devicePortMap =
+            new ConcurrentHashMap<>();
+    /**
+     *  local store for ports on this device connected to neighbor-device-id.
+     */
+    protected ConcurrentHashMap<PortNumber, DeviceId> portDeviceMap =
+            new ConcurrentHashMap<>();
+
+    // distributed store for (device+destination-set) mapped to next-id and neighbors
+    protected EventuallyConsistentMap<DestinationSetNextObjectiveStoreKey, NextNeighbors>
+            dsNextObjStore = null;
+    // distributed store for (device+subnet-ip-prefix) mapped to next-id
+    protected EventuallyConsistentMap<VlanNextObjectiveStoreKey, Integer>
+            vlanNextObjStore = null;
+    // distributed store for (device+port+treatment) mapped to next-id
+    protected EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer>
+            portNextObjStore = null;
+    private SegmentRoutingManager srManager;
+
+    private ScheduledExecutorService executorService
+    = newScheduledThreadPool(1, groupedThreads("bktCorrector", "bktC-%d", log));
+
+    protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
+            .register(URI.class).register(HashSet.class)
+            .register(DeviceId.class).register(PortNumber.class)
+            .register(DestinationSet.class).register(PolicyGroupIdentifier.class)
+            .register(PolicyGroupParams.class)
+            .register(GroupBucketIdentifier.class)
+            .register(GroupBucketIdentifier.BucketOutputType.class);
+
+    protected DefaultGroupHandler(DeviceId deviceId, ApplicationId appId,
+                                  DeviceProperties config,
+                                  LinkService linkService,
+                                  FlowObjectiveService flowObjService,
+                                  SegmentRoutingManager srManager) {
+        this.deviceId = checkNotNull(deviceId);
+        this.appId = checkNotNull(appId);
+        this.deviceConfig = checkNotNull(config);
+        this.linkService = checkNotNull(linkService);
+        this.allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds());
+        try {
+            this.ipv4NodeSegmentId = config.getIPv4SegmentId(deviceId);
+            this.ipv6NodeSegmentId = config.getIPv6SegmentId(deviceId);
+            this.isEdgeRouter = config.isEdgeDevice(deviceId);
+            this.nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage()
+                    + " Skipping value assignment in DefaultGroupHandler");
+        }
+        this.flowObjectiveService = flowObjService;
+        this.dsNextObjStore = srManager.dsNextObjStore();
+        this.vlanNextObjStore = srManager.vlanNextObjStore();
+        this.portNextObjStore = srManager.portNextObjStore();
+        this.srManager = srManager;
+        executorService.scheduleWithFixedDelay(new BucketCorrector(), 10,
+                                               VERIFY_INTERVAL,
+                                               TimeUnit.SECONDS);
+        populateNeighborMaps();
+    }
+
+    /**
+     * Gracefully shuts down a groupHandler. Typically called when the handler is
+     * no longer needed.
+     */
+    public void shutdown() {
+        executorService.shutdown();
+    }
+
+    /**
+     * Creates a group handler object.
+     *
+     * @param deviceId device identifier
+     * @param appId application identifier
+     * @param config interface to retrieve the device properties
+     * @param linkService link service object
+     * @param flowObjService flow objective service object
+     * @param srManager segment routing manager
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return default group handler type
+     */
+    public static DefaultGroupHandler createGroupHandler(
+                                                         DeviceId deviceId,
+                                                         ApplicationId appId,
+                                                         DeviceProperties config,
+                                                         LinkService linkService,
+                                                         FlowObjectiveService flowObjService,
+                                                         SegmentRoutingManager srManager)
+                                                                 throws DeviceConfigNotFoundException {
+        return new DefaultGroupHandler(deviceId, appId, config,
+                                       linkService,
+                                       flowObjService,
+                                       srManager);
+    }
+
+    /**
+     * Updates local stores for link-src device/port to neighbor (link-dst).
+     *
+     * @param link the infrastructure link
+     */
+    public void portUpForLink(Link link) {
+        if (!link.src().deviceId().equals(deviceId)) {
+            log.warn("linkUp: deviceId{} doesn't match with link src {}",
+                     deviceId, link.src().deviceId());
+            return;
+        }
+
+        log.info("* portUpForLink: Device {} linkUp at local port {} to "
+                + "neighbor {}", deviceId, link.src().port(), link.dst().deviceId());
+        // ensure local state is updated even if linkup is aborted later on
+        addNeighborAtPort(link.dst().deviceId(),
+                          link.src().port());
+    }
+
+    /**
+     * Updates local stores for port that has gone down.
+     *
+     * @param port port number that has gone down
+     */
+    public void portDown(PortNumber port) {
+        if (portDeviceMap.get(port) == null) {
+            log.warn("portDown: unknown port");
+            return;
+        }
+
+        log.debug("Device {} portDown {} to neighbor {}", deviceId, port,
+                  portDeviceMap.get(port));
+        devicePortMap.get(portDeviceMap.get(port)).remove(port);
+        portDeviceMap.remove(port);
+    }
+
+    /**
+     * Checks all groups in the src-device of link for neighbor sets that include
+     * the dst-device of link, and edits the hash groups according to link up
+     * or down. Should only be called by the master instance of the src-switch
+     * of link. Typically used when there are no route-path changes due to the
+     * link up or down, as the ECMPspg does not change.
+     *
+     * @param link the infrastructure link that has gone down or come up
+     * @param linkDown true if link has gone down
+     * @param firstTime true if link has come up for the first time i.e a link
+     *                  not seen-before
+     */
+    public void retryHash(Link link, boolean linkDown, boolean firstTime) {
+        MacAddress neighborMac;
+        try {
+            neighborMac = deviceConfig.getDeviceMac(link.dst().deviceId());
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting retryHash.");
+            return;
+        }
+        // find all the destinationSets related to link
+        Set<DestinationSetNextObjectiveStoreKey> dsKeySet = dsNextObjStore.entrySet()
+                .stream()
+                .filter(entry -> entry.getKey().deviceId().equals(deviceId))
+                // Filter out PW transit groups or include them if MPLS ECMP is supported
+                .filter(entry -> !entry.getKey().destinationSet().mplsSet() ||
+                        (entry.getKey().destinationSet().mplsSet() && srManager.getMplsEcmp()))
+                .filter(entry -> entry.getValue().containsNextHop(link.dst().deviceId()))
+                .map(entry -> entry.getKey())
+                .collect(Collectors.toSet());
+
+        log.debug("retryHash: dsNextObjStore contents for linkSrc {} -> linkDst {}: {}",
+                  deviceId, link.dst().deviceId(), dsKeySet);
+
+        for (DestinationSetNextObjectiveStoreKey dsKey : dsKeySet) {
+            NextNeighbors nextHops = dsNextObjStore.get(dsKey);
+            if (nextHops == null) {
+                log.warn("retryHash in device {}, but global store has no record "
+                         + "for dsKey:{}", deviceId, dsKey);
+                continue;
+            }
+            int nextId = nextHops.nextId();
+            Set<DeviceId> dstSet = nextHops.getDstForNextHop(link.dst().deviceId());
+            if (!linkDown) {
+                List<PortLabel> pl = Lists.newArrayList();
+                if (firstTime) {
+                    // some links may have come up before the next-objective was created
+                    // we take this opportunity to ensure other ports to same next-hop-dst
+                    // are part of the hash group (see CORD-1180). Duplicate additions
+                    // to the same hash group are avoided by the driver.
+                    for (PortNumber p : devicePortMap.get(link.dst().deviceId())) {
+                        dstSet.forEach(dst -> {
+                            int edgeLabel = dsKey.destinationSet().getEdgeLabel(dst);
+                            pl.add(new PortLabel(p, edgeLabel));
+                        });
+                    }
+                    addToHashedNextObjective(pl, neighborMac, nextId);
+                } else {
+                    // handle only the port that came up
+                    dstSet.forEach(dst -> {
+                        int edgeLabel = dsKey.destinationSet().getEdgeLabel(dst);
+                        pl.add(new PortLabel(link.src().port(), edgeLabel));
+                    });
+                    addToHashedNextObjective(pl, neighborMac, nextId);
+                }
+            } else {
+                // linkdown
+                List<PortLabel> pl = Lists.newArrayList();
+                dstSet.forEach(dst -> {
+                    int edgeLabel = dsKey.destinationSet().getEdgeLabel(dst);
+                    pl.add(new PortLabel(link.src().port(), edgeLabel));
+                });
+                removeFromHashedNextObjective(pl, neighborMac, nextId);
+            }
+        }
+    }
+
+    /**
+     * Utility class for associating output ports and the corresponding MPLS
+     * labels to push. In dual-homing, there are different labels to push
+     * corresponding to the destination switches in an edge-pair. If both
+     * destinations are reachable via the same spine, then the output-port to
+     * the spine will be associated with two labels i.e. there will be two
+     * PortLabel objects for the same port but with different labels.
+     */
+    private class PortLabel {
+        PortNumber port;
+        int edgeLabel;
+
+        PortLabel(PortNumber port, int edgeLabel) {
+            this.port = port;
+            this.edgeLabel = edgeLabel;
+        }
+
+        @Override
+        public String toString() {
+            return port.toString() + "/" + String.valueOf(edgeLabel);
+        }
+    }
+
+    /**
+     * Makes a call to the FlowObjective service to add buckets to
+     * a hashed group. User must ensure that all the ports & labels are meant
+     * same neighbor (ie. dstMac).
+     *
+     * @param portLabels a collection of port & label combinations to add
+     *                   to the hash group identified by the nextId
+     * @param dstMac destination mac address of next-hop
+     * @param nextId id for next-objective to which buckets will be added
+     *
+     */
+    private void addToHashedNextObjective(Collection<PortLabel> portLabels,
+                                          MacAddress dstMac, Integer nextId) {
+        // setup metadata to pass to nextObjective - indicate the vlan on egress
+        // if needed by the switch pipeline. Since hashed next-hops are always to
+        // other neighboring routers, there is no subnet assigned on those ports.
+        TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
+        metabuilder.matchVlanId(INTERNAL_VLAN);
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder()
+                .withId(nextId)
+                .withType(NextObjective.Type.HASHED)
+                .withMeta(metabuilder.build())
+                .fromApp(appId);
+        // Create the new buckets to be updated
+        portLabels.forEach(pl -> {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(pl.port)
+                .setEthDst(dstMac)
+                .setEthSrc(nodeMacAddr);
+            if (pl.edgeLabel != DestinationSet.NO_EDGE_LABEL) {
+                tBuilder.pushMpls()
+                    .copyTtlOut()
+                    .setMpls(MplsLabel.mplsLabel(pl.edgeLabel));
+            }
+            nextObjBuilder.addTreatment(tBuilder.build());
+        });
+
+        log.debug("addToHash in device {}: Adding Bucket with port/label {} "
+                + "to nextId {}", deviceId, portLabels, nextId);
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("addToHash port/label {} addedTo "
+                        + "NextObj {} on {}", portLabels, nextId, deviceId),
+                (objective, error) ->
+                        log.warn("addToHash failed to add port/label {} to"
+                                + " NextObj {} on {}: {}", portLabels,
+                                 nextId, deviceId, error));
+        NextObjective nextObjective = nextObjBuilder.addToExisting(context);
+        flowObjectiveService.next(deviceId, nextObjective);
+    }
+
+    /**
+     * Makes a call to the FlowObjective service to remove buckets from
+     * a hash group. User must ensure that all the ports & labels are meant
+     * same neighbor (ie. dstMac).
+     *
+     * @param portLabels a collection of port & label combinations to remove
+     *                   from the hash group identified by the nextId
+     * @param dstMac destination mac address of next-hop
+     * @param nextId id for next-objective from which buckets will be removed
+     */
+    private void removeFromHashedNextObjective(Collection<PortLabel> portLabels,
+                                               MacAddress dstMac, Integer nextId) {
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder()
+                .withType(NextObjective.Type.HASHED) //same as original
+                .withId(nextId)
+                .fromApp(appId);
+        // Create the buckets to be removed
+        portLabels.forEach(pl -> {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(pl.port)
+                .setEthDst(dstMac)
+                .setEthSrc(nodeMacAddr);
+            if (pl.edgeLabel != DestinationSet.NO_EDGE_LABEL) {
+                tBuilder.pushMpls()
+                    .copyTtlOut()
+                    .setMpls(MplsLabel.mplsLabel(pl.edgeLabel));
+            }
+            nextObjBuilder.addTreatment(tBuilder.build());
+        });
+        log.debug("removeFromHash in device {}: Removing Bucket with port/label"
+                + " {} from nextId {}", deviceId, portLabels, nextId);
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("port/label {} removedFrom NextObj"
+                        + " {} on {}", portLabels, nextId, deviceId),
+                (objective, error) ->
+                log.warn("port/label {} failed to removeFrom NextObj {} on "
+                        + "{}: {}", portLabels, nextId, deviceId, error));
+        NextObjective nextObjective = nextObjBuilder.removeFromExisting(context);
+        flowObjectiveService.next(deviceId, nextObjective);
+    }
+
+    /**
+     * Checks all the hash-groups in the target-switch meant for the destination
+     * switch, and either adds or removes buckets to make the neighbor-set
+     * match the given next-hops. Typically called by the master instance of the
+     * destination switch, which may be different from the master instance of the
+     * target switch where hash-group changes are made.
+     *
+     * @param targetSw the switch in which the hash groups will be edited
+     * @param nextHops the current next hops for the target switch to reach
+     *                  the dest sw
+     * @param destSw  the destination switch
+     * @param revoke true if hash groups need to remove buckets from the
+     *                          the groups to match the current next hops
+     * @return true if calls are made to edit buckets, or if no edits are required
+     */
+    public boolean fixHashGroups(DeviceId targetSw, Set<DeviceId> nextHops,
+                                 DeviceId destSw, boolean revoke) {
+        // temporary storage of keys to be updated
+        Map<DestinationSetNextObjectiveStoreKey, Set<DeviceId>> tempStore =
+                new HashMap<>();
+        boolean foundNextObjective = false, success = true;
+
+        // retrieve hash-groups meant for destSw, which have destinationSets
+        // with different neighbors than the given next-hops
+        for (DestinationSetNextObjectiveStoreKey dskey : dsNextObjStore.keySet()) {
+            if (!dskey.deviceId().equals(targetSw) ||
+                    !dskey.destinationSet().getDestinationSwitches().contains(destSw)) {
+                continue;
+            }
+            foundNextObjective = true;
+            NextNeighbors nhops = dsNextObjStore.get(dskey);
+            Set<DeviceId> currNeighbors = nhops.nextHops(destSw);
+            int edgeLabel = dskey.destinationSet().getEdgeLabel(destSw);
+            Integer nextId = nhops.nextId();
+
+            if (currNeighbors == null || nextHops == null) {
+                log.warn("fixing hash groups but found currNeighbors:{} or nextHops:{}"
+                        + " in targetSw:{} for dstSw:{}", currNeighbors, nextHops,
+                        targetSw, destSw);
+                success &= false;
+                continue;
+            }
+
+            Set<DeviceId> diff;
+            if (revoke) {
+                diff = Sets.difference(currNeighbors, nextHops);
+                log.debug("targetSw:{} -> dstSw:{} in nextId:{} has current next "
+                        + "hops:{} ..removing {}", targetSw, destSw, nextId,
+                        currNeighbors, diff);
+            } else {
+                diff = Sets.difference(nextHops, currNeighbors);
+                log.debug("targetSw:{} -> dstSw:{} in nextId:{} has current next "
+                        + "hops:{} ..adding {}", targetSw, destSw, nextId,
+                        currNeighbors, diff);
+            }
+            boolean suc = updateAllPortsToNextHop(diff, edgeLabel, nextId,
+                                                  revoke);
+            if (suc) {
+                // to update neighbor set with changes made
+                if (revoke) {
+                    tempStore.put(dskey, Sets.difference(currNeighbors, diff));
+                } else {
+                    tempStore.put(dskey, Sets.union(currNeighbors, diff));
+                }
+            }
+            success &= suc;
+        }
+
+        if (!foundNextObjective) {
+            log.debug("Cannot find any nextObjectives for route targetSw:{} "
+                    + "-> dstSw:{}", targetSw, destSw);
+            return true; // nothing to do, return true so ECMPspg is updated
+        }
+
+        // update the dsNextObjectiveStore with new destinationSet to nextId mappings
+        for (DestinationSetNextObjectiveStoreKey key : tempStore.keySet()) {
+            NextNeighbors currentNextHops = dsNextObjStore.get(key);
+            if (currentNextHops == null) {
+                log.warn("fixHashGroups could not update global store in "
+                        + "device {} .. missing nextNeighbors for key {}",
+                        deviceId, key);
+                continue;
+            }
+            Set<DeviceId> newNeighbors = new HashSet<>();
+            newNeighbors.addAll(tempStore.get(key));
+            Map<DeviceId, Set<DeviceId>> oldDstNextHops =
+                    ImmutableMap.copyOf(currentNextHops.dstNextHops());
+            currentNextHops.dstNextHops().put(destSw, newNeighbors); //local change
+            log.debug("Updating nsNextObjStore target:{} -> dst:{} in key:{} nextId:{}",
+                      targetSw, destSw, key, currentNextHops.nextId());
+            log.debug("Old dstNextHops: {}", oldDstNextHops);
+            log.debug("New dstNextHops: {}", currentNextHops.dstNextHops());
+            // update global store
+            dsNextObjStore.put(key,
+                               new NextNeighbors(currentNextHops.dstNextHops(),
+                                                 currentNextHops.nextId()));
+        }
+        // even if one fails and others succeed, return false so ECMPspg not updated
+        return success;
+    }
+
+    /**
+     * Updates the DestinationSetNextObjectiveStore with any per-destination nexthops
+     * that are not already in the store for the given DestinationSet. Note that
+     * this method does not remove existing next hops for the destinations in the
+     * DestinationSet.
+     *
+     * @param ds the DestinationSet for which the next hops need to be updated
+     * @param newDstNextHops a map of per-destination next hops to update the
+     *                          destinationSet with
+     * @return true if successful in updating all next hops
+     */
+    private boolean updateNextHops(DestinationSet ds,
+                                  Map<DeviceId, Set<DeviceId>> newDstNextHops) {
+        DestinationSetNextObjectiveStoreKey key =
+                new DestinationSetNextObjectiveStoreKey(deviceId, ds);
+        NextNeighbors currNext = dsNextObjStore.get(key);
+        Map<DeviceId, Set<DeviceId>> currDstNextHops = currNext.dstNextHops();
+
+        // add newDstNextHops to currDstNextHops for each dst
+        boolean success = true;
+        for (DeviceId dstSw : ds.getDestinationSwitches()) {
+            Set<DeviceId> currNhops = currDstNextHops.get(dstSw);
+            Set<DeviceId> newNhops = newDstNextHops.get(dstSw);
+            currNhops = (currNhops == null) ? Sets.newHashSet() : currNhops;
+            newNhops = (newNhops == null) ? Sets.newHashSet() : newNhops;
+            int edgeLabel = ds.getEdgeLabel(dstSw);
+            int nextId = currNext.nextId();
+
+            // new next hops should be added
+            boolean suc = updateAllPortsToNextHop(Sets.difference(newNhops, currNhops),
+                                                  edgeLabel, nextId, false);
+            if (suc) {
+                currNhops.addAll(newNhops);
+                currDstNextHops.put(dstSw, currNhops); // this is only a local change
+            }
+            success &= suc;
+        }
+
+        if (success) {
+            // update global store
+            dsNextObjStore.put(key, new NextNeighbors(currDstNextHops,
+                                                      currNext.nextId()));
+            log.debug("Updated device:{} ds:{} new next-hops: {}", deviceId, ds,
+                      dsNextObjStore.get(key));
+        }
+        return success;
+    }
+
+    /**
+     * Adds or removes buckets for all ports to a set of neighbor devices. Caller
+     * needs to ensure that the  given neighbors are all next hops towards the
+     * same destination (represented by the given edgeLabel).
+     *
+     * @param neighbors set of neighbor device ids
+     * @param edgeLabel MPLS label to use in buckets
+     * @param nextId the nextObjective to change
+     * @param revoke true if buckets need to be removed, false if they need to
+     *          be added
+     * @return true if successful in adding or removing buckets for all ports
+     *                  to the neighbors
+     */
+    private boolean updateAllPortsToNextHop(Set<DeviceId> neighbors, int edgeLabel,
+                                         int nextId, boolean revoke) {
+        for (DeviceId neighbor : neighbors) {
+            MacAddress neighborMac;
+            try {
+                neighborMac = deviceConfig.getDeviceMac(neighbor);
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn(e.getMessage() + " Aborting updateAllPortsToNextHop"
+                        + " for nextId:" + nextId);
+                return false;
+            }
+            Collection<PortNumber> portsToNeighbor = devicePortMap.get(neighbor);
+            if (portsToNeighbor == null || portsToNeighbor.isEmpty()) {
+                log.warn("No ports found in dev:{} for neighbor:{} .. cannot "
+                        + "updateAllPortsToNextHop for nextId: {}",
+                         deviceId, neighbor, nextId);
+                return false;
+            }
+            List<PortLabel> pl = Lists.newArrayList();
+            portsToNeighbor.forEach(p -> pl.add(new PortLabel(p, edgeLabel)));
+            if (revoke) {
+                log.debug("updateAllPortsToNextHops in device {}: Removing Bucket(s) "
+                        + "with Port/Label:{} to next object id {}",
+                        deviceId, pl, nextId);
+                removeFromHashedNextObjective(pl, neighborMac, nextId);
+            } else {
+                log.debug("fixHashGroup in device {}: Adding Bucket(s) "
+                        + "with Port/Label: {} to next object id {}",
+                        deviceId, pl, nextId);
+                addToHashedNextObjective(pl, neighborMac, nextId);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Adds or removes a port that has been configured with a vlan to a broadcast group
+     * for bridging. Should only be called by the master instance for this device.
+     *
+     * @param port the port on this device that needs to be added/removed to a bcast group
+     * @param vlanId the vlan id corresponding to the broadcast domain/group
+     * @param popVlan indicates if packets should be sent out untagged or not out
+     *                of the port. If true, indicates an access (untagged) or native vlan
+     *                configuration. If false, indicates a trunk (tagged) vlan config.
+     * @param portUp true if port is enabled, false if disabled
+     */
+    public void processEdgePort(PortNumber port, VlanId vlanId,
+                                boolean popVlan, boolean portUp) {
+        //get the next id for the subnet and edit it.
+        Integer nextId = getVlanNextObjectiveId(vlanId);
+        if (nextId == -1) {
+            if (portUp) {
+                log.debug("**Creating flooding group for first port enabled in"
+                        + " vlan {} on dev {} port {}", vlanId, deviceId, port);
+                createBcastGroupFromVlan(vlanId, Collections.singleton(port));
+            } else {
+                log.warn("Could not find flooding group for subnet {} on dev:{} when"
+                        + " removing port:{}", vlanId, deviceId, port);
+            }
+            return;
+        }
+
+        log.info("**port{} in device {}: {} Bucket with Port {} to"
+                + " next-id {}", (portUp) ? "UP" : "DOWN", deviceId,
+                                          (portUp) ? "Adding" : "Removing",
+                                          port, nextId);
+        // Create the bucket to be added or removed
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        if (popVlan) {
+            tBuilder.popVlan();
+        }
+        tBuilder.setOutput(port);
+
+        TrafficSelector metadata =
+                DefaultTrafficSelector.builder().matchVlanId(vlanId).build();
+
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder().withId(nextId)
+                .withType(NextObjective.Type.BROADCAST).fromApp(appId)
+                .addTreatment(tBuilder.build())
+                .withMeta(metadata);
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+            (objective) -> log.debug("port {} successfully {} NextObj {} on {}",
+                                     port, (portUp) ? "addedTo" : "removedFrom",
+                                     nextId, deviceId),
+            (objective, error) ->
+            log.warn("port {} failed to {} NextObj {} on {}: {}",
+                     port, (portUp) ? "addTo" : "removeFrom",
+                     nextId, deviceId, error));
+
+        NextObjective nextObj = (portUp) ? nextObjBuilder.addToExisting(context)
+                                         : nextObjBuilder.removeFromExisting(context);
+        log.debug("edgePort processed: Submited next objective {} in device {}",
+                  nextId, deviceId);
+        flowObjectiveService.next(deviceId, nextObj);
+    }
+
+    /**
+     * Returns the next objective of type hashed associated with the destination set.
+     * In addition, updates the existing next-objective if new route-route paths found
+     * have resulted in the addition of new next-hops to a particular destination.
+     * If there is no existing next objective for this destination set, this method
+     * would create a next objective and return the nextId. Optionally metadata can be
+     * passed in for the creation of the next objective.
+     *
+     * @param ds destination set
+     * @param nextHops a map of per destination next hops
+     * @param meta metadata passed into the creation of a Next Objective
+     * @param isBos if Bos is set
+     * @return int if found or -1 if there are errors in the creation of the
+     *          neighbor set.
+     */
+    public int getNextObjectiveId(DestinationSet ds,
+                                  Map<DeviceId, Set<DeviceId>> nextHops,
+                                  TrafficSelector meta, boolean isBos) {
+        NextNeighbors next = dsNextObjStore.
+                get(new DestinationSetNextObjectiveStoreKey(deviceId, ds));
+        if (next == null) {
+            log.debug("getNextObjectiveId in device{}: Next objective id "
+                    + "not found for {} ... creating", deviceId, ds);
+            log.trace("getNextObjectiveId: nsNextObjStore contents for device {}: {}",
+                      deviceId,
+                      dsNextObjStore.entrySet()
+                      .stream()
+                      .filter((nsStoreEntry) ->
+                      (nsStoreEntry.getKey().deviceId().equals(deviceId)))
+                      .collect(Collectors.toList()));
+
+            createGroupFromDestinationSet(ds, nextHops, meta, isBos);
+            next = dsNextObjStore.
+                    get(new DestinationSetNextObjectiveStoreKey(deviceId, ds));
+            if (next == null) {
+                log.warn("getNextObjectiveId: unable to create next objective");
+                // failure in creating group
+                return -1;
+            } else {
+                log.debug("getNextObjectiveId in device{}: Next objective id {} "
+                    + "created for {}", deviceId, next.nextId(), ds);
+            }
+        } else {
+            log.trace("getNextObjectiveId in device{}: Next objective id {} "
+                    + "found for {}", deviceId, next.nextId(), ds);
+            // should fix hash groups too if next-hops have changed
+            if (!next.dstNextHops().equals(nextHops)) {
+                log.debug("Nexthops have changed for dev:{} nextId:{} ..updating",
+                          deviceId, next.nextId());
+                if (!updateNextHops(ds, nextHops)) {
+                    // failure in updating group
+                    return -1;
+                }
+            }
+        }
+        return next.nextId();
+    }
+
+    /**
+     * Returns the next objective of type broadcast associated with the vlan,
+     * or -1 if no such objective exists. Note that this method does NOT create
+     * the next objective as a side-effect. It is expected that is objective is
+     * created at startup from network configuration. Typically this is used
+     * for L2 flooding within the subnet configured on the switch.
+     *
+     * @param vlanId vlan id
+     * @return int if found or -1
+     */
+    public int getVlanNextObjectiveId(VlanId vlanId) {
+        Integer nextId = vlanNextObjStore.
+                get(new VlanNextObjectiveStoreKey(deviceId, vlanId));
+
+        return (nextId != null) ? nextId : -1;
+    }
+
+    /**
+     * Returns the next objective of type simple associated with the port on the
+     * device, given the treatment. Different treatments to the same port result
+     * in different next objectives. If no such objective exists, this method
+     * creates one (if requested) and returns the id. Optionally metadata can be passed in for
+     * the creation of the objective. Typically this is used for L2 and L3 forwarding
+     * to compute nodes and containers/VMs on the compute nodes directly attached
+     * to the switch.
+     *
+     * @param portNum the port number for the simple next objective
+     * @param treatment the actions to apply on the packets (should include outport)
+     * @param meta optional metadata passed into the creation of the next objective
+     * @param createIfMissing true if a next object should be created if not found
+     * @return int if found or created, -1 if there are errors during the
+     *          creation of the next objective.
+     */
+    public int getPortNextObjectiveId(PortNumber portNum, TrafficTreatment treatment,
+                                      TrafficSelector meta, boolean createIfMissing) {
+        Integer nextId = portNextObjStore
+                .get(new PortNextObjectiveStoreKey(deviceId, portNum, treatment, meta));
+        if (nextId != null) {
+            return nextId;
+        }
+        log.debug("getPortNextObjectiveId in device {}: Next objective id "
+                + "not found for port: {} .. {}", deviceId, portNum,
+                (createIfMissing) ? "creating" : "aborting");
+        if (!createIfMissing) {
+            return -1;
+        }
+        // create missing next objective
+        createGroupFromPort(portNum, treatment, meta);
+        nextId = portNextObjStore.get(new PortNextObjectiveStoreKey(deviceId, portNum,
+                                                                    treatment, meta));
+        if (nextId == null) {
+            log.warn("getPortNextObjectiveId: unable to create next obj"
+                    + "for dev:{} port:{}", deviceId, portNum);
+            return -1;
+        }
+        return nextId;
+    }
+
+    /**
+     * Checks if the next objective ID (group) for the neighbor set exists or not.
+     *
+     * @param ns neighbor set to check
+     * @return true if it exists, false otherwise
+     */
+    public boolean hasNextObjectiveId(DestinationSet ns) {
+        NextNeighbors nextHops = dsNextObjStore.
+                get(new DestinationSetNextObjectiveStoreKey(deviceId, ns));
+        if (nextHops == null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private void populateNeighborMaps() {
+        Set<Link> outgoingLinks = linkService.getDeviceEgressLinks(deviceId);
+        for (Link link : outgoingLinks) {
+            if (link.type() != Link.Type.DIRECT) {
+                continue;
+            }
+            addNeighborAtPort(link.dst().deviceId(), link.src().port());
+        }
+    }
+
+    protected void addNeighborAtPort(DeviceId neighborId,
+                                     PortNumber portToNeighbor) {
+        // Update DeviceToPort database
+        log.debug("Device {} addNeighborAtPort: neighbor {} at port {}",
+                  deviceId, neighborId, portToNeighbor);
+        Set<PortNumber> ports = Collections
+                .newSetFromMap(new ConcurrentHashMap<PortNumber, Boolean>());
+        ports.add(portToNeighbor);
+        Set<PortNumber> portnums = devicePortMap.putIfAbsent(neighborId, ports);
+        if (portnums != null) {
+            portnums.add(portToNeighbor);
+        }
+
+        // Update portToDevice database
+        DeviceId prev = portDeviceMap.putIfAbsent(portToNeighbor, neighborId);
+        if (prev != null) {
+            log.debug("Device: {} port: {} already has neighbor: {} ",
+                      deviceId, portToNeighbor, prev, neighborId);
+        }
+    }
+
+    /**
+     * Creates a NextObjective for a hash group in this device from a given
+     * DestinationSet.
+     *
+     * @param ds the DestinationSet
+     * @param neighbors a map for each destination and its next-hops
+     * @param meta metadata passed into the creation of a Next Objective
+     * @param isBos if BoS is set
+     */
+    public void createGroupFromDestinationSet(DestinationSet ds,
+                                              Map<DeviceId, Set<DeviceId>> neighbors,
+                                              TrafficSelector meta,
+                                              boolean isBos) {
+        int nextId = flowObjectiveService.allocateNextId();
+        NextObjective.Type type = NextObjective.Type.HASHED;
+        if (neighbors == null || neighbors.isEmpty()) {
+            log.warn("createGroupsFromDestinationSet: needs at least one neighbor"
+                    + "to create group in dev:{} for ds: {} with next-hops {}",
+                    deviceId, ds, neighbors);
+            return;
+        }
+        // If Bos == False and MPLS-ECMP == false, we have
+        // to use simple group and we will pick a single neighbor for a single dest.
+        if (!isBos && !srManager.getMplsEcmp()) {
+            type = NextObjective.Type.SIMPLE;
+        }
+
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder()
+                .withId(nextId)
+                .withType(type)
+                .fromApp(appId);
+        if (meta != null) {
+            nextObjBuilder.withMeta(meta);
+        }
+
+        // create treatment buckets for each neighbor for each dst Device
+        // except in the special case where we only want to pick a single
+        // neighbor for a simple group
+        boolean foundSingleNeighbor = false;
+        boolean treatmentAdded = false;
+        Map<DeviceId, Set<DeviceId>> dstNextHops = new ConcurrentHashMap<>();
+        for (DeviceId dst : ds.getDestinationSwitches()) {
+            Set<DeviceId> nextHops = neighbors.get(dst);
+            if (nextHops == null || nextHops.isEmpty()) {
+                continue;
+            }
+
+            if (foundSingleNeighbor) {
+                break;
+            }
+
+            for (DeviceId neighborId : nextHops) {
+                if (devicePortMap.get(neighborId) == null) {
+                    log.warn("Neighbor {} is not in the port map yet for dev:{}",
+                             neighborId, deviceId);
+                    return;
+                } else if (devicePortMap.get(neighborId).isEmpty()) {
+                    log.warn("There are no ports for "
+                            + "the Device {} in the port map yet", neighborId);
+                    return;
+                }
+
+                MacAddress neighborMac;
+                try {
+                    neighborMac = deviceConfig.getDeviceMac(neighborId);
+                } catch (DeviceConfigNotFoundException e) {
+                    log.warn(e.getMessage() + " Aborting createGroupsFromDestinationset.");
+                    return;
+                }
+                // For each port to the neighbor, we create a new treatment
+                Set<PortNumber> neighborPorts = devicePortMap.get(neighborId);
+                // In this case we are using a SIMPLE group. We randomly pick a port
+                if (!isBos && !srManager.getMplsEcmp()) {
+                    int size = devicePortMap.get(neighborId).size();
+                    int index = RandomUtils.nextInt(0, size);
+                    neighborPorts = Collections.singleton(
+                                        Iterables.get(devicePortMap.get(neighborId),
+                                                      index));
+                    foundSingleNeighbor = true;
+                }
+
+                for (PortNumber sp : neighborPorts) {
+                    TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
+                            .builder();
+                    tBuilder.setEthDst(neighborMac).setEthSrc(nodeMacAddr);
+                    int edgeLabel = ds.getEdgeLabel(dst);
+                    if (edgeLabel != DestinationSet.NO_EDGE_LABEL) {
+                        tBuilder.pushMpls()
+                        .copyTtlOut()
+                        .setMpls(MplsLabel.mplsLabel(edgeLabel));
+                    }
+                    tBuilder.setOutput(sp);
+                    nextObjBuilder.addTreatment(tBuilder.build());
+                    treatmentAdded = true;
+                    //update store
+                    Set<DeviceId> existingNeighbors = dstNextHops.get(dst);
+                    if (existingNeighbors == null) {
+                        existingNeighbors = new HashSet<>();
+                    }
+                    existingNeighbors.add(neighborId);
+                    dstNextHops.put(dst, existingNeighbors);
+                    log.debug("creating treatment for port/label {}/{} in next:{}",
+                              sp, edgeLabel, nextId);
+                }
+
+                if (foundSingleNeighbor) {
+                    break;
+                }
+            }
+        }
+
+        if (!treatmentAdded) {
+            log.warn("Could not createGroup from DestinationSet {} without any"
+                    + "next hops {}", ds, neighbors);
+            return;
+        }
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) ->
+                log.debug("createGroupsFromDestinationSet installed "
+                        + "NextObj {} on {}", nextId, deviceId),
+                (objective, error) ->
+                log.warn("createGroupsFromDestinationSet failed to install"
+                        + " NextObj {} on {}: {}", nextId, deviceId, error)
+                );
+        NextObjective nextObj = nextObjBuilder.add(context);
+        log.debug(".. createGroupsFromDestinationSet: Submitted "
+                + "next objective {} in device {}", nextId, deviceId);
+        flowObjectiveService.next(deviceId, nextObj);
+        //update store
+        dsNextObjStore.put(new DestinationSetNextObjectiveStoreKey(deviceId, ds),
+                           new NextNeighbors(dstNextHops, nextId));
+    }
+
+    /**
+     * Creates broadcast groups for all ports in the same subnet for
+     * all configured subnets.
+     */
+    public void createGroupsFromVlanConfig() {
+        srManager.getVlanPortMap(deviceId).asMap().forEach((vlanId, ports) -> {
+            createBcastGroupFromVlan(vlanId, ports);
+        });
+    }
+
+    /**
+     * Creates a single broadcast group from a given vlan id and list of ports.
+     *
+     * @param vlanId vlan id
+     * @param ports list of ports in the subnet
+     */
+    public void createBcastGroupFromVlan(VlanId vlanId, Collection<PortNumber> ports) {
+        VlanNextObjectiveStoreKey key = new VlanNextObjectiveStoreKey(deviceId, vlanId);
+
+        if (vlanNextObjStore.containsKey(key)) {
+            log.debug("Broadcast group for device {} and subnet {} exists",
+                      deviceId, vlanId);
+            return;
+        }
+
+        TrafficSelector metadata =
+                DefaultTrafficSelector.builder().matchVlanId(vlanId).build();
+
+        int nextId = flowObjectiveService.allocateNextId();
+
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder().withId(nextId)
+                .withType(NextObjective.Type.BROADCAST).fromApp(appId)
+                .withMeta(metadata);
+
+        ports.forEach(port -> {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            if (toPopVlan(port, vlanId)) {
+                tBuilder.popVlan();
+            }
+            tBuilder.setOutput(port);
+            nextObjBuilder.addTreatment(tBuilder.build());
+        });
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+            (objective) ->
+                log.debug("createBroadcastGroupFromVlan installed "
+                        + "NextObj {} on {}", nextId, deviceId),
+            (objective, error) ->
+                log.warn("createBroadcastGroupFromVlan failed to install"
+                        + " NextObj {} on {}: {}", nextId, deviceId, error)
+            );
+        NextObjective nextObj = nextObjBuilder.add(context);
+        flowObjectiveService.next(deviceId, nextObj);
+        log.debug("createBcastGroupFromVlan: Submitted next objective {} "
+                + "for vlan: {} in device {}", nextId, vlanId, deviceId);
+
+        vlanNextObjStore.put(key, nextId);
+    }
+
+    /**
+     * Removes a single broadcast group from a given vlan id.
+     * The group should be empty.
+     * @param deviceId device Id to remove the group
+     * @param portNum port number related to the group
+     * @param vlanId vlan id of the broadcast group to remove
+     * @param popVlan true if the TrafficTreatment involves pop vlan tag action
+     */
+    public void removeBcastGroupFromVlan(DeviceId deviceId, PortNumber portNum,
+                                         VlanId vlanId, boolean popVlan) {
+        VlanNextObjectiveStoreKey key = new VlanNextObjectiveStoreKey(deviceId, vlanId);
+
+        if (!vlanNextObjStore.containsKey(key)) {
+            log.debug("Broadcast group for device {} and subnet {} does not exist",
+                      deviceId, vlanId);
+            return;
+        }
+
+        TrafficSelector metadata =
+                DefaultTrafficSelector.builder().matchVlanId(vlanId).build();
+
+        int nextId = vlanNextObjStore.get(key);
+
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder().withId(nextId)
+                .withType(NextObjective.Type.BROADCAST).fromApp(appId)
+                .withMeta(metadata);
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        if (popVlan) {
+            tBuilder.popVlan();
+        }
+        tBuilder.setOutput(portNum);
+        nextObjBuilder.addTreatment(tBuilder.build());
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) ->
+                        log.debug("removeBroadcastGroupFromVlan removed "
+                                          + "NextObj {} on {}", nextId, deviceId),
+                (objective, error) ->
+                        log.warn("removeBroadcastGroupFromVlan failed to remove "
+                                         + " NextObj {} on {}: {}", nextId, deviceId, error)
+        );
+        NextObjective nextObj = nextObjBuilder.remove(context);
+        flowObjectiveService.next(deviceId, nextObj);
+        log.debug("removeBcastGroupFromVlan: Submited next objective {} in device {}",
+                  nextId, deviceId);
+
+        vlanNextObjStore.remove(key, nextId);
+    }
+
+    /**
+     * Determine if we should pop given vlan before sending packets to the given port.
+     *
+     * @param portNumber port number
+     * @param vlanId vlan id
+     * @return true if the vlan id is not contained in any vlanTagged config
+     */
+    private boolean toPopVlan(PortNumber portNumber, VlanId vlanId) {
+        return srManager.interfaceService
+                .getInterfacesByPort(new ConnectPoint(deviceId, portNumber))
+                .stream().noneMatch(intf -> intf.vlanTagged().contains(vlanId));
+    }
+
+    /**
+     * Create simple next objective for a single port. The treatments can include
+     * all outgoing actions that need to happen on the packet.
+     *
+     * @param portNum  the outgoing port on the device
+     * @param treatment the actions to apply on the packets (should include outport)
+     * @param meta optional data to pass to the driver
+     */
+    public void createGroupFromPort(PortNumber portNum, TrafficTreatment treatment,
+                                    TrafficSelector meta) {
+        int nextId = flowObjectiveService.allocateNextId();
+        PortNextObjectiveStoreKey key = new PortNextObjectiveStoreKey(
+                                                deviceId, portNum, treatment, meta);
+
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder().withId(nextId)
+                .withType(NextObjective.Type.SIMPLE)
+                .addTreatment(treatment)
+                .fromApp(appId)
+                .withMeta(meta);
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+            (objective) ->
+                log.debug("createGroupFromPort installed "
+                        + "NextObj {} on {}", nextId, deviceId),
+            (objective, error) ->
+                log.warn("createGroupFromPort failed to install"
+                        + " NextObj {} on {}: {}", nextId, deviceId, error)
+            );
+        NextObjective nextObj = nextObjBuilder.add(context);
+        flowObjectiveService.next(deviceId, nextObj);
+        log.debug("createGroupFromPort: Submited next objective {} in device {} "
+                + "for port {}", nextId, deviceId, portNum);
+
+        portNextObjStore.put(key, nextId);
+    }
+
+    /**
+     * Removes simple next objective for a single port.
+     *
+     * @param deviceId device id that has the port to deal with
+     * @param portNum the outgoing port on the device
+     * @param vlanId vlan id associated with the port
+     * @param popVlan true if POP_VLAN action is applied on the packets, false otherwise
+     */
+    public void removePortNextObjective(DeviceId deviceId, PortNumber portNum, VlanId vlanId, boolean popVlan) {
+        TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
+        mbuilder.matchVlanId(vlanId);
+
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+        tbuilder.immediate().setOutput(portNum);
+        if (popVlan) {
+            tbuilder.immediate().popVlan();
+        }
+
+        int portNextObjId = srManager.getPortNextObjectiveId(deviceId, portNum,
+                                                             tbuilder.build(), mbuilder.build(), false);
+
+        PortNextObjectiveStoreKey key = new PortNextObjectiveStoreKey(
+                deviceId, portNum, tbuilder.build(), mbuilder.build());
+        if (portNextObjId != -1 && portNextObjStore.containsKey(key)) {
+            NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                    .builder().withId(portNextObjId)
+                    .withType(NextObjective.Type.SIMPLE).fromApp(appId);
+            ObjectiveContext context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("removePortNextObjective removes NextObj {} on {}",
+                                             portNextObjId, deviceId),
+                    (objective, error) ->
+                            log.warn("removePortNextObjective failed to remove NextObj {} on {}: {}",
+                                     portNextObjId, deviceId, error));
+            NextObjective nextObjective = nextObjBuilder.remove(context);
+            log.info("**removePortNextObjective: Submitted "
+                             + "next objective {} in device {}",
+                     portNextObjId, deviceId);
+            flowObjectiveService.next(deviceId, nextObjective);
+
+            portNextObjStore.remove(key);
+        }
+    }
+    /**
+     * Removes groups for the next objective ID given.
+     *
+     * @param objectiveId next objective ID to remove
+     * @return true if succeeds, false otherwise
+     */
+    public boolean removeGroup(int objectiveId) {
+        for (Map.Entry<DestinationSetNextObjectiveStoreKey, NextNeighbors> e :
+                dsNextObjStore.entrySet()) {
+            if (e.getValue().nextId() != objectiveId) {
+                continue;
+            }
+            // Right now it is just used in TunnelHandler
+            // remember in future that PW transit groups could
+            // be Indirect groups
+            NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                    .builder().withId(objectiveId)
+                    .withType(NextObjective.Type.HASHED).fromApp(appId);
+            ObjectiveContext context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("RemoveGroup removes NextObj {} on {}",
+                            objectiveId, deviceId),
+                    (objective, error) ->
+                            log.warn("RemoveGroup failed to remove NextObj {} on {}: {}",
+                                    objectiveId, deviceId, error));
+            NextObjective nextObjective = nextObjBuilder.remove(context);
+            log.info("**removeGroup: Submited "
+                    + "next objective {} in device {}",
+                    objectiveId, deviceId);
+            flowObjectiveService.next(deviceId, nextObjective);
+
+            dsNextObjStore.remove(e.getKey());
+            return true;
+        }
+
+        return false;
+    }
+    /**
+     * Remove simple next objective for a single port. The treatments can include
+     * all outgoing actions that need to happen on the packet.
+     *
+     * @param portNum  the outgoing port on the device
+     * @param treatment the actions applied on the packets (should include outport)
+     * @param meta optional data to pass to the driver
+     */
+    public void removeGroupFromPort(PortNumber portNum, TrafficTreatment treatment,
+                                    TrafficSelector meta) {
+        PortNextObjectiveStoreKey key = new PortNextObjectiveStoreKey(
+                deviceId, portNum, treatment, meta);
+        Integer nextId = portNextObjStore.get(key);
+
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder().withId(nextId)
+                .withType(NextObjective.Type.SIMPLE)
+                .addTreatment(treatment)
+                .fromApp(appId)
+                .withMeta(meta);
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) ->
+                        log.info("removeGroupFromPort installed "
+                                          + "NextObj {} on {}", nextId, deviceId),
+                (objective, error) ->
+                        log.warn("removeGroupFromPort failed to install"
+                                         + " NextObj {} on {}: {}", nextId, deviceId, error)
+        );
+        NextObjective nextObj = nextObjBuilder.remove(context);
+        flowObjectiveService.next(deviceId, nextObj);
+        log.info("removeGroupFromPort: Submitted next objective {} in device {} "
+                          + "for port {}", nextId, deviceId, portNum);
+
+        portNextObjStore.remove(key);
+    }
+
+    /**
+     * Removes all groups from all next objective stores.
+     */
+    /*public void removeAllGroups() {
+        for (Map.Entry<NeighborSetNextObjectiveStoreKey, NextNeighbors> entry:
+                nsNextObjStore.entrySet()) {
+            removeGroup(entry.getValue().nextId());
+        }
+        for (Map.Entry<PortNextObjectiveStoreKey, Integer> entry:
+                portNextObjStore.entrySet()) {
+            removeGroup(entry.getValue());
+        }
+        for (Map.Entry<VlanNextObjectiveStoreKey, Integer> entry:
+                vlanNextObjStore.entrySet()) {
+            removeGroup(entry.getValue());
+        }
+    }*/ //XXX revisit
+
+    /**
+     * Triggers a one time bucket verification operation on all hash groups
+     * on this device.
+     */
+    public void triggerBucketCorrector() {
+        BucketCorrector bc = new BucketCorrector();
+        bc.run();
+    }
+
+    public void updateGroupFromVlanConfiguration(PortNumber portNumber, Collection<VlanId> vlanIds,
+                                                 int nextId, boolean install) {
+        vlanIds.forEach(vlanId -> updateGroupFromVlanInternal(vlanId, portNumber, nextId, install));
+    }
+
+    private void updateGroupFromVlanInternal(VlanId vlanId, PortNumber portNum, int nextId, boolean install) {
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        if (toPopVlan(portNum, vlanId)) {
+            tBuilder.popVlan();
+        }
+        tBuilder.setOutput(portNum);
+
+        TrafficSelector metadata =
+                DefaultTrafficSelector.builder().matchVlanId(vlanId).build();
+
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder().withId(nextId)
+                .withType(NextObjective.Type.BROADCAST).fromApp(appId)
+                .addTreatment(tBuilder.build())
+                .withMeta(metadata);
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("port {} successfully removedFrom NextObj {} on {}",
+                                         portNum, nextId, deviceId),
+                (objective, error) ->
+                        log.warn("port {} failed to removedFrom NextObj {} on {}: {}",
+                                 portNum, nextId, deviceId, error));
+
+        if (install) {
+            flowObjectiveService.next(deviceId, nextObjBuilder.addToExisting(context));
+        } else {
+            flowObjectiveService.next(deviceId, nextObjBuilder.removeFromExisting(context));
+        }
+    }
+
+    /**
+     * Performs bucket verification operation for all hash groups in this device.
+     * Checks RouteHandler to ensure that routing is stable before attempting
+     * verification. Verification involves creating a nextObjective with
+     * operation VERIFY for existing next objectives in the store, and passing
+     * it to the driver. It is the driver that actually performs the verification
+     * by adding or removing buckets to match the verification next objective
+     * created here.
+     */
+    protected final class BucketCorrector implements Runnable {
+        Integer nextId;
+
+        BucketCorrector() {
+            this.nextId = null;
+        }
+
+        BucketCorrector(Integer nextId) {
+            this.nextId = nextId;
+        }
+
+        @Override
+        public void run() {
+            if (!srManager.mastershipService.isLocalMaster(deviceId)) {
+                return;
+            }
+            DefaultRoutingHandler rh = srManager.getRoutingHandler();
+            if (rh == null) {
+                return;
+            }
+            if (!rh.isRoutingStable()) {
+                return;
+            }
+            rh.acquireRoutingLock();
+            try {
+                log.trace("running bucket corrector for dev: {}", deviceId);
+                Set<DestinationSetNextObjectiveStoreKey> dsKeySet = dsNextObjStore.entrySet()
+                        .stream()
+                        .filter(entry -> entry.getKey().deviceId().equals(deviceId))
+                        // Filter out PW transit groups or include them if MPLS ECMP is supported
+                        .filter(entry -> !entry.getKey().destinationSet().mplsSet() ||
+                                (entry.getKey().destinationSet().mplsSet() && srManager.getMplsEcmp()))
+                        .map(entry -> entry.getKey())
+                        .collect(Collectors.toSet());
+                for (DestinationSetNextObjectiveStoreKey dsKey : dsKeySet) {
+                    NextNeighbors next = dsNextObjStore.get(dsKey);
+                    if (next == null) {
+                        continue;
+                    }
+                    int nid = next.nextId();
+                    if (nextId != null && nextId != nid) {
+                        continue;
+                    }
+                    log.trace("bkt-corr: dsNextObjStore for device {}: {}",
+                              deviceId, dsKey, next);
+                    TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
+                    metabuilder.matchVlanId(INTERNAL_VLAN);
+                    NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder()
+                            .withId(nid)
+                            .withType(NextObjective.Type.HASHED)
+                            .withMeta(metabuilder.build())
+                            .fromApp(appId);
+
+                    next.dstNextHops().forEach((dstDev, nextHops) -> {
+                        int edgeLabel = dsKey.destinationSet().getEdgeLabel(dstDev);
+                        nextHops.forEach(neighbor -> {
+                            MacAddress neighborMac;
+                            try {
+                                neighborMac = deviceConfig.getDeviceMac(neighbor);
+                            } catch (DeviceConfigNotFoundException e) {
+                                log.warn(e.getMessage() + " Aborting neighbor"
+                                        + neighbor);
+                                return;
+                            }
+                            devicePortMap.get(neighbor).forEach(port -> {
+                                log.trace("verify in device {} nextId {}: bucket with"
+                                        + " port/label {}/{} to dst {} via {}",
+                                        deviceId, nid, port, edgeLabel,
+                                        dstDev, neighbor);
+                                nextObjBuilder.addTreatment(treatmentBuilder(port,
+                                                                neighborMac, edgeLabel));
+                            });
+                        });
+                    });
+
+                    NextObjective nextObjective = nextObjBuilder.verify();
+                    flowObjectiveService.next(deviceId, nextObjective);
+                }
+            } finally {
+                rh.releaseRoutingLock();
+            }
+
+        }
+
+        TrafficTreatment treatmentBuilder(PortNumber outport, MacAddress dstMac,
+                                          int edgeLabel) {
+            TrafficTreatment.Builder tBuilder =
+                    DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(outport)
+                .setEthDst(dstMac)
+                .setEthSrc(nodeMacAddr);
+            if (edgeLabel != DestinationSet.NO_EDGE_LABEL) {
+                tBuilder.pushMpls()
+                    .copyTtlOut()
+                    .setMpls(MplsLabel.mplsLabel(edgeLabel));
+            }
+            return tBuilder.build();
+        }
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/DestinationSet.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/DestinationSet.java
new file mode 100644
index 0000000..7f839cf
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/DestinationSet.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2015-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.grouphandler;
+
+import org.onosproject.net.DeviceId;
+import org.slf4j.Logger;
+
+import com.google.common.base.MoreObjects.ToStringHelper;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Representation of a set of destination switch dpids along with their edge-node
+ * labels. Meant to be used as a lookup-key in a hash-map to retrieve an ECMP-group
+ * that hashes packets towards a specific destination switch,
+ * or paired-destination switches.
+ */
+public class DestinationSet {
+    public static final int NO_EDGE_LABEL = -1;
+    private static final int NOT_ASSIGNED = 0;
+    private boolean mplsSet;
+    private final DeviceId dstSw1;
+    private final int edgeLabel1;
+    private final DeviceId dstSw2;
+    private final int edgeLabel2;
+
+
+    private static final Logger log = getLogger(DestinationSet.class);
+
+    /**
+     * Constructor for a single destination with no Edge label.
+     *
+     * @param isMplsSet indicates if it is a mpls destination set
+     * @param dstSw the destination switch
+     */
+    public DestinationSet(boolean isMplsSet, DeviceId dstSw) {
+        this.edgeLabel1 = NO_EDGE_LABEL;
+        this.mplsSet = isMplsSet;
+        this.dstSw1 = dstSw;
+        this.edgeLabel2 = NOT_ASSIGNED;
+        this.dstSw2 = null;
+    }
+
+    /**
+     * Constructor for a single destination with Edge label.
+     *
+     * @param isMplsSet indicates if it is a mpls destination set
+     * @param edgeLabel label to be pushed as part of group operation
+     * @param dstSw the destination switch
+     */
+    public DestinationSet(boolean isMplsSet,
+                       int edgeLabel, DeviceId dstSw) {
+        this.mplsSet = isMplsSet;
+        this.edgeLabel1 = edgeLabel;
+        this.dstSw1 = dstSw;
+        this.edgeLabel2 = NOT_ASSIGNED;
+        this.dstSw2 = null;
+    }
+
+    /**
+     * Constructor for paired destination switches and their associated
+     * edge labels.
+     *
+     * @param isMplsSet indicates if it is a mpls destination set
+     * @param edgeLabel1 label to be pushed as part of group operation for dstSw1
+     * @param dstSw1 one of the paired destination switches
+     * @param edgeLabel2 label to be pushed as part of group operation for dstSw2
+     * @param dstSw2 the other paired destination switch
+     */
+    public DestinationSet(boolean isMplsSet,
+                          int edgeLabel1, DeviceId dstSw1,
+                          int edgeLabel2, DeviceId dstSw2) {
+        this.mplsSet = isMplsSet;
+        if (dstSw1.toString().compareTo(dstSw2.toString()) <= 0) {
+            this.edgeLabel1 = edgeLabel1;
+            this.dstSw1 = dstSw1;
+            this.edgeLabel2 = edgeLabel2;
+            this.dstSw2 = dstSw2;
+        } else {
+            this.edgeLabel1 = edgeLabel2;
+            this.dstSw1 = dstSw2;
+            this.edgeLabel2 = edgeLabel1;
+            this.dstSw2 = dstSw1;
+        }
+    }
+
+    /**
+     * Default constructor for kryo serialization.
+     */
+    public DestinationSet() {
+        this.edgeLabel1 = NOT_ASSIGNED;
+        this.edgeLabel2 = NOT_ASSIGNED;
+        this.mplsSet = true;
+        this.dstSw1 = DeviceId.NONE;
+        this.dstSw2 = DeviceId.NONE;
+    }
+
+    /**
+     * Factory method for DestinationSet hierarchy.
+     *
+     * @param random the expected behavior.
+     * @param isMplsSet indicates if it is a mpls destination set
+     * @param dstSw the destination switch
+     * @return the destination set object.
+     */
+    public static DestinationSet destinationSet(boolean random,
+                                          boolean isMplsSet, DeviceId dstSw) {
+        return random ? new RandomDestinationSet(dstSw)
+                      : new DestinationSet(isMplsSet, dstSw);
+    }
+
+    /**
+     * Factory method for DestinationSet hierarchy.
+     *
+     * @param random the expected behavior.
+     * @param isMplsSet indicates if it is a mpls destination set
+     * @param edgeLabel label to be pushed as part of group operation
+     * @param dstSw the destination switch
+     * @return the destination set object
+     */
+    public static DestinationSet destinationSet(boolean random,
+                                          boolean isMplsSet, int edgeLabel,
+                                          DeviceId dstSw) {
+        return random ? new RandomDestinationSet(edgeLabel, dstSw)
+                      : new DestinationSet(isMplsSet, edgeLabel, dstSw);
+    }
+
+    /**
+     * Factory method for DestinationSet hierarchy.
+     *
+     * @param random the expected behavior.
+     * @return the destination set object
+     */
+    public static DestinationSet destinationSet(boolean random) {
+        return random ? new RandomDestinationSet() : new DestinationSet();
+    }
+
+    /**
+     * Gets the label associated with given destination switch.
+     *
+     * @param dstSw the destination switch
+     * @return integer the label associated with the destination switch
+     */
+    public int getEdgeLabel(DeviceId dstSw) {
+        if (dstSw.equals(dstSw1)) {
+            return edgeLabel1;
+        } else if (dstSw.equals(dstSw2)) {
+            return edgeLabel2;
+        }
+        return NOT_ASSIGNED;
+    }
+
+    /**
+     * Gets all the destination switches in this destination set.
+     *
+     * @return a set of destination switch ids
+     */
+    public Set<DeviceId> getDestinationSwitches() {
+        Set<DeviceId> dests = new HashSet<>();
+        dests.add(dstSw1);
+        if (dstSw2 != null) {
+            dests.add(dstSw2);
+        }
+        return dests;
+    }
+
+    /**
+     * Gets the value of mplsSet.
+     *
+     * @return the value of mplsSet
+     */
+    public boolean mplsSet() {
+        return mplsSet;
+    }
+
+    // The list of destination ids and label are used for comparison.
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof DestinationSet)) {
+            return false;
+        }
+        DestinationSet that = (DestinationSet) o;
+        boolean equal = (this.edgeLabel1 == that.edgeLabel1 &&
+                            this.mplsSet == that.mplsSet &&
+                            this.dstSw1.equals(that.dstSw1));
+        if (this.dstSw2 != null && that.dstSw2 == null ||
+                this.dstSw2 == null && that.dstSw2 != null) {
+            return false;
+        }
+        if (this.dstSw2 != null && that.dstSw2 != null) {
+            equal = equal && (this.edgeLabel2 == that.edgeLabel2 &&
+                                this.dstSw2.equals(that.dstSw2));
+        }
+        return equal;
+    }
+
+    // The list of destination ids and label are used for comparison.
+    @Override
+    public int hashCode() {
+        if (dstSw2 == null) {
+            return Objects.hash(mplsSet, edgeLabel1, dstSw1);
+        }
+        return Objects.hash(mplsSet, edgeLabel1, dstSw1, edgeLabel2, dstSw2);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper h = toStringHelper(this)
+                                .add("MplsSet", mplsSet)
+                                .add("DstSw1", dstSw1)
+                                .add("Label1", edgeLabel1);
+        if (dstSw2 != null) {
+            h.add("DstSw2", dstSw2)
+             .add("Label2", edgeLabel2);
+        }
+        return h.toString();
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/GroupBucketIdentifier.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/GroupBucketIdentifier.java
new file mode 100644
index 0000000..1c2e1ac
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/GroupBucketIdentifier.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2015-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.grouphandler;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.net.PortNumber;
+
+/**
+ * Representation of policy group bucket identifier. Not exposed to
+ * the application and only to be used internally.
+ */
+public class GroupBucketIdentifier {
+    private int label;
+    private BucketOutputType type;
+    private PortNumber outPort;
+    private PolicyGroupIdentifier outGroup;
+
+    protected enum BucketOutputType {
+        PORT,
+        GROUP
+    }
+
+    protected GroupBucketIdentifier(int label,
+                                    PortNumber outPort) {
+        this.label = label;
+        this.type = BucketOutputType.PORT;
+        this.outPort = checkNotNull(outPort);
+        this.outGroup = null;
+    }
+
+    protected GroupBucketIdentifier(int label,
+                                    PolicyGroupIdentifier outGroup) {
+        this.label = label;
+        this.type = BucketOutputType.GROUP;
+        this.outPort = null;
+        this.outGroup = checkNotNull(outGroup);
+    }
+
+    protected int label() {
+        return this.label;
+    }
+
+    protected BucketOutputType type() {
+        return this.type;
+    }
+
+    protected PortNumber outPort() {
+        return this.outPort;
+    }
+
+    protected PolicyGroupIdentifier outGroup() {
+        return this.outGroup;
+    }
+}
+
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/NextNeighbors.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/NextNeighbors.java
new file mode 100644
index 0000000..eaca1aa
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/NextNeighbors.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2015-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.grouphandler;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+import org.onosproject.net.DeviceId;
+
+/**
+ * Represents the nexthop information associated with a route-path towards a
+ * set of destinations.
+ */
+public class NextNeighbors {
+    private final Map<DeviceId, Set<DeviceId>> dstNextHops;
+    private final int nextId;
+
+    /**
+     * Constructor.
+     *
+     * @param dstNextHops map of destinations and the next-hops towards each dest
+     * @param nextId id of nextObjective that manifests the next-hop info
+     */
+    public NextNeighbors(Map<DeviceId, Set<DeviceId>> dstNextHops, int nextId) {
+        this.dstNextHops = dstNextHops;
+        this.nextId = nextId;
+    }
+
+    /**
+     * Returns a map of destinations and the next-hops towards them.
+     *
+     * @return map of destinations and the next-hops towards them
+     */
+    public Map<DeviceId, Set<DeviceId>> dstNextHops() {
+        return dstNextHops;
+    }
+
+    /**
+     * Set of next-hops towards the given destination.
+     *
+     * @param deviceId the destination
+     * @return set of nexthops towards the destination
+     */
+    public Set<DeviceId> nextHops(DeviceId deviceId) {
+        return dstNextHops.get(deviceId);
+    }
+
+    /**
+     * Return the nextId representing the nextObjective towards the next-hops.
+     *
+     * @return nextId representing the nextObjective towards the next-hops
+     */
+    public int nextId() {
+        return nextId;
+    }
+
+    /**
+     * Checks if the given nextHopId is a valid next hop to any one of the
+     * destinations.
+     *
+     * @param nextHopId the deviceId for the next hop
+     * @return true if given next
+     */
+    public boolean containsNextHop(DeviceId nextHopId) {
+        for (Set<DeviceId> nextHops : dstNextHops.values()) {
+            if (nextHops != null && nextHops.contains(nextHopId)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a set of destinations which have the given nextHopId as one
+     * of the next-hops to that destination.
+     *
+     * @param nextHopId the deviceId for the next hop
+     * @return set of deviceIds that have the given nextHopId as a next-hop
+     *          which could be empty if no destinations were found
+     */
+    public Set<DeviceId> getDstForNextHop(DeviceId nextHopId) {
+        Set<DeviceId> dstSet = new HashSet<>();
+        for (DeviceId dstKey : dstNextHops.keySet()) {
+            if (dstNextHops.get(dstKey).contains(nextHopId)) {
+                dstSet.add(dstKey);
+            }
+        }
+        return dstSet;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof NextNeighbors)) {
+            return false;
+        }
+        NextNeighbors that = (NextNeighbors) o;
+        return (this.nextId == that.nextId) &&
+                this.dstNextHops.equals(that.dstNextHops);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(nextId, dstNextHops);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("nextId", nextId)
+                .add("dstNextHops", dstNextHops)
+                .toString();
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java
new file mode 100644
index 0000000..c0935ce
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java
@@ -0,0 +1,332 @@
+/*
+ * Copyright 2015-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.grouphandler;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceProperties;
+import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.link.LinkService;
+import org.slf4j.Logger;
+
+/**
+ * A module to create group chains based on the specified device
+ * ports and label stack to be applied on each port.
+ */
+public class PolicyGroupHandler extends DefaultGroupHandler {
+
+    private final Logger log = getLogger(getClass());
+    private HashMap<PolicyGroupIdentifier, PolicyGroupIdentifier> dependentGroups = new HashMap<>();
+
+    /**
+     * Constructs policy group handler.
+     *
+     * @param deviceId device identifier
+     * @param appId application identifier
+     * @param config interface to retrieve the device properties
+     * @param linkService link service object
+     * @param flowObjService flow objective service object
+     * @param srManager segment routing manager
+     */
+    public PolicyGroupHandler(DeviceId deviceId,
+                              ApplicationId appId,
+                              DeviceProperties config,
+                              LinkService linkService,
+                              FlowObjectiveService flowObjService,
+                              SegmentRoutingManager srManager) {
+        super(deviceId, appId, config, linkService, flowObjService, srManager);
+    }
+
+    /**
+     * Creates policy group chain.
+     *
+     * @param id unique identifier associated with the policy group
+     * @param params a list of policy group params
+     * @return policy group identifier
+     */
+    public PolicyGroupIdentifier createPolicyGroupChain(String id,
+                                                        List<PolicyGroupParams> params) {
+        List<GroupBucketIdentifier> bucketIds = new ArrayList<>();
+        for (PolicyGroupParams param: params) {
+            List<PortNumber> ports = param.getPorts();
+            if (ports == null) {
+                log.warn("createPolicyGroupChain in sw {} with wrong "
+                        + "input parameters", deviceId);
+                return null;
+            }
+
+            int labelStackSize = (param.getLabelStack() != null) ?
+                                      param.getLabelStack().size() : 0;
+
+            if (labelStackSize > 1) {
+                for (PortNumber sp : ports) {
+                    PolicyGroupIdentifier previousGroupkey = null;
+                    DeviceId neighbor = portDeviceMap.get(sp);
+                    for (int idx = 0; idx < param.getLabelStack().size(); idx++) {
+                        int label = param.getLabelStack().get(idx);
+                        if (idx == (labelStackSize - 1)) {
+                            // Innermost Group
+                            GroupBucketIdentifier bucketId =
+                                    new GroupBucketIdentifier(label,
+                                                              previousGroupkey);
+                            bucketIds.add(bucketId);
+                        } else if (idx == 0) {
+                            // Outermost Group
+                            List<GroupBucket> outBuckets = new ArrayList<>();
+                            GroupBucketIdentifier bucketId =
+                                    new GroupBucketIdentifier(label, sp);
+                            PolicyGroupIdentifier key = new
+                                    PolicyGroupIdentifier(id,
+                                                          Collections.singletonList(param),
+                                                          Collections.singletonList(bucketId));
+                            MacAddress neighborEthDst;
+                            try {
+                                neighborEthDst = deviceConfig.getDeviceMac(neighbor);
+                            } catch (DeviceConfigNotFoundException e) {
+                                log.warn(e.getMessage()
+                                        + " Skipping createPolicyGroupChain for this label.");
+                                continue;
+                            }
+
+                            TrafficTreatment.Builder tBuilder =
+                                    DefaultTrafficTreatment.builder();
+                            tBuilder.setOutput(sp)
+                                    .setEthDst(neighborEthDst)
+                                    .setEthSrc(nodeMacAddr)
+                                    .pushMpls()
+                                    .setMpls(MplsLabel.mplsLabel(label));
+                            /*outBuckets.add(DefaultGroupBucket.
+                                           createSelectGroupBucket(tBuilder.build()));
+                            GroupDescription desc = new
+                                    DefaultGroupDescription(deviceId,
+                                                            GroupDescription.Type.INDIRECT,
+                                                            new GroupBuckets(outBuckets));
+                            //TODO: BoS*/
+                            previousGroupkey = key;
+                            //groupService.addGroup(desc);
+                            //TODO: Use nextObjective APIs here
+                        } else {
+                            // Intermediate Groups
+                            GroupBucketIdentifier bucketId =
+                                    new GroupBucketIdentifier(label,
+                                                              previousGroupkey);
+                            PolicyGroupIdentifier key = new
+                                    PolicyGroupIdentifier(id,
+                                                          Collections.singletonList(param),
+                                                          Collections.singletonList(bucketId));
+                            // Add to group dependency list
+                            dependentGroups.put(previousGroupkey, key);
+                            previousGroupkey = key;
+                        }
+                    }
+                }
+            } else {
+                int label = -1;
+                if (labelStackSize == 1) {
+                    label = param.getLabelStack().get(0);
+                }
+                for (PortNumber sp : ports) {
+                    GroupBucketIdentifier bucketId =
+                            new GroupBucketIdentifier(label, sp);
+                    bucketIds.add(bucketId);
+                }
+            }
+        }
+        PolicyGroupIdentifier innermostGroupkey = null;
+        if (!bucketIds.isEmpty()) {
+            innermostGroupkey = new
+                    PolicyGroupIdentifier(id,
+                                          params,
+                                          bucketIds);
+            // Add to group dependency list
+            boolean fullyResolved = true;
+            for (GroupBucketIdentifier bucketId:bucketIds) {
+                if (bucketId.type() == BucketOutputType.GROUP) {
+                    dependentGroups.put(bucketId.outGroup(),
+                                        innermostGroupkey);
+                    fullyResolved = false;
+                }
+            }
+
+            if (fullyResolved) {
+                List<GroupBucket> outBuckets = new ArrayList<>();
+                for (GroupBucketIdentifier bucketId : bucketIds) {
+                    DeviceId neighbor = portDeviceMap.
+                            get(bucketId.outPort());
+
+                    MacAddress neighborEthDst;
+                    try {
+                        neighborEthDst = deviceConfig.getDeviceMac(neighbor);
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage()
+                                + " Skipping createPolicyGroupChain for this bucketId.");
+                        continue;
+                    }
+
+                    TrafficTreatment.Builder tBuilder =
+                            DefaultTrafficTreatment.builder();
+                    tBuilder.setOutput(bucketId.outPort())
+                            .setEthDst(neighborEthDst)
+                            .setEthSrc(nodeMacAddr);
+                    if (bucketId.label() != DestinationSet.NO_EDGE_LABEL) {
+                        tBuilder.pushMpls()
+                            .setMpls(MplsLabel.mplsLabel(bucketId.label()));
+                    }
+                    //TODO: BoS
+                    /*outBuckets.add(DefaultGroupBucket.
+                                   createSelectGroupBucket(tBuilder.build()));*/
+                }
+                /*GroupDescription desc = new
+                        DefaultGroupDescription(deviceId,
+                                                GroupDescription.Type.SELECT,
+                                                new GroupBuckets(outBuckets));
+                groupService.addGroup(desc);*/
+                //TODO: Use nextObjective APIs here
+            }
+        }
+        return innermostGroupkey;
+    }
+
+    //TODO: Use nextObjective APIs to handle the group chains
+    /*
+    @Override
+    protected void handleGroupEvent(GroupEvent event) {}
+    */
+
+    /**
+     * Generates policy group key.
+     *
+     * @param id unique identifier associated with the policy group
+     * @param params a list of policy group params
+     * @return policy group identifier
+     */
+    public PolicyGroupIdentifier generatePolicyGroupKey(String id,
+                                   List<PolicyGroupParams> params) {
+        List<GroupBucketIdentifier> bucketIds = new ArrayList<>();
+        for (PolicyGroupParams param: params) {
+            List<PortNumber> ports = param.getPorts();
+            if (ports == null) {
+                log.warn("generateGroupKey in sw {} with wrong "
+                        + "input parameters", deviceId);
+                return null;
+            }
+
+            int labelStackSize = (param.getLabelStack() != null)
+                    ? param.getLabelStack().size() : 0;
+
+            if (labelStackSize > 1) {
+                for (PortNumber sp : ports) {
+                    PolicyGroupIdentifier previousGroupkey = null;
+                    for (int idx = 0; idx < param.getLabelStack().size(); idx++) {
+                        int label = param.getLabelStack().get(idx);
+                        if (idx == (labelStackSize - 1)) {
+                            // Innermost Group
+                            GroupBucketIdentifier bucketId =
+                                    new GroupBucketIdentifier(label,
+                                                              previousGroupkey);
+                            bucketIds.add(bucketId);
+                        } else if (idx == 0) {
+                            // Outermost Group
+                            GroupBucketIdentifier bucketId =
+                                    new GroupBucketIdentifier(label, sp);
+                            PolicyGroupIdentifier key = new
+                                    PolicyGroupIdentifier(id,
+                                                          Collections.singletonList(param),
+                                                          Collections.singletonList(bucketId));
+                            previousGroupkey = key;
+                        } else {
+                            // Intermediate Groups
+                            GroupBucketIdentifier bucketId =
+                                    new GroupBucketIdentifier(label,
+                                                              previousGroupkey);
+                            PolicyGroupIdentifier key = new
+                                    PolicyGroupIdentifier(id,
+                                                          Collections.singletonList(param),
+                                                          Collections.singletonList(bucketId));
+                            previousGroupkey = key;
+                        }
+                    }
+                }
+            } else {
+                int label = -1;
+                if (labelStackSize == 1) {
+                    label = param.getLabelStack().get(0);
+                }
+                for (PortNumber sp : ports) {
+                    GroupBucketIdentifier bucketId =
+                            new GroupBucketIdentifier(label, sp);
+                    bucketIds.add(bucketId);
+                }
+            }
+        }
+        PolicyGroupIdentifier innermostGroupkey = null;
+        if (!bucketIds.isEmpty()) {
+            innermostGroupkey = new
+                    PolicyGroupIdentifier(id,
+                                          params,
+                                          bucketIds);
+        }
+        return innermostGroupkey;
+    }
+
+    /**
+     * Removes policy group chain.
+     *
+     * @param key policy group identifier
+     */
+    public void removeGroupChain(PolicyGroupIdentifier key) {
+        checkArgument(key != null);
+        List<PolicyGroupIdentifier> groupsToBeDeleted = new ArrayList<>();
+        groupsToBeDeleted.add(key);
+
+        Iterator<PolicyGroupIdentifier> it =
+                groupsToBeDeleted.iterator();
+
+        while (it.hasNext()) {
+            PolicyGroupIdentifier innerMostGroupKey = it.next();
+            for (GroupBucketIdentifier bucketId:
+                        innerMostGroupKey.bucketIds()) {
+                if (bucketId.type() != BucketOutputType.GROUP) {
+                    groupsToBeDeleted.add(bucketId.outGroup());
+                }
+            }
+            /*groupService.removeGroup(deviceId,
+                                     getGroupKey(innerMostGroupKey),
+                                     appId);*/
+            //TODO: Use nextObjective APIs here
+            it.remove();
+        }
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupIdentifier.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupIdentifier.java
new file mode 100644
index 0000000..fdc6dea
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupIdentifier.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2015-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.grouphandler;
+
+import java.util.List;
+
+/**
+ * Representation of policy based group identifiers.
+ * Opaque to group handler applications and only the outermost
+ * policy group identifier in a chain is visible to the applications.
+ */
+public class PolicyGroupIdentifier {
+    private String id;
+    private List<PolicyGroupParams> inputParams;
+    private List<GroupBucketIdentifier> bucketIds;
+
+    /**
+     * Constructs policy group identifier.
+     *
+     * @param id unique identifier associated with the policy group
+     * @param input policy group params associated with this group
+     * @param bucketIds buckets associated with this group
+     */
+    protected PolicyGroupIdentifier(String id,
+                                 List<PolicyGroupParams> input,
+                                 List<GroupBucketIdentifier> bucketIds) {
+        this.id = id;
+        this.inputParams = input;
+        this.bucketIds = bucketIds;
+    }
+
+    /**
+     * Returns the bucket identifier list associated with the policy
+     * group identifier.
+     *
+     * @return list of bucket identifier
+     */
+    protected List<GroupBucketIdentifier> bucketIds() {
+        return this.bucketIds;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 17;
+        int combinedHash = 0;
+        for (PolicyGroupParams input:inputParams) {
+            combinedHash = combinedHash + input.hashCode();
+        }
+        for (GroupBucketIdentifier bucketId:bucketIds) {
+            combinedHash = combinedHash + bucketId.hashCode();
+        }
+        result = 31 * result + combinedHash;
+
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof PolicyGroupIdentifier) {
+            PolicyGroupIdentifier that = (PolicyGroupIdentifier) obj;
+            boolean result = this.id.equals(that.id);
+            result = result &&
+                    this.inputParams.containsAll(that.inputParams) &&
+                    that.inputParams.containsAll(this.inputParams);
+            result = result &&
+                    this.bucketIds.containsAll(that.bucketIds) &&
+                    that.bucketIds.containsAll(this.bucketIds);
+            return result;
+        }
+
+        return false;
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupParams.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupParams.java
new file mode 100644
index 0000000..5baf849
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupParams.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015-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.grouphandler;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Objects;
+
+import org.onosproject.net.PortNumber;
+
+/**
+ * Representation of parameters used to create policy based groups.
+ */
+public class PolicyGroupParams {
+    private final List<PortNumber> ports;
+    private final List<Integer> labelStack;
+
+    /**
+     * Constructor.
+     *
+     * @param labelStack mpls label stack to be applied on the ports
+     * @param ports ports to be part of the policy group
+     */
+    public PolicyGroupParams(List<Integer> labelStack,
+                             List<PortNumber> ports) {
+        this.ports = checkNotNull(ports);
+        this.labelStack = checkNotNull(labelStack);
+    }
+
+    /**
+     * Returns the ports associated with the policy group params.
+     *
+     * @return list of port numbers
+     */
+    public List<PortNumber> getPorts() {
+        return ports;
+    }
+
+    /**
+     * Returns the label stack associated with the policy group params.
+     *
+     * @return list of integers
+     */
+    public List<Integer> getLabelStack() {
+        return labelStack;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 17;
+        int combinedHash = 0;
+        for (PortNumber port:ports) {
+            combinedHash = combinedHash + port.hashCode();
+        }
+        combinedHash = combinedHash + Objects.hash(labelStack);
+        result = 31 * result + combinedHash;
+
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof PolicyGroupParams) {
+            PolicyGroupParams that = (PolicyGroupParams) obj;
+            boolean result = this.labelStack.equals(that.labelStack);
+            result = result &&
+                    this.ports.containsAll(that.ports) &&
+                    that.ports.containsAll(this.ports);
+            return result;
+        }
+
+        return false;
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/RandomDestinationSet.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/RandomDestinationSet.java
new file mode 100644
index 0000000..3671b03
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/RandomDestinationSet.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.grouphandler;
+
+import org.onosproject.net.DeviceId;
+
+/**
+ * Extends its super class modifying its internal behavior.
+ * Pick a neighbor will pick a random neighbor.
+ */
+public class RandomDestinationSet extends DestinationSet {
+
+    public RandomDestinationSet(DeviceId dstSw) {
+        super(true, dstSw);
+    }
+
+    public RandomDestinationSet(int edgeLabel,
+                             DeviceId dstSw) {
+        super(true, edgeLabel, dstSw);
+    }
+
+    public RandomDestinationSet() {
+        super();
+    }
+
+    // XXX revisit the need for this class since neighbors no longer stored here
+    // will be handled when we fix pseudowires for dual-Tor scenarios
+
+
+    /*@Override
+    public DeviceId getFirstNeighbor() {
+        if (getDeviceIds().isEmpty()) {
+            return DeviceId.NONE;
+        }
+        int size = getDeviceIds().size();
+        int index = RandomUtils.nextInt(0, size);
+        return Iterables.get(getDeviceIds(), index);
+    }*/
+
+    @Override
+    public String toString() {
+        return " RandomNeighborset Sw: " //+ getDeviceIds()
+                + " and Label: " //+ getEdgeLabel()
+                + " for destination: "; // + getDestinationSw();
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/package-info.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/package-info.java
new file mode 100644
index 0000000..d99f1d1
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/grouphandler/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-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.
+ */
+
+/**
+ * Segment routing group handling.
+ */
+package org.onosproject.segmentrouting.grouphandler;
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/package-info.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/package-info.java
new file mode 100644
index 0000000..137ba3c
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-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.
+ */
+
+/**
+ * Segment routing application components.
+ */
+package org.onosproject.segmentrouting;
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2Tunnel.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2Tunnel.java
new file mode 100644
index 0000000..417a795
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2Tunnel.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.pwaas;
+
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.Link;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Implementation of the default l2 tunnel.
+ */
+public class DefaultL2Tunnel implements L2Tunnel {
+
+    /**
+     * Mode of the pseudo wire.
+     */
+    private L2Mode pwMode;
+    /**
+     * Service delimiting tag.
+     */
+    private VlanId sdTag;
+    /**
+     * Tunnel id.
+     */
+    private long tunnelId;
+    /**
+     * Pseudo wire label.
+     */
+    private MplsLabel pwLabel;
+    /**
+     * Inter-CO label.
+     */
+    private MplsLabel interCoLabel;
+
+    private List<Link> pathUsed;
+
+    /**
+     * Vlan which will be used for the encapsualted
+     * vlan traffic.
+     */
+    private VlanId transportVlan;
+
+    /**
+     * Creates a inter-co l2 tunnel using the
+     * supplied parameters.
+     *
+     * @param mode         the tunnel mode
+     * @param sdtag        the service delimiting tag
+     * @param tunnelId     the tunnel id
+     * @param pwLabel      the pseudo wire label
+     * @param interCoLabel the inter central office label
+     */
+    public DefaultL2Tunnel(L2Mode mode, VlanId sdtag, long tunnelId, MplsLabel pwLabel, MplsLabel interCoLabel) {
+        checkNotNull(mode);
+        checkArgument(tunnelId > 0);
+        checkNotNull(pwLabel);
+        checkNotNull(interCoLabel);
+
+        this.pwMode = mode;
+        this.sdTag = sdtag;
+        this.tunnelId = tunnelId;
+        this.pwLabel = pwLabel;
+        this.interCoLabel = interCoLabel;
+    }
+
+    /**
+     * Creates a l2Tunnel from a given tunnel.
+     *
+     * @param l2Tunnel to replicate
+     */
+    public DefaultL2Tunnel(DefaultL2Tunnel l2Tunnel) {
+
+        this.pwMode = l2Tunnel.pwMode();
+        this.sdTag = l2Tunnel.sdTag();
+        this.tunnelId = l2Tunnel.tunnelId();
+        this.pwLabel = l2Tunnel.pwLabel();
+        this.interCoLabel = l2Tunnel.interCoLabel();
+        this.pathUsed = l2Tunnel.pathUsed();
+        this.transportVlan = l2Tunnel.transportVlan;
+    }
+
+    /**
+     * Creates a intra-co l2 tunnel using the
+     * supplied parameters.
+     *
+     * @param mode     the tunnel mode
+     * @param sdtag    the service delimiting tag
+     * @param tunnelId the tunnel id
+     * @param pwLabel  the pseudo wire label
+     */
+    public DefaultL2Tunnel(L2Mode mode, VlanId sdtag, long tunnelId, MplsLabel pwLabel) {
+        this(mode, sdtag, tunnelId, pwLabel, MplsLabel.mplsLabel(MplsLabel.MAX_MPLS));
+    }
+
+
+    /**
+     * Creates an empty l2 tunnel.
+     **/
+    public DefaultL2Tunnel() {
+        this.pwMode = null;
+        this.sdTag = null;
+        this.tunnelId = 0;
+        this.pwLabel = null;
+        this.interCoLabel = null;
+    }
+
+    /**
+     * Returns the mode of the pseudo wire.
+     *
+     * @return the pseudo wire mode
+     */
+    @Override
+    public L2Mode pwMode() {
+        return pwMode;
+    }
+
+    /**
+     * Returns the service delimitation
+     * tag.
+     *
+     * @return the service delimitation vlan id
+     */
+    @Override
+    public VlanId sdTag() {
+        return sdTag;
+    }
+
+    /**
+     * Returns the tunnel id of the pseudo wire.
+     *
+     * @return the pseudo wire tunnel id
+     */
+    @Override
+    public long tunnelId() {
+        return tunnelId;
+    }
+
+    /**
+     * Returns the pw label.
+     *
+     * @return the mpls pw label
+     */
+    @Override
+    public MplsLabel pwLabel() {
+        return pwLabel;
+    }
+
+    /**
+     * Set the path for the pseudowire.
+     *
+     * @param path The path to set
+     */
+    @Override
+    public void setPath(List<Link> path) {
+        pathUsed = new ArrayList<>(path);
+    }
+
+    /**
+     * Set the transport vlan for the pseudowire.
+     *
+     * @param vlan the vlan to use.
+     */
+    @Override
+    public void setTransportVlan(VlanId vlan) {
+        transportVlan = vlan;
+    }
+
+    /**
+     * Returns the used path of the pseudowire.
+     *
+     * @return pathUsed
+     */
+    @Override
+    public List<Link> pathUsed() {
+        return pathUsed;
+    }
+
+    @Override
+    public VlanId transportVlan() {
+        return transportVlan;
+    }
+
+
+    /**
+     * Returns the inter-co label.
+     *
+     * @return the mpls inter-co label
+     */
+    @Override
+    public MplsLabel interCoLabel() {
+        return interCoLabel;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(this.tunnelId, this.pwMode, this.sdTag, this.pwLabel, this.interCoLabel);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o instanceof DefaultL2Tunnel) {
+            DefaultL2Tunnel that = (DefaultL2Tunnel) o;
+            return this.tunnelId == that.tunnelId &&
+                    this.pwMode.equals(that.pwMode) &&
+                    this.sdTag.equals(that.sdTag) &&
+                    this.pwLabel.equals(that.pwLabel) &&
+                    this.interCoLabel.equals(that.interCoLabel);
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("pwMode", pwMode())
+                .add("sdTag", sdTag())
+                .add("tunnelId", tunnelId())
+                .add("pwLabel", pwLabel())
+                .add("interCoLabel", interCoLabel())
+                .add("transportVlan", transportVlan())
+                .toString();
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelDescription.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelDescription.java
new file mode 100644
index 0000000..7a47972
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelDescription.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.pwaas;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Helper class to carry the l2 tunnel
+ * and its policy.
+ */
+public class DefaultL2TunnelDescription implements L2TunnelDescription {
+
+    /**
+     * The l2 tunnel.
+     */
+    private L2Tunnel l2Tunnel;
+
+    /**
+     * The l2 tunnel policy.
+     */
+    private L2TunnelPolicy l2TunnelPolicy;
+
+    /**
+     * Creates a l2 tunnel description using the given info.
+     *
+     * @param l2Tunnel the l2 tunnel
+     * @param l2TunnelPolicy the l2 tunnel description
+     */
+    public DefaultL2TunnelDescription(L2Tunnel l2Tunnel,
+                                      L2TunnelPolicy l2TunnelPolicy) {
+        checkNotNull(l2Tunnel);
+        checkNotNull(l2TunnelPolicy);
+
+        this.l2Tunnel = l2Tunnel;
+        this.l2TunnelPolicy = l2TunnelPolicy;
+    }
+
+    /**
+     * Creates an empty l2 tunnel description.
+     */
+    public DefaultL2TunnelDescription() {
+        this.l2Tunnel = null;
+        this.l2TunnelPolicy = null;
+    }
+
+    @Override
+    public L2Tunnel l2Tunnel() {
+        return l2Tunnel;
+    }
+
+    @Override
+    public L2TunnelPolicy l2TunnelPolicy() {
+        return l2TunnelPolicy;
+    }
+
+    @Override
+    public void setL2Tunnel(L2Tunnel tunnel) {
+        l2Tunnel = tunnel;
+    }
+
+    @Override
+    public void setL2TunnelPolicy(L2TunnelPolicy policy) {
+        l2TunnelPolicy = policy;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(this.l2Tunnel, this.l2TunnelPolicy);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o instanceof DefaultL2TunnelDescription) {
+            DefaultL2TunnelDescription that = (DefaultL2TunnelDescription) o;
+            // Equality is based on tunnel id and pw label
+            // which is always the last label.
+            return this.l2Tunnel.equals(that.l2Tunnel) &&
+                    this.l2TunnelPolicy.equals(that.l2TunnelPolicy);
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("l2Tunnel", l2Tunnel())
+                .add("l2TunnelPolicy", l2TunnelPolicy())
+                .toString();
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
new file mode 100644
index 0000000..2dc9de2
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
@@ -0,0 +1,1733 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.pwaas;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang3.RandomUtils;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.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.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.PwaasConfig;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.DistributedSet;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.Versioned;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.net.flowobjective.ForwardingObjective.Flag.VERSATILE;
+import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Pipeline.INITIATION;
+import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Pipeline.TERMINATION;
+import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Result.*;
+import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Direction.FWD;
+import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Direction.REV;
+
+/**
+ * Handles pwaas related events.
+ */
+public class DefaultL2TunnelHandler implements L2TunnelHandler {
+
+    private static final Logger log = LoggerFactory.getLogger(DefaultL2TunnelHandler.class);
+
+    private final SegmentRoutingManager srManager;
+    /**
+     * To store the next objectives related to the initiation.
+     */
+    private final ConsistentMap<String, NextObjective> l2InitiationNextObjStore;
+    /**
+     * To store the next objectives related to the termination.
+     */
+    private final ConsistentMap<String, NextObjective> l2TerminationNextObjStore;
+
+    /**
+     * To store policies.
+     */
+    private final ConsistentMap<String, L2TunnelPolicy> l2PolicyStore;
+
+    /**
+     * To store tunnels.
+     */
+    private final ConsistentMap<String, L2Tunnel> l2TunnelStore;
+
+    private final KryoNamespace.Builder l2TunnelKryo;
+
+    /**
+     * Contains transport vlans used for spine-leaf pseudowires.
+     */
+    private final DistributedSet<VlanId> vlanStore;
+
+    /**
+     * Used for determining transport vlans for leaf-spine.
+     */
+    private short transportVlanUpper = 4093, transportVlanLower = 3500;
+
+    private static final VlanId UNTAGGED_TRANSPORT_VLAN = VlanId.vlanId((short) 4094);
+
+    /**
+     * Create a l2 tunnel handler for the deploy and
+     * for the tear down of pseudo wires.
+     *
+     * @param segmentRoutingManager the segment routing manager
+     */
+    public DefaultL2TunnelHandler(SegmentRoutingManager segmentRoutingManager) {
+        srManager = segmentRoutingManager;
+        l2TunnelKryo = new KryoNamespace.Builder()
+                .register(KryoNamespaces.API)
+                .register(L2Tunnel.class,
+                          L2TunnelPolicy.class,
+                          DefaultL2Tunnel.class,
+                          DefaultL2TunnelPolicy.class,
+                          L2Mode.class,
+                          MplsLabel.class,
+                          VlanId.class,
+                          ConnectPoint.class);
+
+        l2InitiationNextObjStore = srManager.
+                storageService.
+                <String, NextObjective>consistentMapBuilder().
+                withName("onos-l2initiation-nextobj-store").
+                withSerializer(Serializer.using(l2TunnelKryo.build())).
+                build();
+
+        l2TerminationNextObjStore = srManager.storageService.
+                <String, NextObjective>consistentMapBuilder()
+                .withName("onos-l2termination-nextobj-store")
+                .withSerializer(Serializer.using(l2TunnelKryo.build()))
+                .build();
+
+        l2PolicyStore = srManager.storageService
+                .<String, L2TunnelPolicy>consistentMapBuilder()
+                .withName("onos-l2-policy-store")
+                .withSerializer(Serializer.using(l2TunnelKryo.build()))
+                .build();
+
+        l2TunnelStore = srManager.storageService
+                .<String, L2Tunnel>consistentMapBuilder()
+                .withName("onos-l2-tunnel-store")
+                .withSerializer(Serializer.using(l2TunnelKryo.build()))
+                .build();
+
+        vlanStore = srManager.storageService.<VlanId>setBuilder()
+                .withName("onos-transport-vlan-store")
+                .withSerializer(Serializer.using(
+                        new KryoNamespace.Builder()
+                                .register(KryoNamespaces.API)
+                                .build()))
+                .build()
+                .asDistributedSet();
+    }
+
+    /**
+     * Deploys any pre-existing pseudowires in the configuration.
+     * Used by manager only in initialization.
+     */
+    @Override
+    public void init() {
+
+        PwaasConfig config = srManager.cfgService.getConfig(srManager.appId(), PwaasConfig.class);
+        if (config == null) {
+            return;
+        }
+
+        log.info("Deploying existing pseudowires");
+
+        // gather pseudowires
+        Set<L2TunnelDescription> pwToAdd = config
+                .getPwIds()
+                .stream()
+                .map(config::getPwDescription)
+                .collect(Collectors.toSet());
+
+        // deploy pseudowires
+        deploy(pwToAdd);
+    }
+
+    /**
+     * Returns all L2 Policies.
+     *
+     * @return List of policies
+     */
+    @Override
+    public List<L2TunnelPolicy> getL2Policies() {
+
+        return new ArrayList<>(l2PolicyStore
+                .values()
+                .stream()
+                .map(Versioned::value)
+                .collect(Collectors.toList()));
+
+    }
+
+    /**
+     * Returns all L2 Tunnels.
+     *
+     * @return List of tunnels.
+     */
+    @Override
+    public List<L2Tunnel> getL2Tunnels() {
+
+        return new ArrayList<>(l2TunnelStore
+                .values()
+                .stream()
+                .map(Versioned::value)
+                .collect(Collectors.toList()));
+
+    }
+
+    @Override
+    public void processLinkDown(Link link) {
+
+        List<L2Tunnel> tunnels = getL2Tunnels();
+        List<L2TunnelPolicy> policies = getL2Policies();
+
+        // determine affected pseudowires and update them at once
+        Set<L2TunnelDescription> pwToUpdate = tunnels
+                .stream()
+                .filter(tun -> tun.pathUsed().contains(link))
+                .map(l2Tunnel -> {
+                        L2TunnelPolicy policy = null;
+                        for (L2TunnelPolicy l2Policy : policies) {
+                            if (l2Policy.tunnelId() == l2Tunnel.tunnelId()) {
+                                policy = l2Policy;
+                                break;
+                            }
+                        }
+
+                        return new DefaultL2TunnelDescription(l2Tunnel, policy);
+                })
+                .collect(Collectors.toSet());
+
+
+        log.info("Pseudowires affected by link failure : {}, rerouting them...", pwToUpdate);
+
+        // update all pseudowires
+        pwToUpdate.forEach(tun -> updatePw(tun, tun));
+    }
+
+    @Override
+    public void processPwaasConfigAdded(NetworkConfigEvent event) {
+        checkArgument(event.config().isPresent(),
+                "Config is not presented in PwaasConfigAdded event {}", event);
+
+        log.info("Network event : Pseudowire configuration added!");
+        PwaasConfig config = (PwaasConfig) event.config().get();
+
+        // gather pseudowires
+        Set<L2TunnelDescription> pwToAdd = config
+                .getPwIds()
+                .stream()
+                .map(config::getPwDescription)
+                .collect(Collectors.toSet());
+
+        // deploy pseudowires
+        deploy(pwToAdd);
+    }
+
+    /**
+     * Returns the new vlan id for an ingress point of a
+     * pseudowire. For double tagged, it is the outer,
+     * For single tagged it is the single tag, and for
+     * inner it is None.
+     *
+     * @param ingressOuter vlanid of ingress outer
+     * @param ingressInner vlanid of ingress inner
+     * @param egressOuter  vlanid of egress outer
+     * @param egressInner  vlanid of egress inner
+     * @return returns the vlan id which will be installed at vlan table 1.
+     */
+    private VlanId determineEgressVlan(VlanId ingressOuter, VlanId ingressInner,
+                                      VlanId egressOuter, VlanId egressInner) {
+
+        // validity of vlan combinations was checked at verifyPseudowire
+        if (!(ingressOuter.equals(VlanId.NONE))) {
+            return egressOuter;
+        } else if (!(ingressInner.equals(VlanId.NONE))) {
+            return egressInner;
+        } else {
+            return VlanId.vlanId("None");
+        }
+    }
+
+    /**
+     * Determines vlan used for transporting the pw traffic.
+     *
+     * Leaf-Leaf traffic is transferred untagged, thus we choose the UNTAGGED_TRANSPORT_VLAN
+     * and also make sure to add the popVlan instruction.
+     * For spine-leaf pws we choose the highest vlan value available from a certain range.
+     *
+     * @param spinePw if the pw is leaf-spine.
+     * @return The vlan id chossen to transport this pseudowire. If vlan is UNTAGGED_TRANSPORT_VLAN
+     *         then the pw is transported untagged.
+     */
+    private VlanId determineTransportVlan(boolean spinePw) {
+
+        if (!spinePw) {
+
+            log.info("Untagged transport with internal vlan {} for pseudowire!", UNTAGGED_TRANSPORT_VLAN);
+            return UNTAGGED_TRANSPORT_VLAN;
+        } else {
+            for (short i = transportVlanUpper; i > transportVlanLower; i--) {
+
+                VlanId vlanToUse = VlanId.vlanId((short) i);
+                if (!vlanStore.contains(vlanToUse)) {
+
+                    vlanStore.add(vlanToUse);
+                    log.info("Transport vlan {} for pseudowire!", vlanToUse);
+                    return vlanToUse;
+                }
+            }
+
+            log.info("No available transport vlan found, pseudowire traffic will be carried untagged " +
+                             "with internal vlan {}!", UNTAGGED_TRANSPORT_VLAN);
+            return UNTAGGED_TRANSPORT_VLAN;
+        }
+    }
+
+    /**
+     * Adds a single pseudowire from leaf to a leaf.
+     * This method can be called from cli commands
+     * without configuration updates, thus it does not check for mastership
+     * of the ingress pseudowire device.
+     *
+     * @param pw The pseudowire
+     * @param spinePw True if pseudowire is from leaf to spine
+     * @return result of pseudowire deployment
+     */
+    private Result deployPseudowire(L2TunnelDescription pw, boolean spinePw) {
+
+        Result result;
+        long l2TunnelId;
+
+        l2TunnelId = pw.l2Tunnel().tunnelId();
+
+        // The tunnel id cannot be 0.
+        if (l2TunnelId == 0) {
+            log.warn("Tunnel id id must be > 0");
+            return Result.ADDITION_ERROR;
+        }
+
+        // get path here, need to use the same for fwd and rev direction
+        List<Link> path = getPath(pw.l2TunnelPolicy().cP1(),
+                                  pw.l2TunnelPolicy().cP2());
+        if (path == null) {
+            log.info("Deploying process : No path between the connection points for pseudowire {}", l2TunnelId);
+            return WRONG_PARAMETERS;
+        }
+
+        Link fwdNextHop;
+        Link revNextHop;
+        if (!spinePw) {
+            if (path.size() != 2) {
+                log.info("Deploying process : Path between two leafs should have size of 2, for pseudowire {}",
+                         l2TunnelId);
+                return INTERNAL_ERROR;
+            }
+
+            fwdNextHop = path.get(0);
+            revNextHop = reverseLink(path.get(1));
+        } else {
+            if (path.size() != 1) {
+                log.info("Deploying process : Path between leaf spine should equal to 1, for pseudowire {}",
+                         l2TunnelId);
+                return INTERNAL_ERROR;
+            }
+
+            fwdNextHop = path.get(0);
+            revNextHop = reverseLink(path.get(0));
+        }
+
+        pw.l2Tunnel().setPath(path);
+        pw.l2Tunnel().setTransportVlan(determineTransportVlan(spinePw));
+
+        // next hops for next objectives
+
+        log.info("Deploying process : Establishing forward direction for pseudowire {}", l2TunnelId);
+
+        VlanId egressVlan = determineEgressVlan(pw.l2TunnelPolicy().cP1OuterTag(),
+                                                pw.l2TunnelPolicy().cP1InnerTag(),
+                                                pw.l2TunnelPolicy().cP2OuterTag(),
+                                                pw.l2TunnelPolicy().cP2InnerTag());
+        // We establish the tunnel.
+        // result.nextId will be used in fwd
+        result = deployPseudoWireInit(pw.l2Tunnel(),
+                                      pw.l2TunnelPolicy().cP1(),
+                                      pw.l2TunnelPolicy().cP2(),
+                                      FWD,
+                                      fwdNextHop,
+                                      spinePw,
+                                      egressVlan);
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying pseudowire initiation for CP1");
+            return Result.ADDITION_ERROR;
+        }
+
+        // We create the policy.
+        result = deployPolicy(l2TunnelId,
+                              pw.l2TunnelPolicy().cP1(),
+                              pw.l2TunnelPolicy().cP1InnerTag(),
+                              pw.l2TunnelPolicy().cP1OuterTag(),
+                              egressVlan,
+                              result.nextId);
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying pseudowire policy for CP1");
+            return Result.ADDITION_ERROR;
+        }
+
+        // We terminate the tunnel
+        result = deployPseudoWireTerm(pw.l2Tunnel(),
+                                       pw.l2TunnelPolicy().cP2(),
+                                       egressVlan,
+                                       FWD,
+                                      spinePw);
+
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying pseudowire termination for CP1");
+            return Result.ADDITION_ERROR;
+
+        }
+
+        log.info("Deploying process : Establishing reverse direction for pseudowire {}", l2TunnelId);
+
+        egressVlan = determineEgressVlan(pw.l2TunnelPolicy().cP2OuterTag(),
+                                         pw.l2TunnelPolicy().cP2InnerTag(),
+                                         pw.l2TunnelPolicy().cP1OuterTag(),
+                                         pw.l2TunnelPolicy().cP1InnerTag());
+
+        // We establish the reverse tunnel.
+        result = deployPseudoWireInit(pw.l2Tunnel(),
+                                       pw.l2TunnelPolicy().cP2(),
+                                       pw.l2TunnelPolicy().cP1(),
+                                       REV,
+                                       revNextHop,
+                                       spinePw,
+                                       egressVlan);
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying pseudowire initiation for CP2");
+            return Result.ADDITION_ERROR;
+        }
+
+
+        result = deployPolicy(l2TunnelId,
+                               pw.l2TunnelPolicy().cP2(),
+                               pw.l2TunnelPolicy().cP2InnerTag(),
+                               pw.l2TunnelPolicy().cP2OuterTag(),
+                               egressVlan,
+                               result.nextId);
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying policy for CP2");
+            return Result.ADDITION_ERROR;
+        }
+
+        result = deployPseudoWireTerm(pw.l2Tunnel(),
+                                       pw.l2TunnelPolicy().cP1(),
+                                       egressVlan,
+                                       REV,
+                                      spinePw);
+
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying pseudowire termination for CP2");
+            return Result.ADDITION_ERROR;
+        }
+
+        log.info("Deploying process : Updating relevant information for pseudowire {}", l2TunnelId);
+
+        // Populate stores
+        l2TunnelStore.put(Long.toString(l2TunnelId), pw.l2Tunnel());
+        l2PolicyStore.put(Long.toString(l2TunnelId), pw.l2TunnelPolicy());
+
+        return Result.SUCCESS;
+    }
+
+    /**
+     * To deploy a number of pseudo wires.
+     * <p>
+     * Called ONLY when configuration changes, thus the check
+     * for the mastership of the device.
+     * <p>
+     * Only the master of CP1 will deploy this pseudowire.
+     *
+     * @param pwToAdd the set of pseudo wires to add
+     */
+    private void deploy(Set<L2TunnelDescription> pwToAdd) {
+
+        Result result;
+
+        for (L2TunnelDescription currentL2Tunnel : pwToAdd) {
+            ConnectPoint cp1 = currentL2Tunnel.l2TunnelPolicy().cP1();
+            ConnectPoint cp2 = currentL2Tunnel.l2TunnelPolicy().cP2();
+            long tunnelId = currentL2Tunnel.l2TunnelPolicy().tunnelId();
+
+            // only the master of CP1 will program this pseudowire
+            if (!srManager.isMasterOf(cp1)) {
+                log.debug("Not the master of {}. Ignore pseudo wire deployment id={}", cp1, tunnelId);
+                continue;
+            }
+
+            try {
+                // differentiate between leaf-leaf pseudowires and leaf-spine
+                // and pass the appropriate flag in them.
+                if (!srManager.deviceConfiguration().isEdgeDevice(cp1.deviceId()) &&
+                    !srManager.deviceConfiguration().isEdgeDevice(cp2.deviceId())) {
+                    log.warn("Can not deploy pseudowire from spine to spine!");
+                    result = Result.INTERNAL_ERROR;
+                } else if (srManager.deviceConfiguration().isEdgeDevice(cp1.deviceId()) &&
+                     srManager.deviceConfiguration().isEdgeDevice(cp2.deviceId())) {
+                    log.info("Deploying a leaf-leaf pseudowire {}", tunnelId);
+                    result = deployPseudowire(currentL2Tunnel, false);
+                } else {
+                    log.info("Deploying a leaf-spine pseudowire {}", tunnelId);
+                    result = deployPseudowire(currentL2Tunnel, true);
+                }
+            } catch (DeviceConfigNotFoundException e) {
+                log.error("Exception caught when deploying pseudowire", e.toString());
+                result = Result.INTERNAL_ERROR;
+            }
+
+            switch (result) {
+                case INTERNAL_ERROR:
+                    log.warn("Could not deploy pseudowire {}, internal error!", tunnelId);
+                    break;
+                case WRONG_PARAMETERS:
+                    log.warn("Could not deploy pseudowire {}, wrong parameters!", tunnelId);
+                    break;
+                case ADDITION_ERROR:
+                    log.warn("Could not deploy pseudowire {}, error in populating rules!", tunnelId);
+                    break;
+                default:
+                    log.info("Pseudowire with {} succesfully deployed!", tunnelId);
+                    break;
+            }
+        }
+    }
+
+
+    @Override
+    public void processPwaasConfigUpdated(NetworkConfigEvent event) {
+        checkArgument(event.config().isPresent(),
+                "Config is not presented in PwaasConfigUpdated event {}", event);
+        checkArgument(event.prevConfig().isPresent(),
+                "PrevConfig is not presented in PwaasConfigUpdated event {}", event);
+
+        log.info("Pseudowire configuration updated.");
+
+        // We retrieve the old pseudo wires.
+        PwaasConfig prevConfig = (PwaasConfig) event.prevConfig().get();
+        Set<Long> prevPws = prevConfig.getPwIds();
+
+        // We retrieve the new pseudo wires.
+        PwaasConfig config = (PwaasConfig) event.config().get();
+        Set<Long> newPws = config.getPwIds();
+
+        // We compute the pseudo wires to update.
+        Set<Long> updPws = newPws.stream()
+                .filter(tunnelId -> prevPws.contains(tunnelId)
+                        && !config.getPwDescription(tunnelId).equals(prevConfig.getPwDescription(tunnelId)))
+                .collect(Collectors.toSet());
+
+        // The pseudo wires to remove.
+        Set<Long> rmvPWs = prevPws.stream()
+                .filter(tunnelId -> !newPws.contains(tunnelId)).collect(Collectors.toSet());
+
+        Set<L2TunnelDescription> pwToRemove = rmvPWs.stream()
+                .map(prevConfig::getPwDescription)
+                .collect(Collectors.toSet());
+        tearDown(pwToRemove);
+
+        // The pseudo wires to add.
+        Set<Long> addedPWs = newPws.stream()
+                .filter(tunnelId -> !prevPws.contains(tunnelId))
+                .collect(Collectors.toSet());
+        Set<L2TunnelDescription> pwToAdd = addedPWs.stream()
+                .map(config::getPwDescription)
+                .collect(Collectors.toSet());
+        deploy(pwToAdd);
+
+
+        // The pseudo wires to update.
+        updPws.forEach(tunnelId -> updatePw(prevConfig.getPwDescription(tunnelId),
+                                            config.getPwDescription(tunnelId)));
+
+        log.info("Pseudowires removed : {}, Pseudowires updated : {}, Pseudowires added : {}", rmvPWs,
+                 updPws, addedPWs);
+    }
+
+    /**
+     * Helper function to update a pw.
+     * <p>
+     * Called upon configuration changes that update existing pseudowires and
+     * when links fail. Checking of mastership for CP1 is mandatory because it is
+     * called in multiple instances for both cases.
+     * <p>
+     * Meant to call asynchronously for various events, thus this call can not block and need
+     * to perform asynchronous operations.
+     * <p>
+     * For this reason error checking is omitted.
+     *
+     * @param oldPw the pseudo wire to remove
+     * @param newPw the pseudo wire to add
+     */
+    private void updatePw(L2TunnelDescription oldPw,
+                         L2TunnelDescription newPw) {
+        ConnectPoint oldCp1 = oldPw.l2TunnelPolicy().cP1();
+        long tunnelId = oldPw.l2Tunnel().tunnelId();
+
+        // only the master of CP1 will update this pseudowire
+        if (!srManager.isMasterOf(oldPw.l2TunnelPolicy().cP1())) {
+            log.debug("Not the master of {}. Ignore pseudo wire update id={}", oldCp1, tunnelId);
+            return;
+        }
+        // only determine if the new pseudowire is leaf-spine, because
+        // removal process is the same for both leaf-leaf and leaf-spine pws
+        boolean newPwSpine;
+        try {
+            newPwSpine = !srManager.deviceConfiguration().isEdgeDevice(newPw.l2TunnelPolicy().cP1().deviceId()) ||
+                    !srManager.deviceConfiguration().isEdgeDevice(newPw.l2TunnelPolicy().cP2().deviceId());
+        } catch (DeviceConfigNotFoundException e) {
+            // if exception is caught treat the new pw as leaf-leaf
+            newPwSpine = false;
+        }
+
+        // copy the variable here because we need to use it in lambda thus it needs to be final
+        boolean finalNewPwSpine = newPwSpine;
+
+        log.info("Updating pseudowire {}", oldPw.l2Tunnel().tunnelId());
+
+        // The async tasks to orchestrate the next and forwarding update
+        CompletableFuture<ObjectiveError> fwdInitNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> revInitNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> fwdTermNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> revTermNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> fwdPwFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> revPwFuture = new CompletableFuture<>();
+
+        // first delete all information from our stores, we can not do it asynchronously
+        l2PolicyStore.remove(Long.toString(tunnelId));
+
+        // grab the old l2 tunnel from the store, since it carries information which is not exposed
+        // to the user configuration and set it to oldPw.
+        oldPw.setL2Tunnel(l2TunnelStore.get(Long.toString(tunnelId)).value());
+        VlanId transportVlan = l2TunnelStore.get(Long.toString(tunnelId)).value().transportVlan();
+        l2TunnelStore.remove(Long.toString(tunnelId));
+
+        // remove the reserved transport vlan, if one is used
+        if (!transportVlan.equals(UNTAGGED_TRANSPORT_VLAN)) {
+            vlanStore.remove(transportVlan);
+        }
+
+        // First we remove both policy.
+        log.debug("Start deleting fwd policy for {}", tunnelId);
+        VlanId egressVlan = determineEgressVlan(oldPw.l2TunnelPolicy().cP1OuterTag(),
+                                                 oldPw.l2TunnelPolicy().cP1InnerTag(),
+                                                 oldPw.l2TunnelPolicy().cP2OuterTag(),
+                                                 oldPw.l2TunnelPolicy().cP2InnerTag());
+        deletePolicy(tunnelId, oldPw.l2TunnelPolicy().cP1(),
+                      oldPw.l2TunnelPolicy().cP1InnerTag(),
+                      oldPw.l2TunnelPolicy().cP1OuterTag(),
+                      egressVlan,
+                      fwdInitNextFuture,
+                      FWD);
+
+        deletePolicy(tunnelId, oldPw.l2TunnelPolicy().cP2(),
+                      oldPw.l2TunnelPolicy().cP2InnerTag(),
+                      oldPw.l2TunnelPolicy().cP2OuterTag(),
+                      egressVlan, revInitNextFuture,
+                      REV);
+
+        // Finally we remove both the tunnels.
+        fwdInitNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                log.debug("Update process : Fwd policy removed. " +
+                                  "Now remove fwd {} for {}", INITIATION, tunnelId);
+                tearDownPseudoWireInit(tunnelId, oldPw.l2TunnelPolicy().cP1(), fwdTermNextFuture, FWD);
+            }
+        });
+        revInitNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                log.debug("Update process : Rev policy removed. " +
+                                  "Now remove rev {} for {}", INITIATION, tunnelId);
+                tearDownPseudoWireInit(tunnelId, oldPw.l2TunnelPolicy().cP2(), revTermNextFuture, REV);
+            }
+        });
+        fwdTermNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                log.debug("Update process : Fwd {} removed. " +
+                                  "Now remove fwd {} for {}", INITIATION, TERMINATION, tunnelId);
+                tearDownPseudoWireTerm(oldPw.l2Tunnel(), oldPw.l2TunnelPolicy().cP2(),  fwdPwFuture, FWD);
+            }
+        });
+        revTermNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                log.debug("Update process : Rev {} removed. " +
+                                  "Now remove rev {} for {}", INITIATION, TERMINATION, tunnelId);
+                tearDownPseudoWireTerm(oldPw.l2Tunnel(), oldPw.l2TunnelPolicy().cP1(), revPwFuture, REV);
+            }
+        });
+
+        // get path here, need to use the same for fwd and rev direction
+        List<Link> path = getPath(newPw.l2TunnelPolicy().cP1(),
+                                   newPw.l2TunnelPolicy().cP2());
+        if (path == null) {
+            log.error("Update process : " +
+                             "No path between the connection points for pseudowire {}", newPw.l2Tunnel().tunnelId());
+            return;
+        }
+
+        Link fwdNextHop, revNextHop;
+        if (!finalNewPwSpine) {
+            if (path.size() != 2) {
+                log.error("Update process : Error, path between two leafs should have size of 2, for pseudowire {}",
+                         newPw.l2Tunnel().tunnelId());
+                return;
+            }
+            fwdNextHop = path.get(0);
+            revNextHop = reverseLink(path.get(1));
+        } else {
+            if (path.size() != 1) {
+                log.error("Update process : Error, path between leaf spine should equal to 1, for pseudowire {}",
+                         newPw.l2Tunnel().tunnelId());
+                return;
+            }
+            fwdNextHop = path.get(0);
+            revNextHop = reverseLink(path.get(0));
+        }
+
+        // set new path and transport vlan.
+        newPw.l2Tunnel().setPath(path);
+        newPw.l2Tunnel().setTransportVlan(determineTransportVlan(newPwSpine));
+
+        // At the end we install the updated PW.
+        fwdPwFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+
+                // Upgrade stores and book keeping information, need to move this here
+                // cause this call is asynchronous.
+                l2PolicyStore.put(Long.toString(tunnelId), newPw.l2TunnelPolicy());
+                l2TunnelStore.put(Long.toString(tunnelId), newPw.l2Tunnel());
+
+                VlanId egressVlanId = determineEgressVlan(newPw.l2TunnelPolicy().cP1OuterTag(),
+                                                          newPw.l2TunnelPolicy().cP1InnerTag(),
+                                                          newPw.l2TunnelPolicy().cP2OuterTag(),
+                                                          newPw.l2TunnelPolicy().cP2InnerTag());
+
+                log.debug("Update process : Deploying new fwd pw for {}", tunnelId);
+                Result lamdaResult = deployPseudoWireInit(newPw.l2Tunnel(), newPw.l2TunnelPolicy().cP1(),
+                                                           newPw.l2TunnelPolicy().cP2(), FWD,
+                                                           fwdNextHop, finalNewPwSpine, egressVlanId);
+                if (lamdaResult != SUCCESS) {
+                    return;
+                }
+
+                lamdaResult = deployPolicy(tunnelId, newPw.l2TunnelPolicy().cP1(),
+                                            newPw.l2TunnelPolicy().cP1InnerTag(),
+                                           newPw.l2TunnelPolicy().cP1OuterTag(),
+                                            egressVlanId, lamdaResult.nextId);
+                if (lamdaResult != SUCCESS) {
+                    return;
+                }
+                deployPseudoWireTerm(newPw.l2Tunnel(), newPw.l2TunnelPolicy().cP2(),
+                                      egressVlanId, FWD, finalNewPwSpine);
+
+            }
+        });
+        revPwFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+
+                log.debug("Update process : Deploying new rev pw for {}", tunnelId);
+
+                VlanId egressVlanId = determineEgressVlan(newPw.l2TunnelPolicy().cP2OuterTag(),
+                                                          newPw.l2TunnelPolicy().cP2InnerTag(),
+                                                          newPw.l2TunnelPolicy().cP1OuterTag(),
+                                                          newPw.l2TunnelPolicy().cP1InnerTag());
+
+                Result lamdaResult = deployPseudoWireInit(newPw.l2Tunnel(),
+                                                           newPw.l2TunnelPolicy().cP2(),
+                                                           newPw.l2TunnelPolicy().cP1(),
+                                                           REV,
+                                                           revNextHop, finalNewPwSpine, egressVlanId);
+                if (lamdaResult != SUCCESS) {
+                    return;
+                }
+
+                lamdaResult = deployPolicy(tunnelId,
+                                            newPw.l2TunnelPolicy().cP2(),
+                                            newPw.l2TunnelPolicy().cP2InnerTag(),
+                                            newPw.l2TunnelPolicy().cP2OuterTag(),
+                                            egressVlanId,
+                                            lamdaResult.nextId);
+                if (lamdaResult != SUCCESS) {
+                    return;
+                }
+                deployPseudoWireTerm(newPw.l2Tunnel(),
+                                      newPw.l2TunnelPolicy().cP1(),
+                                      egressVlanId,
+                                      REV, finalNewPwSpine);
+            }
+        });
+    }
+
+    @Override
+    public void processPwaasConfigRemoved(NetworkConfigEvent event) {
+        checkArgument(event.prevConfig().isPresent(),
+                "PrevConfig is not presented in PwaasConfigRemoved event {}", event);
+
+        log.info("Network event : Pseudowire configuration removed!");
+        PwaasConfig config = (PwaasConfig) event.prevConfig().get();
+
+        Set<L2TunnelDescription> pwToRemove = config
+                .getPwIds()
+                .stream()
+                .map(config::getPwDescription)
+                .collect(Collectors.toSet());
+
+        // We teardown all the pseudo wire deployed
+        tearDown(pwToRemove);
+    }
+
+    /**
+     * Helper function for removing a single pseudowire.
+     * <p>
+     * No mastership of CP1 is checked, because it can be called from
+     * the CLI for removal of pseudowires.
+     *
+     * @param l2TunnelId the id of the pseudowire to tear down
+     * @return Returns SUCCESS if no error is obeserved or an appropriate
+     * error on a failure
+     */
+    private Result tearDownPseudowire(long l2TunnelId) {
+
+        CompletableFuture<ObjectiveError> fwdInitNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> fwdTermNextFuture = new CompletableFuture<>();
+
+        CompletableFuture<ObjectiveError> revInitNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> revTermNextFuture = new CompletableFuture<>();
+
+        if (l2TunnelId == 0) {
+            log.warn("Removal process : Tunnel id cannot be 0");
+            return Result.WRONG_PARAMETERS;
+        }
+
+        // check existence of tunnels/policy in the store, if one is missing abort!
+        Versioned<L2Tunnel> l2TunnelVersioned = l2TunnelStore.get(Long.toString(l2TunnelId));
+        Versioned<L2TunnelPolicy> l2TunnelPolicyVersioned = l2PolicyStore.get(Long.toString(l2TunnelId));
+        if ((l2TunnelVersioned == null) || (l2TunnelPolicyVersioned == null)) {
+            log.warn("Removal process : Policy and/or tunnel missing for tunnel id {}", l2TunnelId);
+            return Result.REMOVAL_ERROR;
+        }
+
+        L2TunnelDescription pwToRemove = new DefaultL2TunnelDescription(l2TunnelVersioned.value(),
+                                                                               l2TunnelPolicyVersioned.value());
+
+        // remove the tunnels and the policies from the store
+        l2PolicyStore.remove(Long.toString(l2TunnelId));
+        l2TunnelStore.remove(Long.toString(l2TunnelId));
+
+        // remove the reserved transport vlan
+        if (!pwToRemove.l2Tunnel().transportVlan().equals(UNTAGGED_TRANSPORT_VLAN)) {
+            vlanStore.remove(pwToRemove.l2Tunnel().transportVlan());
+        }
+
+        log.info("Removal process : Tearing down forward direction of pseudowire {}", l2TunnelId);
+
+        VlanId egressVlan = determineEgressVlan(pwToRemove.l2TunnelPolicy().cP1OuterTag(),
+                                                 pwToRemove.l2TunnelPolicy().cP1InnerTag(),
+                                                 pwToRemove.l2TunnelPolicy().cP2OuterTag(),
+                                                 pwToRemove.l2TunnelPolicy().cP2InnerTag());
+        deletePolicy(l2TunnelId,
+                      pwToRemove.l2TunnelPolicy().cP1(),
+                      pwToRemove.l2TunnelPolicy().cP1InnerTag(),
+                      pwToRemove.l2TunnelPolicy().cP1OuterTag(),
+                      egressVlan,
+                      fwdInitNextFuture,
+                      FWD);
+
+        fwdInitNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                // Finally we will tear down the pseudo wire.
+                tearDownPseudoWireInit(l2TunnelId,
+                                        pwToRemove.l2TunnelPolicy().cP1(),
+                                        fwdTermNextFuture,
+                                        FWD);
+            }
+        });
+
+        fwdTermNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                tearDownPseudoWireTerm(pwToRemove.l2Tunnel(),
+                                        pwToRemove.l2TunnelPolicy().cP2(),
+                                        null,
+                                        FWD);
+            }
+        });
+
+        log.info("Removal process : Tearing down reverse direction of pseudowire {}", l2TunnelId);
+
+        egressVlan = determineEgressVlan(pwToRemove.l2TunnelPolicy().cP2OuterTag(),
+                                          pwToRemove.l2TunnelPolicy().cP2InnerTag(),
+                                          pwToRemove.l2TunnelPolicy().cP1OuterTag(),
+                                          pwToRemove.l2TunnelPolicy().cP1InnerTag());
+
+        // We do the same operations on the reverse side.
+        deletePolicy(l2TunnelId,
+                      pwToRemove.l2TunnelPolicy().cP2(),
+                      pwToRemove.l2TunnelPolicy().cP2InnerTag(),
+                      pwToRemove.l2TunnelPolicy().cP2OuterTag(),
+                      egressVlan,
+                      revInitNextFuture,
+                      REV);
+
+        revInitNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                tearDownPseudoWireInit(l2TunnelId,
+                                        pwToRemove.l2TunnelPolicy().cP2(),
+                                        revTermNextFuture,
+                                        REV);
+            }
+        });
+
+        revTermNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                tearDownPseudoWireTerm(pwToRemove.l2Tunnel(),
+                                        pwToRemove.l2TunnelPolicy().cP1(),
+                                        null,
+                                        REV);
+            }
+        });
+
+        return Result.SUCCESS;
+    }
+
+    @Override
+    public void tearDown(Set<L2TunnelDescription> pwToRemove) {
+
+        Result result;
+
+        // We remove all the pw in the configuration file.
+        for (L2TunnelDescription currentL2Tunnel : pwToRemove) {
+            ConnectPoint cp1 = currentL2Tunnel.l2TunnelPolicy().cP1();
+            ConnectPoint cp2 = currentL2Tunnel.l2TunnelPolicy().cP2();
+            long tunnelId = currentL2Tunnel.l2TunnelPolicy().tunnelId();
+
+            // only the master of CP1 will program this pseudowire
+            if (!srManager.isMasterOf(cp1)) {
+                log.debug("Not the master of {}. Ignore pseudo wire removal id={}", cp1, tunnelId);
+                continue;
+            }
+
+            // no need to differentiate here between leaf-leaf and leaf-spine, because
+            // the only change is in the groups, which we do not remove either way
+            log.info("Removing pseudowire {}", tunnelId);
+
+            result = tearDownPseudowire(tunnelId);
+            switch (result) {
+                case WRONG_PARAMETERS:
+                    log.warn("Error in supplied parameters for the pseudowire removal with tunnel id {}!",
+                            tunnelId);
+                    break;
+                case REMOVAL_ERROR:
+                    log.warn("Error in pseudowire removal with tunnel id {}!", tunnelId);
+                    break;
+                default:
+                    log.warn("Pseudowire with tunnel id {} was removed successfully", tunnelId);
+            }
+        }
+    }
+
+    /**
+     * Handles the policy establishment which consists in
+     * create the filtering and forwarding objectives related
+     * to the initiation and termination.
+     *
+     * @param tunnelId     the tunnel id
+     * @param ingress      the ingress point
+     * @param ingressInner the ingress inner tag
+     * @param ingressOuter the ingress outer tag
+     * @param nextId       the next objective id
+     * @param egressVlan   Vlan-id to set, depends on ingress vlan
+     *                     combinations. For example, if pw is double tagged
+     *                     then this is the value of the outer vlan, if single
+     *                     tagged then it is the new value of the single tag.
+     *                     Should be None for untagged traffic.
+     * @return the result of the operation
+     */
+    private Result deployPolicy(long tunnelId, ConnectPoint ingress, VlanId ingressInner,
+                                VlanId ingressOuter, VlanId egressVlan, int nextId) {
+
+        List<Objective> objectives = Lists.newArrayList();
+        // We create the forwarding objective for supporting
+        // the l2 tunnel.
+        ForwardingObjective.Builder fwdBuilder = createInitFwdObjective(tunnelId, ingress.port(), nextId);
+        // We create and add objective context.
+        ObjectiveContext context = new DefaultObjectiveContext((objective) ->
+                                                                log.debug("FwdObj for tunnel {} populated", tunnelId),
+                                                               (objective, error) ->
+                                                                log.warn("Failed to populate fwdrObj " +
+                                                                                 "for tunnel {}", tunnelId, error));
+        objectives.add(fwdBuilder.add(context));
+
+        // We create the filtering objective to define the
+        // permit traffic in the switch
+        FilteringObjective.Builder filtBuilder = createFiltObjective(ingress.port(), ingressInner, ingressOuter);
+
+        // We add the metadata.
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+                .builder()
+                .setTunnelId(tunnelId)
+                .setVlanId(egressVlan);
+        filtBuilder.withMeta(treatment.build());
+
+        // We create and add objective context.
+        context = new DefaultObjectiveContext((objective) -> log.debug("FilterObj for tunnel {} populated", tunnelId),
+                                              (objective, error) -> log.warn("Failed to populate filterObj for " +
+                                                                                     "tunnel {}", tunnelId, error));
+        objectives.add(filtBuilder.add(context));
+
+        for (Objective objective : objectives) {
+            if (objective instanceof ForwardingObjective) {
+                srManager.flowObjectiveService.forward(ingress.deviceId(), (ForwardingObjective) objective);
+                log.debug("Creating new FwdObj for initiation NextObj with id={} for tunnel {}", nextId, tunnelId);
+            } else {
+                srManager.flowObjectiveService.filter(ingress.deviceId(), (FilteringObjective) objective);
+                log.debug("Creating new FiltObj for tunnel {}", tunnelId);
+            }
+        }
+        return SUCCESS;
+    }
+
+    /**
+     * Handles the tunnel establishment which consists in
+     * create the next objectives related to the initiation.
+     *
+     * @param l2Tunnel  the tunnel to deploy
+     * @param ingress   the ingress connect point
+     * @param egress    the egress connect point
+     * @param direction the direction of the pw
+     * @param spinePw if the pseudowire involves a spine switch
+     * @return the result of the operation
+     */
+    private Result deployPseudoWireInit(L2Tunnel l2Tunnel, ConnectPoint ingress,
+                                        ConnectPoint egress, Direction direction,
+                                        Link nextHop, boolean spinePw, VlanId termVlanId) {
+
+        if (nextHop == null) {
+            log.warn("No path between ingress and egress cps for tunnel {}", l2Tunnel.tunnelId());
+            return WRONG_PARAMETERS;
+        }
+
+        // We create the next objective without the metadata
+        // context and id. We check if it already exists in the
+        // store. If not we store as it is in the store.
+        NextObjective.Builder nextObjectiveBuilder = createNextObjective(INITIATION,
+                                                                         nextHop.src(),
+                                                                         nextHop.dst(),
+                                                                         l2Tunnel,
+                                                                         egress.deviceId(),
+                                                                         spinePw,
+                                                                         termVlanId);
+
+        if (nextObjectiveBuilder == null) {
+            return INTERNAL_ERROR;
+        }
+        // We set the metadata. We will use this metadata
+        // to inform the driver we are doing a l2 tunnel.
+        TrafficSelector metadata = DefaultTrafficSelector
+                .builder()
+                .matchTunnelId(l2Tunnel.tunnelId())
+                .build();
+        nextObjectiveBuilder.withMeta(metadata);
+        int nextId = srManager.flowObjectiveService.allocateNextId();
+        if (nextId < 0) {
+            log.warn("Not able to allocate a next id for initiation");
+            return INTERNAL_ERROR;
+        }
+        nextObjectiveBuilder.withId(nextId);
+        String key = generateKey(l2Tunnel.tunnelId(), direction);
+        l2InitiationNextObjStore.put(key, nextObjectiveBuilder.add());
+        ObjectiveContext context = new DefaultObjectiveContext((objective) ->
+                                                                 log.debug("Initiation l2 tunnel rule " +
+                                                                                   "for {} populated",
+                                                                           l2Tunnel.tunnelId()),
+                                                               (objective, error) ->
+                                                                       log.warn("Failed to populate Initiation " +
+                                                                                        "l2 tunnel rule for {}: {}",
+                                                                                l2Tunnel.tunnelId(), error));
+        NextObjective nextObjective = nextObjectiveBuilder.add(context);
+        srManager.flowObjectiveService.next(ingress.deviceId(), nextObjective);
+        log.debug("Initiation next objective for {} not found. Creating new NextObj with id={}",
+                  l2Tunnel.tunnelId(), nextObjective.id());
+        Result result = SUCCESS;
+        result.nextId = nextObjective.id();
+        return result;
+    }
+
+    /**
+     * Handles the tunnel termination, which consists in the creation
+     * of a forwarding objective and a next objective.
+     *
+     * @param l2Tunnel   the tunnel to terminate
+     * @param egress     the egress point
+     * @param egressVlan the expected vlan at egress
+     * @param direction  the direction
+     * @param spinePw if the pseudowire involves a spine switch
+     * @return the result of the operation
+     */
+    private Result deployPseudoWireTerm(L2Tunnel l2Tunnel, ConnectPoint egress,
+                                        VlanId egressVlan, Direction direction, boolean spinePw) {
+
+        // We create the group relative to the termination.
+        NextObjective.Builder nextObjectiveBuilder = createNextObjective(TERMINATION, egress, null,
+                                                                         l2Tunnel, egress.deviceId(),
+                                                                         spinePw,
+                                                                         egressVlan);
+        if (nextObjectiveBuilder == null) {
+            return INTERNAL_ERROR;
+        }
+        TrafficSelector metadata = DefaultTrafficSelector
+                .builder()
+                .matchVlanId(egressVlan)
+                .build();
+        nextObjectiveBuilder.withMeta(metadata);
+        int nextId = srManager.flowObjectiveService.allocateNextId();
+        if (nextId < 0) {
+            log.warn("Not able to allocate a next id for initiation");
+            return INTERNAL_ERROR;
+        }
+        nextObjectiveBuilder.withId(nextId);
+        String key = generateKey(l2Tunnel.tunnelId(), direction);
+        l2TerminationNextObjStore.put(key, nextObjectiveBuilder.add());
+        ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("Termination l2 tunnel rule " +
+                                                                                        "for {} populated",
+                                                                                        l2Tunnel.tunnelId()),
+                                                               (objective, error) -> log.warn("Failed to populate " +
+                                                                                              "termination l2 tunnel " +
+                                                                                              "rule for {}: {}",
+                                                                                              l2Tunnel.tunnelId(),
+                                                                                              error));
+        NextObjective nextObjective = nextObjectiveBuilder.add(context);
+        srManager.flowObjectiveService.next(egress.deviceId(), nextObjective);
+        log.debug("Termination next objective for {} not found. Creating new NextObj with id={}",
+                  l2Tunnel.tunnelId(), nextObjective.id());
+
+        // We create the flow relative to the termination.
+        ForwardingObjective.Builder fwdBuilder = createTermFwdObjective(l2Tunnel.pwLabel(), l2Tunnel.tunnelId(),
+                                                                        egress.port(), nextObjective.id());
+        context = new DefaultObjectiveContext((objective) -> log.debug("FwdObj for tunnel termination {} populated",
+                                                                       l2Tunnel.tunnelId()),
+                                              (objective, error) -> log.warn("Failed to populate fwdrObj" +
+                                                                             " for tunnel termination {}",
+                                                                             l2Tunnel.tunnelId(), error));
+        srManager.flowObjectiveService.forward(egress.deviceId(), fwdBuilder.add(context));
+        log.debug("Creating new FwdObj for termination NextObj with id={} for tunnel {}",
+                  nextId, l2Tunnel.tunnelId());
+
+        if (spinePw) {
+
+            // determine the input port at the
+            PortNumber inPort;
+
+            if (egress.deviceId().
+                    equals(l2Tunnel.pathUsed().get(0).dst().deviceId())) {
+                    inPort = l2Tunnel.pathUsed().get(0).dst().port();
+            } else {
+                    inPort = l2Tunnel.pathUsed().get(0).src().port();
+            }
+
+            MacAddress dstMac;
+            try {
+                dstMac = srManager.deviceConfiguration().getDeviceMac(egress.deviceId());
+            } catch (Exception e) {
+                log.info("Device not found in configuration, no programming of MAC address");
+                dstMac = null;
+            }
+
+            log.info("Populating filtering objective for pseudowire transport" +
+                             " with vlan = {}, port = {}, mac = {}",
+                     l2Tunnel.transportVlan(),
+                     inPort,
+                     dstMac);
+            FilteringObjective.Builder filteringObjectiveBuilder =
+                    createNormalPipelineFiltObjective(inPort, l2Tunnel.transportVlan(), dstMac);
+            context = new DefaultObjectiveContext(( objective ) ->
+                                                          log.debug("Special filtObj for  " + "for {} populated",
+                                                                    l2Tunnel.tunnelId()),
+                                                  ( objective, error ) ->
+                                                          log.warn("Failed to populate " +
+                                                                           "special filtObj " +
+                                                                           "rule for {}: {}",
+                                                                                   l2Tunnel.tunnelId(), error));
+            TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+            filteringObjectiveBuilder.withMeta(treatment.build());
+            srManager.flowObjectiveService.filter(egress.deviceId(), filteringObjectiveBuilder.add(context));
+            log.debug("Creating new special FiltObj for termination point with tunnel {} for port {}",
+                      l2Tunnel.tunnelId(),
+                      inPort);
+        }
+
+        return SUCCESS;
+    }
+
+
+    /**
+     * Creates the filtering objective according to a given port and vlanid.
+     *
+     * @param inPort   the in port
+     * @param vlanId the inner vlan tag
+     * @return the filtering objective
+     */
+    private FilteringObjective.Builder createNormalPipelineFiltObjective(PortNumber inPort,
+                                                                         VlanId vlanId,
+                                                                         MacAddress dstMac) {
+
+        log.info("Creating filtering objective for pseudowire transport with vlan={}, port={}, mac={}",
+                 vlanId,
+                 inPort,
+                 dstMac);
+        FilteringObjective.Builder fwdBuilder = DefaultFilteringObjective
+                .builder()
+                .withKey(Criteria.matchInPort(inPort))
+                .addCondition(Criteria.matchVlanId(vlanId))
+                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
+                .permit()
+                .fromApp(srManager.appId());
+
+        if (dstMac != null) {
+            fwdBuilder.addCondition(Criteria.matchEthDst(dstMac));
+        }
+
+        return fwdBuilder;
+    }
+
+    /**
+     * Creates the filtering objective according to a given policy.
+     *
+     * @param inPort   the in port
+     * @param innerTag the inner vlan tag
+     * @param outerTag the outer vlan tag
+     * @return the filtering objective
+     */
+    private FilteringObjective.Builder createFiltObjective(PortNumber inPort, VlanId innerTag, VlanId outerTag) {
+
+        log.info("Creating filtering objective for vlans {} / {}", outerTag, innerTag);
+        return DefaultFilteringObjective
+                .builder()
+                .withKey(Criteria.matchInPort(inPort))
+                .addCondition(Criteria.matchInnerVlanId(innerTag))
+                .addCondition(Criteria.matchVlanId(outerTag))
+                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
+                .permit()
+                .fromApp(srManager.appId());
+    }
+
+    /**
+     * Creates the forwarding objective for the termination.
+     *
+     * @param pwLabel    the pseudo wire label
+     * @param tunnelId   the tunnel id
+     * @param egressPort the egress port
+     * @param nextId     the next step
+     * @return the forwarding objective to support the termination
+     */
+    private ForwardingObjective.Builder createTermFwdObjective(MplsLabel pwLabel, long tunnelId,
+                                                               PortNumber egressPort, int nextId) {
+
+        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder trafficTreatment = DefaultTrafficTreatment.builder();
+        // The flow has to match on the pw label and bos
+        trafficSelector.matchEthType(Ethernet.MPLS_UNICAST);
+        trafficSelector.matchMplsLabel(pwLabel);
+        trafficSelector.matchMplsBos(true);
+        // The flow has to decrement ttl, restore ttl in
+        // pop mpls, set tunnel id and port.
+        trafficTreatment.decMplsTtl();
+        trafficTreatment.copyTtlIn();
+        trafficTreatment.popMpls();
+        trafficTreatment.setTunnelId(tunnelId);
+        trafficTreatment.setOutput(egressPort);
+
+        return DefaultForwardingObjective
+                .builder()
+                .fromApp(srManager.appId())
+                .makePermanent()
+                .nextStep(nextId)
+                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
+                .withSelector(trafficSelector.build())
+                .withTreatment(trafficTreatment.build())
+                .withFlag(VERSATILE);
+    }
+
+    /**
+     * Creates the forwarding objective for the initiation.
+     *
+     * @param tunnelId the tunnel id
+     * @param inPort   the input port
+     * @param nextId   the next step
+     * @return the forwarding objective to support the initiation.
+     */
+    private ForwardingObjective.Builder createInitFwdObjective(long tunnelId, PortNumber inPort, int nextId) {
+
+        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector.builder();
+
+        // The flow has to match on the mpls logical
+        // port and the tunnel id.
+        trafficSelector.matchTunnelId(tunnelId);
+        trafficSelector.matchInPort(inPort);
+
+        return DefaultForwardingObjective
+                .builder()
+                .fromApp(srManager.appId())
+                .makePermanent()
+                .nextStep(nextId)
+                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
+                .withSelector(trafficSelector.build())
+                .withFlag(VERSATILE);
+
+    }
+
+    /**
+     * Creates the next objective according to a given
+     * pipeline. We don't set the next id and we don't
+     * create the final meta to check if we are re-using
+     * the same next objective for different tunnels.
+     *
+     * @param pipeline the pipeline to support
+     * @param srcCp    the source port
+     * @param dstCp    the destination port
+     * @param l2Tunnel the tunnel to support
+     * @param egressId the egress device id
+     * @param spinePw if the pw involves a spine switch
+     * @return the next objective to support the pipeline
+     */
+    private NextObjective.Builder createNextObjective(Pipeline pipeline, ConnectPoint srcCp,
+                                                      ConnectPoint dstCp,  L2Tunnel l2Tunnel,
+                                                      DeviceId egressId, boolean spinePw, VlanId termVlanId) {
+        NextObjective.Builder nextObjBuilder;
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+        if (pipeline == INITIATION) {
+            nextObjBuilder = DefaultNextObjective
+                    .builder()
+                    .withType(NextObjective.Type.SIMPLE)
+                    .fromApp(srManager.appId());
+            // The pw label is the bottom of stack. It has to
+            // be different -1.
+            if (l2Tunnel.pwLabel().toInt() == MplsLabel.MAX_MPLS) {
+                log.warn("Pw label not configured");
+                return null;
+            }
+            treatmentBuilder.pushMpls();
+            treatmentBuilder.setMpls(l2Tunnel.pwLabel());
+            treatmentBuilder.setMplsBos(true);
+            treatmentBuilder.copyTtlOut();
+
+            // If the inter-co label is present we have to set the label.
+            if (l2Tunnel.interCoLabel().toInt() != MplsLabel.MAX_MPLS) {
+                treatmentBuilder.pushMpls();
+                treatmentBuilder.setMpls(l2Tunnel.interCoLabel());
+                treatmentBuilder.setMplsBos(false);
+                treatmentBuilder.copyTtlOut();
+            }
+
+            // if pw is leaf-to-leaf we need to
+            // add the routing label also
+            if (!spinePw) {
+                // We retrieve the sr label from the config
+                // specific for pseudowire traffic
+                // using the egress leaf device id.
+                MplsLabel srLabel;
+                try {
+                    srLabel = MplsLabel.mplsLabel(srManager.deviceConfiguration().getPWRoutingLabel(egressId));
+
+                } catch (DeviceConfigNotFoundException e) {
+                    log.warn("Sr label for pw traffic not configured");
+                    return null;
+                }
+
+                treatmentBuilder.pushMpls();
+                treatmentBuilder.setMpls(srLabel);
+                treatmentBuilder.setMplsBos(false);
+                treatmentBuilder.copyTtlOut();
+            }
+
+            // We have to rewrite the src and dst mac address.
+            MacAddress ingressMac;
+            try {
+                ingressMac = srManager.deviceConfiguration().getDeviceMac(srcCp.deviceId());
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn("Was not able to find the ingress mac");
+                return null;
+            }
+            treatmentBuilder.setEthSrc(ingressMac);
+            MacAddress neighborMac;
+            try {
+                neighborMac = srManager.deviceConfiguration().getDeviceMac(dstCp.deviceId());
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn("Was not able to find the neighbor mac");
+                return null;
+            }
+            treatmentBuilder.setEthDst(neighborMac);
+
+            // if not a leaf-spine pw we need to POP the vlan at the output
+            // since we carry this traffic untagged.
+            if (!spinePw) {
+                treatmentBuilder.popVlan();
+            }
+
+            // set the appropriate transport vlan
+            treatmentBuilder.setVlanId(l2Tunnel.transportVlan());
+        } else {
+            // We create the next objective which
+            // will be a simple l2 group.
+            nextObjBuilder = DefaultNextObjective
+                    .builder()
+                    .withType(NextObjective.Type.SIMPLE)
+                    .fromApp(srManager.appId());
+
+            // for termination point we use the outer vlan of the
+            // encapsulated packet
+            treatmentBuilder.setVlanId(termVlanId);
+        }
+
+        treatmentBuilder.setOutput(srcCp.port());
+        nextObjBuilder.addTreatment(treatmentBuilder.build());
+        return nextObjBuilder;
+    }
+
+    /**
+     * Reverses a link.
+     *
+     * @param link link to be reversed
+     * @return the reversed link
+     */
+    private Link reverseLink(Link link) {
+
+        DefaultLink.Builder linkBuilder = DefaultLink.builder();
+
+        linkBuilder.src(link.dst());
+        linkBuilder.dst(link.src());
+        linkBuilder.type(link.type());
+        linkBuilder.providerId(link.providerId());
+
+        return linkBuilder.build();
+    }
+
+    /**
+     * Returns the path betwwen two connect points.
+     *
+     * @param srcCp source connect point
+     * @param dstCp destination connect point
+     * @return the path
+     */
+    private List<Link> getPath(ConnectPoint srcCp, ConnectPoint dstCp) {
+        /* TODO We retrieve a set of paths in case of a link failure, what happens
+         * if the TopologyService gets the link notification AFTER us and has not updated the paths?
+         *
+         * TODO This has the potential to act on old topology.
+         * Maybe we should make SRManager be a listener on topology events instead raw link events.
+         */
+        Set<Path> paths = srManager.topologyService.getPaths(
+                srManager.topologyService.currentTopology(),
+                srcCp.deviceId(), dstCp.deviceId());
+
+        log.debug("Paths obtained from topology service {}", paths);
+
+        // We randomly pick a path.
+        if (paths.isEmpty()) {
+            return null;
+        }
+        int size = paths.size();
+        int index = RandomUtils.nextInt(0, size);
+
+        List<Link> result = Iterables.get(paths, index).links();
+        log.debug("Randomly picked a path {}", result);
+
+        return result;
+    }
+
+    /**
+     * Deletes a given policy using the parameter supplied.
+     *
+     * @param tunnelId     the tunnel id
+     * @param ingress      the ingress point
+     * @param ingressInner the ingress inner vlan id
+     * @param ingressOuter the ingress outer vlan id
+     * @param future       to perform the async operation
+     * @param direction    the direction: forward or reverse
+     */
+    private void deletePolicy(long tunnelId, ConnectPoint ingress, VlanId ingressInner, VlanId ingressOuter,
+                              VlanId egressVlan, CompletableFuture<ObjectiveError> future, Direction direction) {
+
+        String key = generateKey(tunnelId, direction);
+        if (!l2InitiationNextObjStore.containsKey(key)) {
+            log.warn("Abort delete of policy for tunnel {}: next does not exist in the store", tunnelId);
+            if (future != null) {
+                future.complete(null);
+            }
+            return;
+        }
+        NextObjective nextObjective = l2InitiationNextObjStore.get(key).value();
+        int nextId = nextObjective.id();
+        List<Objective> objectives = Lists.newArrayList();
+        // We create the forwarding objective.
+        ForwardingObjective.Builder fwdBuilder = createInitFwdObjective(tunnelId, ingress.port(), nextId);
+        ObjectiveContext context = new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.debug("Previous fwdObj for policy {} removed", tunnelId);
+                if (future != null) {
+                    future.complete(null);
+                }
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.warn("Failed to remove previous fwdObj for policy {}: {}", tunnelId, error);
+                if (future != null) {
+                    future.complete(error);
+                }
+            }
+        };
+        objectives.add(fwdBuilder.remove(context));
+        // We create the filtering objective to define the
+        // permit traffic in the switch
+        FilteringObjective.Builder filtBuilder = createFiltObjective(ingress.port(), ingressInner, ingressOuter);
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+                .builder()
+                .setTunnelId(tunnelId)
+                .setVlanId(egressVlan);
+        filtBuilder.withMeta(treatment.build());
+        context = new DefaultObjectiveContext((objective) -> log.debug("FilterObj for policy {} revoked", tunnelId),
+                                              (objective, error) ->
+                                                      log.warn("Failed to revoke filterObj for policy {}",
+                                                               tunnelId, error));
+        objectives.add(filtBuilder.remove(context));
+
+        for (Objective objective : objectives) {
+            if (objective instanceof ForwardingObjective) {
+                srManager.flowObjectiveService.forward(ingress.deviceId(), (ForwardingObjective) objective);
+            } else {
+                srManager.flowObjectiveService.filter(ingress.deviceId(), (FilteringObjective) objective);
+            }
+        }
+    }
+
+    /**
+     * Deletes the pseudo wire initiation.
+     *
+     * @param l2TunnelId the tunnel id
+     * @param ingress    the ingress connect point
+     * @param future     to perform an async operation
+     * @param direction  the direction: reverse of forward
+     */
+    private void tearDownPseudoWireInit(long l2TunnelId, ConnectPoint ingress,
+                                        CompletableFuture<ObjectiveError> future, Direction direction) {
+
+        String key = generateKey(l2TunnelId, direction);
+        if (!l2InitiationNextObjStore.containsKey(key)) {
+            log.info("Abort delete of {} for {}: next does not exist in the store", INITIATION, key);
+            if (future != null) {
+                future.complete(null);
+            }
+            return;
+        }
+        NextObjective nextObjective = l2InitiationNextObjStore.get(key).value();
+
+        // un-comment in case you want to delete groups used by the pw
+        // however, this will break the update of pseudowires cause the L2 interface group can
+        // not be deleted (it is referenced by other groups)
+        /*
+        ObjectiveContext context = new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.debug("Previous {} next for {} removed", INITIATION, key);
+                if (future != null) {
+                    future.complete(null);
+                }
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.warn("Failed to remove previous {} next for {}: {}", INITIATION, key, error);
+                if (future != null) {
+                    future.complete(error);
+                }
+            }
+        };
+        srManager.flowObjectiveService.next(ingress.deviceId(), (NextObjective) nextObjective.copy().remove(context));
+        */
+
+        future.complete(null);
+        l2InitiationNextObjStore.remove(key);
+    }
+
+    /**
+     * Deletes the pseudo wire termination.
+     *
+     * @param l2Tunnel  the tunnel
+     * @param egress    the egress connect point
+     * @param future    the async task
+     * @param direction the direction of the tunnel
+     */
+    private void tearDownPseudoWireTerm(L2Tunnel l2Tunnel,
+                                        ConnectPoint egress,
+                                        CompletableFuture<ObjectiveError> future,
+                                        Direction direction) {
+
+        String key = generateKey(l2Tunnel.tunnelId(), direction);
+        if (!l2TerminationNextObjStore.containsKey(key)) {
+            log.info("Abort delete of {} for {}: next does not exist in the store", TERMINATION, key);
+            if (future != null) {
+                future.complete(null);
+            }
+            return;
+        }
+        NextObjective nextObjective = l2TerminationNextObjStore.get(key).value();
+        ForwardingObjective.Builder fwdBuilder = createTermFwdObjective(l2Tunnel.pwLabel(),
+                                                                        l2Tunnel.tunnelId(),
+                                                                        egress.port(),
+                                                                        nextObjective.id());
+        ObjectiveContext context = new DefaultObjectiveContext((objective) ->
+                                                                       log.debug("FwdObj for {} {}, " +
+                                                                                         "direction {} removed",
+                                                                                        TERMINATION,
+                                                                                        l2Tunnel.tunnelId(),
+                                                                                        direction),
+                                                               (objective, error) ->
+                                                                       log.warn("Failed to remove fwdObj " +
+                                                                                        "for {} {}" +
+                                                                                        ", direction {}",
+                                                                                TERMINATION,
+                                                                                l2Tunnel.tunnelId(),
+                                                                                error,
+                                                                                direction));
+        srManager.flowObjectiveService.forward(egress.deviceId(), fwdBuilder.remove(context));
+
+        // un-comment in case you want to delete groups used by the pw
+        // however, this will break the update of pseudowires cause the L2 interface group can
+        // not be deleted (it is referenced by other groups)
+        /*
+        context = new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.debug("Previous {} next for {} removed", TERMINATION, key);
+                if (future != null) {
+                    future.complete(null);
+                }
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.warn("Failed to remove previous {} next for {}: {}", TERMINATION, key, error);
+                if (future != null) {
+                    future.complete(error);
+                }
+            }
+        };
+        srManager.flowObjectiveService.next(egress.deviceId(), (NextObjective) nextObjective.copy().remove(context));
+        */
+
+        // delete the extra filtering objective for terminating
+        // spine-spine pws
+        if (!l2Tunnel.transportVlan().equals(UNTAGGED_TRANSPORT_VLAN)) {
+
+            // determine the input port at the
+            PortNumber inPort;
+
+            if (egress.deviceId().
+                    equals(l2Tunnel.pathUsed().get(0).dst().deviceId())) {
+                inPort = l2Tunnel.pathUsed().get(0).dst().port();
+            } else {
+                inPort = l2Tunnel.pathUsed().get(0).src().port();
+            }
+
+            MacAddress dstMac;
+            try {
+                dstMac = srManager.deviceConfiguration().getDeviceMac(egress.deviceId());
+            } catch (Exception e) {
+                log.info("Device not found in configuration, no programming of MAC address");
+                dstMac = null;
+            }
+
+            log.info("Removing filtering objective for pseudowire transport" +
+                             " with vlan = {}, port = {}, mac = {}",
+                     l2Tunnel.transportVlan(),
+                     inPort,
+                     dstMac);
+            FilteringObjective.Builder filteringObjectiveBuilder =
+                    createNormalPipelineFiltObjective(inPort, l2Tunnel.transportVlan(), dstMac);
+            context = new DefaultObjectiveContext(( objective ) ->
+                                                          log.debug("Special filtObj for  " + "for {} removed",
+                                                                    l2Tunnel.tunnelId()), ( objective, error ) ->
+                    log.warn("Failed to populate " + "special filtObj " +
+                                     "rule for {}: {}", l2Tunnel.tunnelId(), error));
+            TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+            filteringObjectiveBuilder.withMeta(treatment.build());
+            srManager.flowObjectiveService.filter(egress.deviceId(), filteringObjectiveBuilder.remove(context));
+            log.debug("Removing special FiltObj for termination point with tunnel {} for port {}",
+                      l2Tunnel.tunnelId(),
+                      inPort);
+        }
+
+        l2TerminationNextObjStore.remove(key);
+        future.complete(null);
+    }
+
+    /**
+     * Utilities to generate pw key.
+     *
+     * @param tunnelId  the tunnel id
+     * @param direction the direction of the pw
+     * @return the key of the store
+     */
+    private String generateKey(long tunnelId, Direction direction) {
+        return String.format("%s-%s", tunnelId, direction);
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelPolicy.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelPolicy.java
new file mode 100644
index 0000000..4738744
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelPolicy.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.pwaas;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Implementation of the default l2 tunnel policy.
+ */
+public class DefaultL2TunnelPolicy implements L2TunnelPolicy {
+
+    /**
+     * Id of the tunnel associated to this policy.
+     */
+    private long tunnelId;
+    /**
+     * First connect point.
+     */
+    private ConnectPoint cP1;
+    /**
+     * Second connect point.
+     */
+    private ConnectPoint cP2;
+    /**
+     * cP1 inner vlan tag. Used in QinQ packets.
+     */
+    private VlanId cP1InnerTag;
+    /**
+     * cP1 outer vlan tag.
+     */
+    private VlanId cP1OuterTag;
+    /**
+     * cP2 inner vlan tag. Used in QinQ packets.
+     */
+    private VlanId cP2InnerTag;
+    /**
+     * cP2 outer vlan tag.
+     */
+    private VlanId cP2OuterTag;
+
+    /**
+     * Creates a default l2 tunnel policy using
+     * the given parameters.
+     *
+     * @param tunnelId the tunnel id
+     * @param cP1 the first connect point
+     * @param cP1InnerTag the cP1 inner tag
+     * @param cP1OuterTag the cP1 outer tag
+     * @param cP2 the second connect point
+     * @param cP2InnerTag the cP2 inner tag
+     * @param cP2OuterTag the cP2 outer tag
+     */
+    public DefaultL2TunnelPolicy(long tunnelId,
+                                 ConnectPoint cP1, VlanId cP1InnerTag, VlanId cP1OuterTag,
+                                 ConnectPoint cP2, VlanId cP2InnerTag, VlanId cP2OuterTag) {
+        this.cP1 = checkNotNull(cP1);
+        this.cP2 = checkNotNull(cP2);
+        this.tunnelId = tunnelId;
+        this.cP1InnerTag = cP1InnerTag;
+        this.cP1OuterTag = cP1OuterTag;
+        this.cP2InnerTag = cP2InnerTag;
+        this.cP2OuterTag = cP2OuterTag;
+    }
+
+    /**
+     * Creates a default l2 policy given the provided policy.
+     * @param policy L2policy to replicate
+     */
+    public DefaultL2TunnelPolicy(DefaultL2TunnelPolicy policy) {
+
+        this.cP1 = policy.cP1;
+        this.cP2 = policy.cP2;
+        this.tunnelId = policy.tunnelId;
+        this.cP1InnerTag = policy.cP1InnerTag;
+        this.cP1OuterTag = policy.cP1OuterTag;
+        this.cP2InnerTag = policy.cP2InnerTag;
+        this.cP2OuterTag = policy.cP2OuterTag;
+    }
+
+    @Override
+    public ConnectPoint cP1() {
+        return cP1;
+    }
+
+    @Override
+    public ConnectPoint cP2() {
+        return cP2;
+    }
+
+    @Override
+    public VlanId cP1InnerTag() {
+        return cP1InnerTag;
+    }
+
+    @Override
+    public VlanId cP1OuterTag() {
+        return cP1OuterTag;
+    }
+
+    @Override
+    public VlanId cP2InnerTag() {
+        return cP2InnerTag;
+    }
+
+    @Override
+    public VlanId cP2OuterTag() {
+        return cP2OuterTag;
+    }
+
+    @Override
+    public long tunnelId() {
+        return this.tunnelId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(tunnelId,
+                            cP1,
+                            cP2,
+                            cP1InnerTag,
+                            cP1OuterTag,
+                            cP2InnerTag,
+                            cP2OuterTag
+        );
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o instanceof DefaultL2TunnelPolicy) {
+            DefaultL2TunnelPolicy that = (DefaultL2TunnelPolicy) o;
+            if (this.tunnelId == that.tunnelId &&
+                    this.cP1.equals(that.cP1) &&
+                    this.cP2.equals(that.cP2) &&
+                    this.cP1InnerTag.equals(that.cP1InnerTag) &&
+                    this.cP1OuterTag.equals(that.cP1OuterTag) &&
+                    this.cP2InnerTag.equals(that.cP2InnerTag) &&
+                    this.cP2OuterTag.equals(that.cP2OuterTag)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("tunnelId", tunnelId())
+                .add("cP1", cP1())
+                .add("cP2", cP2())
+                .add("cP1InnerTag", cP1InnerTag())
+                .add("cP1OuterTag", cP1OuterTag())
+                .add("cP2InnerTag", cP2InnerTag())
+                .add("cP2OuterTag", cP2OuterTag())
+                .toString();
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2Mode.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2Mode.java
new file mode 100644
index 0000000..685a606
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2Mode.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.pwaas;
+
+/**
+ * Enum to identify mode of the pwaas.
+ */
+public enum L2Mode {
+    /**
+     * Raw mode.
+     */
+    RAW,
+    /**
+     * Tagged mode. In this case the packet need
+     * the sd tag.
+     */
+    TAGGED
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2Tunnel.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2Tunnel.java
new file mode 100644
index 0000000..3e98480
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2Tunnel.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.pwaas;
+
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.Link;
+
+import java.util.List;
+
+public interface L2Tunnel {
+
+    /**
+     * Return the mode of the l2 tunnel.
+     *
+     * @return The pw mode.
+     */
+    L2Mode pwMode();
+
+    /**
+     * Returns the service delimiting tag.
+     *
+     * @return the sd tag
+     */
+    VlanId sdTag();
+
+    /**
+     * Returns the id of the tunnel.
+     *
+     * @return the tunnel id
+     */
+    long tunnelId();
+
+    /**
+     * Return the label of the pseudowire.
+     *
+     * @return the pw label.
+     */
+    MplsLabel pwLabel();
+
+    /**
+     * Returns the path used by the pseudowire.
+     *
+     * @return The path that is used
+     */
+    List<Link> pathUsed();
+
+    /**
+     * Returns the transport vlan used by the pseudowire.
+     *
+     * @return The transport vlan
+     */
+    VlanId transportVlan();
+
+    /**
+     * Returns the inter-co label used by the pseudowire.
+     *
+     * @return The inter CO label.
+     */
+    MplsLabel interCoLabel();
+
+    /**
+     * Sets the path that this pw uses.
+     *
+     * @param path The apth to use
+     */
+    void setPath(List<Link> path);
+
+    /**
+     * Set the transport vlan that this pw will use.
+     *
+     * @param vlan The vlan to use.
+     */
+    void setTransportVlan(VlanId vlan);
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelDescription.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelDescription.java
new file mode 100644
index 0000000..7be187a
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelDescription.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.pwaas;
+
+public interface L2TunnelDescription {
+
+    /**
+     * Returns the l2 tunnel.
+     *
+     * @return the l2 tunnel
+     */
+    L2Tunnel l2Tunnel();
+
+    /**
+     * Returns the l2 tunnel policy.
+     *
+     * @return the l2 tunnel policy.
+     */
+    L2TunnelPolicy l2TunnelPolicy();
+
+    /**
+     * Sets the l2 tunnel.
+     *
+     * @param tunnel the l2 tunnel to set.
+     */
+    void setL2Tunnel(L2Tunnel tunnel);
+
+    /**
+     * Sets the l2 policy.
+     *
+     * @param policy the policy to set.
+     */
+    void setL2TunnelPolicy(L2TunnelPolicy policy);
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
new file mode 100644
index 0000000..3a89a21
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.pwaas;
+
+import org.onosproject.net.Link;
+import org.onosproject.net.config.NetworkConfigEvent;
+
+import java.util.List;
+import java.util.Set;
+
+public interface L2TunnelHandler {
+    void init();
+
+    /**
+     * Returns a copy of the l2 policies that exist in the store.
+     *
+     * @return The l2 policies
+     */
+    List<L2TunnelPolicy> getL2Policies();
+
+    /**
+     * Returns a copy of the l2 tunnels that exist in the store.
+     *
+     * @return The l2 tunnels.
+     */
+    List<L2Tunnel> getL2Tunnels();
+
+    /**
+     * Processes a link removal. Finds affected pseudowires and rewires them.
+     * TODO: Make it also take into account failures of links that are used for pw
+     * traffic in the spine.
+     * @param link The link that failed
+     */
+    void processLinkDown(Link link);
+
+    /**
+     * Processes Pwaas Config added event.
+     *
+     * @param event network config add event
+     */
+    void processPwaasConfigAdded(NetworkConfigEvent event);
+
+    /**
+     * Processes PWaaS Config updated event.
+     *
+     * @param event network config updated event
+     */
+    void processPwaasConfigUpdated(NetworkConfigEvent event);
+
+    /**
+     * Processes Pwaas Config removed event.
+     *
+     * @param event network config removed event
+     */
+    void processPwaasConfigRemoved(NetworkConfigEvent event);
+
+    /**
+     * Helper function to handle the pw removal.
+     * <p>
+     * This method should for the mastership of the device because it is
+     * used only from network configuration updates, thus we only want
+     * one instance only to program each pseudowire.
+     *
+     * @param pwToRemove the pseudo wires to remove
+     */
+    void tearDown(Set<L2TunnelDescription> pwToRemove);
+
+    /**
+     * Pwaas pipelines.
+     */
+    enum Pipeline {
+        /**
+         * The initiation pipeline.
+         */
+        INITIATION, /**
+         * The termination pipeline.
+         */
+        TERMINATION
+    }
+
+    /**
+     * Enum helper to carry results of various operations.
+     */
+    enum Result {
+        /**
+         * Happy ending scenario.
+         */
+        SUCCESS(0, "No error occurred"),
+
+        /**
+         * We have problems with the supplied parameters.
+         */
+        WRONG_PARAMETERS(1, "Wrong parameters"),
+
+        /**
+         * We have an internal error during the deployment
+         * or removal phase.
+         */
+        INTERNAL_ERROR(3, "Internal error"),
+
+        /**
+         *
+         */
+        REMOVAL_ERROR(5, "Can not remove pseudowire from network configuration"),
+
+        /**
+         *
+         */
+        ADDITION_ERROR(6, "Can not add pseudowire in network configuration"),
+
+        /**
+         *
+         */
+        CONFIG_NOT_FOUND(7, "Can not find configuration class for pseudowires");
+
+        private final int code;
+        private final String description;
+        public int nextId;
+
+        Result(int code, String description) {
+            this.code = code;
+            this.description = description;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        @Override
+        public String toString() {
+            return code + ": " + description;
+        }
+    }
+
+    /**
+     * Enum helper for handling the direction of the pw.
+     */
+    enum Direction {
+        /**
+         * The forward direction of the pseudo wire.
+         */
+        FWD, /**
+         * The reverse direction of the pseudo wire.
+         */
+        REV
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelPolicy.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelPolicy.java
new file mode 100644
index 0000000..17be45b
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelPolicy.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.pwaas;
+
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+
+public interface L2TunnelPolicy {
+
+    /**
+     * Returns the first connect point of the policy.
+     *
+     * @return first connect point
+     */
+    ConnectPoint cP1();
+
+    /**
+     * Returns the second connect point of the policy.
+     *
+     * @return second connect point
+     */
+    ConnectPoint cP2();
+
+    /**
+     * Returns the cP1 inner vlan tag of the policy.
+     *
+     * @return cP1 inner vlan tag
+     */
+    VlanId cP1InnerTag();
+
+    /**
+     * Returns the cP1 outer vlan tag of the policy.
+     *
+     * @return cP1 outer vlan tag
+     */
+    VlanId cP1OuterTag();
+
+    /**
+     * Returns the cP2 inner vlan tag of the policy.
+     *
+     * @return cP2 inner vlan tag
+     */
+    VlanId cP2InnerTag();
+
+    /**
+     * Returns the cP2 outer vlan tag of the policy.
+     *
+     * @return cP2 outer vlan tag
+     */
+    VlanId cP2OuterTag();
+
+    /**
+     * Returns the tunnel ID of the policy.
+     *
+     * @return Tunnel ID
+     */
+    long tunnelId();
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/package-info.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/package-info.java
new file mode 100644
index 0000000..463b163
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Set of resources implementing the Pwaas.
+ */
+package org.onosproject.segmentrouting.pwaas;
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/DestinationSetNextObjectiveStoreKey.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/DestinationSetNextObjectiveStoreKey.java
new file mode 100644
index 0000000..9b6e621
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/DestinationSetNextObjectiveStoreKey.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licedses/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.storekey;
+
+import java.util.Objects;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.segmentrouting.grouphandler.DestinationSet;
+
+/**
+ * Key of Destination set next objective store.
+ */
+public class DestinationSetNextObjectiveStoreKey {
+    private final DeviceId deviceId;
+    private final DestinationSet ds;
+
+    /**
+     * Constructs the key of destination set next objective store.
+     *
+     * @param deviceId device ID
+     * @param ds destination set
+     */
+    public DestinationSetNextObjectiveStoreKey(DeviceId deviceId,
+                                            DestinationSet ds) {
+        this.deviceId = deviceId;
+        this.ds = ds;
+    }
+
+    /**
+     * Returns the device ID in the key.
+     *
+     * @return device ID
+     */
+    public DeviceId deviceId() {
+        return this.deviceId;
+    }
+
+    /**
+     * Returns the destination set in the key.
+     *
+     * @return destination set
+     */
+    public DestinationSet destinationSet() {
+        return this.ds;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof DestinationSetNextObjectiveStoreKey)) {
+            return false;
+        }
+        DestinationSetNextObjectiveStoreKey that =
+                (DestinationSetNextObjectiveStoreKey) o;
+        return (Objects.equals(this.deviceId, that.deviceId) &&
+                Objects.equals(this.ds, that.ds));
+    }
+
+    // The list of destination ids and label are used for comparison.
+    @Override
+    public int hashCode() {
+        int result = 17;
+        result = 31 * result + Objects.hashCode(this.deviceId)
+                + Objects.hashCode(this.ds);
+
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "Device: " + deviceId + " " + ds;
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/McastStoreKey.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/McastStoreKey.java
new file mode 100644
index 0000000..6891b77
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/McastStoreKey.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.storekey;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.Objects;
+
+/**
+ * Key of multicast next objective store.
+ */
+public class McastStoreKey {
+    private final IpAddress mcastIp;
+    private final DeviceId deviceId;
+
+    /**
+     * Constructs the key of multicast next objective store.
+     *
+     * @param mcastIp multicast group IP address
+     * @param deviceId device ID
+     */
+    public McastStoreKey(IpAddress mcastIp, DeviceId deviceId) {
+        checkNotNull(mcastIp, "mcastIp cannot be null");
+        checkNotNull(deviceId, "deviceId cannot be null");
+        checkArgument(mcastIp.isMulticast(), "mcastIp must be a multicast address");
+        this.mcastIp = mcastIp;
+        this.deviceId = deviceId;
+    }
+
+    /**
+     * Returns the multicast IP address of this key.
+     *
+     * @return multicast IP
+     */
+    public IpAddress mcastIp() {
+        return mcastIp;
+    }
+
+    /**
+     * Returns the device ID of this key.
+     *
+     * @return device ID
+     */
+    public DeviceId deviceId() {
+        return deviceId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof McastStoreKey)) {
+            return false;
+        }
+        McastStoreKey that =
+                (McastStoreKey) o;
+        return (Objects.equals(this.mcastIp, that.mcastIp) &&
+                Objects.equals(this.deviceId, that.deviceId));
+    }
+
+    @Override
+    public int hashCode() {
+         return Objects.hash(mcastIp, deviceId);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(getClass())
+                .add("mcastIp", mcastIp)
+                .add("deviceId", deviceId)
+                .toString();
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/PortNextObjectiveStoreKey.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/PortNextObjectiveStoreKey.java
new file mode 100644
index 0000000..0429bd1
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/PortNextObjectiveStoreKey.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.segmentrouting.storekey;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+
+import java.util.Objects;
+
+/**
+ * Key of Device/Port to NextObjective store.
+ *
+ * Since there can be multiple next objectives to the same physical port,
+ * we differentiate between them by including the treatment in the key.
+ */
+public class PortNextObjectiveStoreKey {
+    private final DeviceId deviceId;
+    private final PortNumber portNum;
+    private final TrafficTreatment treatment;
+    private final TrafficSelector meta;
+
+    /**
+     * Constructs the key of port next objective store.
+     *
+     * @param deviceId device ID
+     * @param portNum port number
+     * @param treatment treatment that will be applied to the interface
+     * @param meta optional data to pass to the driver
+     */
+    public PortNextObjectiveStoreKey(DeviceId deviceId, PortNumber portNum,
+                                     TrafficTreatment treatment,
+                                     TrafficSelector meta) {
+        this.deviceId = deviceId;
+        this.portNum = portNum;
+        this.treatment = treatment;
+        this.meta = meta;
+    }
+
+    /**
+     * Gets device id in this PortNextObjectiveStoreKey.
+     *
+     * @return device id
+     */
+    public DeviceId deviceId() {
+        return deviceId;
+    }
+
+    /**
+     * Gets port information in this PortNextObjectiveStoreKey.
+     *
+     * @return port information
+     */
+    public PortNumber portNumber() {
+        return portNum;
+    }
+
+    /**
+     * Gets treatment information in this PortNextObjectiveStoreKey.
+     *
+     * @return treatment information
+     */
+    public TrafficTreatment treatment() {
+        return treatment;
+    }
+
+    /**
+     * Gets metadata information in this PortNextObjectiveStoreKey.
+     *
+     * @return meta information
+     */
+    public TrafficSelector meta() {
+        return meta;
+    }
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof PortNextObjectiveStoreKey)) {
+            return false;
+        }
+        PortNextObjectiveStoreKey that =
+                (PortNextObjectiveStoreKey) o;
+        return (Objects.equals(this.deviceId, that.deviceId) &&
+                Objects.equals(this.portNum, that.portNum) &&
+                Objects.equals(this.treatment, that.treatment) &&
+                Objects.equals(this.meta, that.meta));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(deviceId, portNum, treatment, meta);
+    }
+
+    @Override
+    public String toString() {
+        return "Device: " + deviceId + " Port: " + portNum +
+                " Treatment: " + treatment +
+                " Meta: " + meta;
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/VlanNextObjectiveStoreKey.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/VlanNextObjectiveStoreKey.java
new file mode 100644
index 0000000..5d9f2fd
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/VlanNextObjectiveStoreKey.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.storekey;
+
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+/**
+ * Key of VLAN to NextObjective store.
+ */
+public class VlanNextObjectiveStoreKey {
+    private final DeviceId deviceId;
+    private final VlanId vlanId;
+
+    /**
+     * Constructs the key of VLAN next objective store.
+     *
+     * @param deviceId device ID
+     * @param vlanId VLAN information
+     */
+    public VlanNextObjectiveStoreKey(DeviceId deviceId,
+                                     VlanId vlanId) {
+        this.deviceId = deviceId;
+        this.vlanId = vlanId;
+    }
+
+    /**
+     * Gets device id in this VlanNextObjectiveStoreKey.
+     *
+     * @return device id
+     */
+    public DeviceId deviceId() {
+        return this.deviceId;
+    }
+
+    /**
+     * Gets vlan information in this VlanNextObjectiveStoreKey.
+     *
+     * @return vlan id
+     */
+    public VlanId vlanId() {
+        return this.vlanId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof VlanNextObjectiveStoreKey)) {
+            return false;
+        }
+        VlanNextObjectiveStoreKey that =
+                (VlanNextObjectiveStoreKey) o;
+        return (Objects.equals(this.deviceId, that.deviceId) &&
+                Objects.equals(this.vlanId, that.vlanId));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(deviceId, vlanId);
+    }
+
+    @Override
+    public String toString() {
+        return "deviceId: " + deviceId + " vlanId: " + vlanId;
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/XConnectStoreKey.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/XConnectStoreKey.java
new file mode 100644
index 0000000..0e90a22
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/XConnectStoreKey.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.storekey;
+
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+/**
+ * Key of VLAN cross-connect next objective store.
+ */
+public class XConnectStoreKey {
+    private final DeviceId deviceId;
+    private final VlanId vlanId;
+
+    /**
+     * Constructs the key of cross-connect next objective store.
+     *
+     * @param deviceId device ID of the VLAN cross-connection
+     * @param vlanId VLAN ID of the VLAN cross-connection
+     */
+    public XConnectStoreKey(DeviceId deviceId, VlanId vlanId) {
+        this.deviceId = deviceId;
+        this.vlanId = vlanId;
+    }
+
+    /**
+     * Returns the device ID of this key.
+     *
+     * @return device ID
+     */
+    public DeviceId deviceId() {
+        return this.deviceId;
+    }
+
+    /**
+     * Returns the VLAN ID of this key.
+     *
+     * @return VLAN ID
+     */
+    public VlanId vlanId() {
+        return this.vlanId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof XConnectStoreKey)) {
+            return false;
+        }
+        XConnectStoreKey that =
+                (XConnectStoreKey) o;
+        return (Objects.equals(this.deviceId, that.deviceId) &&
+                Objects.equals(this.vlanId, that.vlanId));
+    }
+
+    // The list of neighbor ids and label are used for comparison.
+    @Override
+    public int hashCode() {
+         return Objects.hash(deviceId, vlanId);
+    }
+
+    @Override
+    public String toString() {
+        return "Device: " + deviceId + " VlanId: " + vlanId;
+    }
+}
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/package-info.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/package-info.java
new file mode 100644
index 0000000..44fc6a7
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/storekey/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Key data structure of various stores used by Segment Routing.
+ */
+package org.onosproject.segmentrouting.storekey;
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/segmentrouting/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..cfd7502
--- /dev/null
+++ b/apps/segmentrouting/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,95 @@
+<!--
+  ~ Copyright 2015-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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <!-- XXX revisit when we formally add policies
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.TunnelListCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.PolicyListCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.PolicyAddCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.PolicyRemoveCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.TunnelAddCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.TunnelRemoveCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.RerouteNetworkCommand"/>
+        </command>
+        -->
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.DeviceSubnetListCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.EcmpGraphCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.NextHopCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.VerifyGroupsCommand"/>
+            <completers>
+                <ref component-id="deviceIdCompleter"/>
+            </completers>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.PseudowireListCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.PseudowireRemoveCommand"/>
+            <completers>
+                <ref component-id="pseudowireIdCompleter"/>
+            </completers>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.PseudowireAddCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.LinkStateCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.McastNextListCommand"/>
+            <completers>
+                <ref component-id="mcastGroupCompleter"/>
+                <ref component-id="nullCompleter"/>
+            </completers>
+        </command>
+        <command>
+            <action class="org.onosproject.segmentrouting.cli.McastTreeListCommand"/>
+            <completers>
+                <ref component-id="mcastGroupCompleter"/>
+                <ref component-id="nullCompleter"/>
+            </completers>
+        </command>
+    </command-bundle>
+
+    <bean id="nullCompleter" class="org.apache.karaf.shell.console.completer.NullCompleter"/>
+    <bean id="deviceIdCompleter" class="org.onosproject.cli.net.DeviceIdCompleter"/>
+    <bean id="pseudowireIdCompleter" class="org.onosproject.segmentrouting.cli.PseudowireIdCompleter"/>
+    <bean id="mcastGroupCompleter" class="org.onosproject.cli.net.McastGroupCompleter"/>
+
+</blueprint>
+
+
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/AugmentedPortAuthTracker.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/AugmentedPortAuthTracker.java
new file mode 100644
index 0000000..cc214e3
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/AugmentedPortAuthTracker.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2017-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;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An augmented implementation of {@link PortAuthTracker}, so that we can
+ * instrument its behavior for unit test assertions.
+ */
+class AugmentedPortAuthTracker extends PortAuthTracker {
+
+    // instrument blocking flow activity, so we can see when we get hits
+    final List<ConnectPoint> installed = new ArrayList<>();
+    final List<ConnectPoint> cleared = new ArrayList<>();
+
+
+    void resetMetrics() {
+        installed.clear();
+        cleared.clear();
+    }
+
+    @Override
+    void installBlockingFlow(DeviceId d, PortNumber p) {
+        super.installBlockingFlow(d, p);
+        installed.add(new ConnectPoint(d, p));
+    }
+
+    @Override
+    void clearBlockingFlow(DeviceId d, PortNumber p) {
+        super.clearBlockingFlow(d, p);
+        cleared.add(new ConnectPoint(d, p));
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
new file mode 100644
index 0000000..e33a36d
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
@@ -0,0 +1,855 @@
+/*
+ * Copyright 2017-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;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.host.HostLocationProbingService;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+
+/**r
+ * Unit test for {@link HostHandler}.
+ */
+public class HostHandlerTest {
+    private HostHandler hostHandler;
+
+    // Mocked routing and bridging tables
+    private static final Map<MockBridgingTableKey, MockBridgingTableValue> BRIDGING_TABLE =
+            Maps.newConcurrentMap();
+    private static final Map<MockRoutingTableKey, MockRoutingTableValue> ROUTING_TABLE =
+            Maps.newConcurrentMap();
+    private static final Map<ConnectPoint, Set<IpPrefix>> SUBNET_TABLE = Maps.newConcurrentMap();
+    // Mocked Next Id
+    private static final Map<Integer, TrafficTreatment> NEXT_TABLE = Maps.newConcurrentMap();
+
+    // Host Mac, VLAN
+    private static final ProviderId PROVIDER_ID = ProviderId.NONE;
+    private static final MacAddress HOST_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final VlanId HOST_VLAN_UNTAGGED = VlanId.NONE;
+    private static final HostId HOST_ID_UNTAGGED = HostId.hostId(HOST_MAC, HOST_VLAN_UNTAGGED);
+    private static final VlanId HOST_VLAN_TAGGED = VlanId.vlanId((short) 20);
+    private static final HostId HOST_ID_TAGGED = HostId.hostId(HOST_MAC, HOST_VLAN_TAGGED);
+    // Host IP
+    private static final IpAddress HOST_IP11 = IpAddress.valueOf("10.0.1.1");
+    private static final IpAddress HOST_IP21 = IpAddress.valueOf("10.0.2.1");
+    private static final IpAddress HOST_IP12 = IpAddress.valueOf("10.0.1.2");
+    private static final IpAddress HOST_IP13 = IpAddress.valueOf("10.0.1.3");
+    private static final IpAddress HOST_IP14 = IpAddress.valueOf("10.0.1.4");
+    private static final IpAddress HOST_IP32 = IpAddress.valueOf("10.0.3.2");
+    // Device
+    private static final DeviceId DEV1 = DeviceId.deviceId("of:0000000000000001");
+    private static final DeviceId DEV2 = DeviceId.deviceId("of:0000000000000002");
+    private static final DeviceId DEV3 = DeviceId.deviceId("of:0000000000000003");
+    private static final DeviceId DEV4 = DeviceId.deviceId("of:0000000000000004");
+    private static final DeviceId DEV5 = DeviceId.deviceId("of:0000000000000005");
+    private static final DeviceId DEV6 = DeviceId.deviceId("of:0000000000000006");
+    // Port
+    private static final PortNumber P1 = PortNumber.portNumber(1);
+    private static final PortNumber P2 = PortNumber.portNumber(2);
+    private static final PortNumber P3 = PortNumber.portNumber(3);
+    private static final PortNumber P9 = PortNumber.portNumber(9);
+    // Connect Point
+    private static final ConnectPoint CP11 = new ConnectPoint(DEV1, P1);
+    private static final HostLocation HOST_LOC11 = new HostLocation(CP11, 0);
+    private static final ConnectPoint CP12 = new ConnectPoint(DEV1, P2);
+    private static final HostLocation HOST_LOC12 = new HostLocation(CP12, 0);
+    private static final ConnectPoint CP13 = new ConnectPoint(DEV1, P3);
+    private static final HostLocation HOST_LOC13 = new HostLocation(CP13, 0);
+    private static final ConnectPoint CP21 = new ConnectPoint(DEV2, P1);
+    private static final HostLocation HOST_LOC21 = new HostLocation(CP21, 0);
+    private static final ConnectPoint CP22 = new ConnectPoint(DEV2, P2);
+    private static final HostLocation HOST_LOC22 = new HostLocation(CP22, 0);
+    // Connect Point for dual-homed host failover
+    private static final ConnectPoint CP31 = new ConnectPoint(DEV3, P1);
+    private static final HostLocation HOST_LOC31 = new HostLocation(CP31, 0);
+    private static final ConnectPoint CP32 = new ConnectPoint(DEV3, P2);
+    private static final HostLocation HOST_LOC32 = new HostLocation(CP32, 0);
+    private static final ConnectPoint CP41 = new ConnectPoint(DEV4, P1);
+    private static final HostLocation HOST_LOC41 = new HostLocation(CP41, 0);
+    private static final ConnectPoint CP39 = new ConnectPoint(DEV3, P9);
+    private static final ConnectPoint CP49 = new ConnectPoint(DEV4, P9);
+    // Conenct Point for mastership test
+    private static final ConnectPoint CP51 = new ConnectPoint(DEV5, P1);
+    private static final HostLocation HOST_LOC51 = new HostLocation(CP51, 0);
+    private static final ConnectPoint CP61 = new ConnectPoint(DEV6, P1);
+    private static final HostLocation HOST_LOC61 = new HostLocation(CP61, 0);
+    // Interface VLAN
+    private static final VlanId INTF_VLAN_UNTAGGED = VlanId.vlanId((short) 10);
+    private static final Set<VlanId> INTF_VLAN_TAGGED = Sets.newHashSet(VlanId.vlanId((short) 20));
+    private static final VlanId INTF_VLAN_NATIVE = VlanId.vlanId((short) 30);
+    private static final Set<VlanId> INTF_VLAN_PAIR = Sets.newHashSet(VlanId.vlanId((short) 10),
+            VlanId.vlanId((short) 20), VlanId.vlanId((short) 30));
+    private static final VlanId INTF_VLAN_OTHER = VlanId.vlanId((short) 40);
+    // Interface subnet
+    private static final IpPrefix INTF_PREFIX1 = IpPrefix.valueOf("10.0.1.254/24");
+    private static final IpPrefix INTF_PREFIX2 = IpPrefix.valueOf("10.0.2.254/24");
+    private static final IpPrefix INTF_PREFIX3 = IpPrefix.valueOf("10.0.3.254/24");
+    private static final InterfaceIpAddress INTF_IP1 =
+            new InterfaceIpAddress(INTF_PREFIX1.address(), INTF_PREFIX1);
+    private static final InterfaceIpAddress INTF_IP2 =
+            new InterfaceIpAddress(INTF_PREFIX2.address(), INTF_PREFIX2);
+    private static final InterfaceIpAddress INTF_IP3 =
+            new InterfaceIpAddress(INTF_PREFIX3.address(), INTF_PREFIX3);
+    // Interfaces
+    private static final Interface INTF11 =
+            new Interface(null, CP11, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF12 =
+            new Interface(null, CP12, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF13 =
+            new Interface(null, CP13, Lists.newArrayList(INTF_IP2), MacAddress.NONE, null,
+                    null, INTF_VLAN_TAGGED, INTF_VLAN_NATIVE);
+    private static final Interface INTF21 =
+            new Interface(null, CP21, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF22 =
+            new Interface(null, CP22, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF31 =
+            new Interface(null, CP31, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF32 =
+            new Interface(null, CP32, Lists.newArrayList(INTF_IP3), MacAddress.NONE, null,
+                    INTF_VLAN_OTHER, null, null);
+    private static final Interface INTF39 =
+            new Interface(null, CP39, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    null, INTF_VLAN_PAIR, null);
+    private static final Interface INTF41 =
+            new Interface(null, CP41, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF49 =
+            new Interface(null, CP49, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    null, INTF_VLAN_PAIR, null);
+    // Host
+    private static final Host HOST1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC,
+            HOST_VLAN_UNTAGGED, Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11),
+            false);
+
+    // A set of hosts
+    private static final Set<Host> HOSTS = Sets.newHashSet(HOST1);
+    // A set of devices of which we have mastership
+    private static final Set<DeviceId> LOCAL_DEVICES = Sets.newHashSet(DEV1, DEV2, DEV3, DEV4);
+    // A set of interfaces
+    private static final Set<Interface> INTERFACES = Sets.newHashSet(INTF11, INTF12, INTF13, INTF21,
+            INTF22, INTF31, INTF32, INTF39, INTF41, INTF49);
+
+    private MockLocationProbingService mockLocationProbingService;
+
+    @Before
+    public void setUp() throws Exception {
+        // Initialize pairDevice and pairLocalPort config
+        ObjectMapper mapper = new ObjectMapper();
+        ConfigApplyDelegate delegate = config -> { };
+
+        SegmentRoutingDeviceConfig dev3Config = new SegmentRoutingDeviceConfig();
+        JsonNode dev3Tree = mapper.createObjectNode();
+        dev3Config.init(DEV3, "host-handler-test", dev3Tree, mapper, delegate);
+        dev3Config.setPairDeviceId(DEV4).setPairLocalPort(P9);
+
+        SegmentRoutingDeviceConfig dev4Config = new SegmentRoutingDeviceConfig();
+        JsonNode dev4Tree = mapper.createObjectNode();
+        dev4Config.init(DEV4, "host-handler-test", dev4Tree, mapper, delegate);
+        dev4Config.setPairDeviceId(DEV3).setPairLocalPort(P9);
+
+        MockNetworkConfigRegistry mockNetworkConfigRegistry = new MockNetworkConfigRegistry();
+        mockNetworkConfigRegistry.applyConfig(dev3Config);
+        mockNetworkConfigRegistry.applyConfig(dev4Config);
+
+        // Initialize Segment Routing Manager
+        SegmentRoutingManager srManager = new MockSegmentRoutingManager(NEXT_TABLE);
+        srManager.cfgService = new NetworkConfigRegistryAdapter();
+        srManager.deviceConfiguration = new DeviceConfiguration(srManager);
+        srManager.flowObjectiveService = new MockFlowObjectiveService(BRIDGING_TABLE, NEXT_TABLE);
+        srManager.routingRulePopulator = new MockRoutingRulePopulator(srManager, ROUTING_TABLE);
+        srManager.defaultRoutingHandler = new MockDefaultRoutingHandler(srManager, SUBNET_TABLE);
+        srManager.interfaceService = new MockInterfaceService(INTERFACES);
+        srManager.mastershipService = new MockMastershipService(LOCAL_DEVICES);
+        srManager.hostService = new MockHostService(HOSTS);
+        srManager.cfgService = mockNetworkConfigRegistry;
+        mockLocationProbingService = new MockLocationProbingService();
+        srManager.probingService = mockLocationProbingService;
+        srManager.linkHandler = new MockLinkHandler(srManager);
+
+        hostHandler = new HostHandler(srManager);
+
+        ROUTING_TABLE.clear();
+        BRIDGING_TABLE.clear();
+    }
+
+    @Test
+    public void init() throws Exception {
+        hostHandler.init(DEV1);
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        hostHandler.init(DEV2);
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testHostAddedAtWrongLocation() throws Exception {
+        hostHandler.processHostAddedAtLocation(HOST1, HOST_LOC13);
+    }
+
+
+    @Test()
+    public void testHostAddedAtCorrectLocation() throws Exception {
+        hostHandler.processHostAddedAtLocation(HOST1, HOST_LOC11);
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test
+    public void testHostAdded() throws Exception {
+        Host subject;
+
+        // Untagged host discovered on untagged port
+        // Expect: add one routing rule and one bridging rule
+        subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Untagged host discovered on tagged/native port
+        // Expect: add one routing rule and one bridging rule
+        subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC13), Sets.newHashSet(HOST_IP21), false);
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_NATIVE)));
+
+        // Tagged host discovered on untagged port
+        // Expect: ignore the host. No rule is added.
+        subject = new DefaultHost(PROVIDER_ID, HOST_ID_TAGGED, HOST_MAC, HOST_VLAN_TAGGED,
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(2, BRIDGING_TABLE.size());
+
+        // Tagged host discovered on tagged port with the same IP
+        // Expect: update existing route, add one bridging rule
+        subject = new DefaultHost(PROVIDER_ID, HOST_ID_TAGGED, HOST_MAC, HOST_VLAN_TAGGED,
+                Sets.newHashSet(HOST_LOC13), Sets.newHashSet(HOST_IP21), false);
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertEquals(HOST_VLAN_TAGGED, ROUTING_TABLE.get(new MockRoutingTableKey(HOST_LOC13.deviceId(),
+                HOST_IP21.toIpPrefix())).vlanId);
+        assertEquals(3, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, HOST_VLAN_TAGGED)));
+    }
+
+    @Test
+    public void testDualHomedHostAdded() throws Exception {
+        // Add a dual-homed host that has 2 locations
+        // Expect: add two routing rules and two bridging rules
+        Host subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11), false);
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test
+    public void testSingleHomedHostAddedOnPairLeaf() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC32), Sets.newHashSet(HOST_IP32), false);
+
+        // Add a single-homed host with one location
+        // Expect: the pair link should not be utilized
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP32.toIpPrefix())).portNumber);
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertEquals(P2, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_OTHER)).portNumber);
+    }
+
+    @Test
+    public void testDualHomedHostAddedOneByOne() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31), Sets.newHashSet(HOST_IP11), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31, HOST_LOC41), Sets.newHashSet(HOST_IP11), false);
+
+        // Add a dual-homed host with one location
+        // Expect: the pair link is utilized temporarily before the second location is discovered
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        // Expect probe to be sent out on pair device
+        assertTrue(mockLocationProbingService.verifyProbe(host1, CP41, HostLocationProbingService.ProbeMode.DISCOVER));
+
+        // Add the second location of dual-homed host
+        // Expect: no longer use the pair link
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        // FIXME: Delay event handling a little bit to wait for the previous redirection flows to be completed
+        //        The permanent solution would be introducing CompletableFuture and wait for it
+        Thread.sleep(HostHandler.HOST_MOVED_DELAY_MS + 50);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+    }
+
+    @Test
+    public void testHostRemoved() throws Exception {
+        Host subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
+
+        // Add a host
+        // Expect: add one routing rule and one bridging rule
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Remove the host
+        // Expect: add the routing rule and the bridging rule
+        hostHandler.processHostRemovedEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, subject));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, BRIDGING_TABLE.size());
+    }
+
+    @Test
+    public void testDualHomedHostRemoved() throws Exception {
+        // Add a dual-homed host that has 2 locations
+        // Expect: add two routing rules and two bridging rules
+        Host subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11), false);
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Remove a dual-homed host that has 2 locations
+        // Expect: all routing and bridging rules are removed
+        hostHandler.processHostRemovedEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, subject));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, BRIDGING_TABLE.size());
+    }
+
+    @Test
+    public void testHostMoved() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC21), Sets.newHashSet(HOST_IP11), false);
+        Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC13), Sets.newHashSet(HOST_IP11), false);
+
+        // Add a host
+        // Expect: add one new routing rule, one new bridging rule
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP13.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Move the host to CP13, which has different subnet setting
+        // Expect: remove routing rule. Change vlan in bridging rule.
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host1));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_NATIVE)));
+        assertNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Move the host to CP21, which has same subnet setting
+        // Expect: add a new routing rule. Change vlan in bridging rule.
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host3));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test
+    public void testDualHomedHostMoved() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC12, HOST_LOC22), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+        Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP13, HOST_IP14), false);
+        Host host4 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC22), Sets.newHashSet(HOST_IP12, HOST_IP13), false);
+
+        // Add a host with IP11, IP12 and LOC11, LOC21
+        // Expect: 4 routing rules and 2 bridging rules
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Move the host to LOC12, LOC22 and keep the IP
+        // Expect: 4 routing rules and 2 bridging rules all at the new location
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P2, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P2, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Move the host to LOC11, LOC21 and change the IP to IP13, IP14 at the same time
+        // Expect: 4 routing rules and 2 bridging rules all at the new location
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host2));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP14.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP14.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Move the host to LOC11, LOC22 and change the IP to IP12, IP13 at the same time
+        // Expect: 4 routing rules and 2 bridging rules all at the new location
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host4, host3));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P2, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+    }
+
+    @Test
+    public void testHostMoveToInvalidLocation() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC51), Sets.newHashSet(HOST_IP11), false);
+
+        // Add a host
+        // Expect: add one new routing rule, one new bridging rule
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Move the host to an invalid location
+        // Expect: Old flow is removed. New flow is not created
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, BRIDGING_TABLE.size());
+
+        // Move the host to a valid location
+        // Expect: add one new routing rule, one new bridging rule
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host1, host2));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test
+    public void testDualHomedHostMoveToInvalidLocation() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC51), Sets.newHashSet(HOST_IP11), false);
+        Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC61, HOST_LOC51), Sets.newHashSet(HOST_IP11), false);
+
+        // Add a host
+        // Expect: add two new routing rules, two new bridging rules
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Move first host location to an invalid location
+        // Expect: One routing and one bridging flow
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Move second host location to an invalid location
+        // Expect: No routing or bridging rule
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host2));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, BRIDGING_TABLE.size());
+
+        // Move second host location back to a valid location
+        // Expect: One routing and one bridging flow
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host3));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Move first host location back to a valid location
+        // Expect: Two routing and two bridging flow
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host1, host2));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+    }
+
+    @Test
+    public void testDualHomingSingleLocationFail() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31, HOST_LOC41), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+
+        // Add a host
+        // Expect: add four new routing rules, two new bridging rules
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Host becomes single-homed
+        // Expect: redirect flows from host location to pair link
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Host becomes dual-homed again
+        // Expect: Redirect flows from pair link back to host location
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host1, host2));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        // FIXME: Delay event handling a little bit to wait for the previous redirection flows to be completed
+        //        The permanent solution would be introducing CompletableFuture and wait for it
+        Thread.sleep(HostHandler.HOST_MOVED_DELAY_MS + 50);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+    }
+
+    @Test
+    public void testDualHomingBothLocationFail() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31, HOST_LOC41), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+
+        // Add a host
+        // Expect: add four new routing rules, two new bridging rules
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Host becomes single-homed
+        // Expect: redirect flows from host location to pair link
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Host loses both locations
+        // Expect: Remove last location and all previous redirection flows
+        hostHandler.processHostRemovedEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, host2));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, BRIDGING_TABLE.size());
+    }
+
+    @Test
+    public void testHostUpdated() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP21), false);
+        Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP12), false);
+
+        // Add a host
+        // Expect: add one new routing rule. Add one new bridging rule.
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(HOST_LOC11.deviceId(), HOST_MAC,
+                INTF_VLAN_UNTAGGED)));
+
+        // Update the host IP to same subnet
+        // Expect: update routing rule with new IP. No change to bridging rule.
+        hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host3, host1));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Update the host IP to different subnet
+        // Expect: Remove routing rule. No change to bridging rule.
+        hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host2, host3));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test
+    public void testDelayedIpAndLocation() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31), Sets.newHashSet(), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31), Sets.newHashSet(HOST_IP11), false);
+        Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31, HOST_LOC41), Sets.newHashSet(HOST_IP11), false);
+
+        // Add a dual-home host with only one location and no IP
+        // Expect: only bridging redirection works
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Discover IP
+        // Expect: routing redirection should also work
+        hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host2, host1));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        // Expect probe to be sent out on pair device
+        assertTrue(mockLocationProbingService.verifyProbe(host2, CP41, HostLocationProbingService.ProbeMode.DISCOVER));
+
+        // Discover location
+        // Expect: cancel all redirections
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host2));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        // FIXME: Delay event handling a little bit to wait for the previous redirection flows to be completed
+        //        The permanent solution would be introducing CompletableFuture and wait for it
+        Thread.sleep(HostHandler.HOST_MOVED_DELAY_MS + 50);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+    }
+
+    @Test
+    public void testDelayedIpAndLocation2() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31), Sets.newHashSet(), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31, HOST_LOC41), Sets.newHashSet(), false);
+        Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC31, HOST_LOC41), Sets.newHashSet(HOST_IP11), false);
+
+        // Add a dual-home host with only one location and no IP
+        // Expect: only bridging redirection works
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Discover Location
+        // Expect: cancel bridging redirections
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Discover IP
+        // Expect: add IP rules to both location
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host3, host2));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+    }
+
+    @Test
+    public void testDualHomedHostUpdated() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11, HOST_IP21), false);
+        Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP13, HOST_IP14), false);
+
+        // Add a dual-homed host with two locations and two IPs
+        // Expect: add four new routing rules. Add two new bridging rules
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Update both host IPs
+        // Expect: update routing rules with new IP. No change to bridging rule.
+        hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host3, host1));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP13.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP14.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP13.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP14.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Update one of the host IP to different subnet
+        // Expect: update routing rule with new IP. No change to bridging rule.
+        hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host2, host3));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP21.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test
+    public void testBridgingFwdObjBuilder() throws Exception {
+        assertNotNull(hostHandler.bridgingFwdObjBuilder(DEV2, HOST_MAC, HOST_VLAN_UNTAGGED, P1, false));
+        assertNull(hostHandler.bridgingFwdObjBuilder(DEV2, HOST_MAC, HOST_VLAN_UNTAGGED, P3, false));
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockBridgingTableKey.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockBridgingTableKey.java
new file mode 100644
index 0000000..a90b1cf
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockBridgingTableKey.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017-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;
+
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+/**
+ * Mock Bridging Table Key.
+ */
+class MockBridgingTableKey {
+    DeviceId deviceId;
+    MacAddress macAddress;
+    VlanId vlanId;
+
+    MockBridgingTableKey(DeviceId deviceId, MacAddress macAddress, VlanId vlanId) {
+        this.deviceId = deviceId;
+        this.macAddress = macAddress;
+        this.vlanId = vlanId;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof MockBridgingTableKey)) {
+            return false;
+        }
+        final MockBridgingTableKey other = (MockBridgingTableKey) obj;
+        return Objects.equals(this.macAddress, other.macAddress) &&
+                Objects.equals(this.deviceId, other.deviceId) &&
+                Objects.equals(this.vlanId, other.vlanId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(macAddress, vlanId);
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockBridgingTableValue.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockBridgingTableValue.java
new file mode 100644
index 0000000..68b0db8
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockBridgingTableValue.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017-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;
+
+import org.onosproject.net.PortNumber;
+
+import java.util.Objects;
+
+/**
+ * Mock Bridging Table Value.
+ */
+class MockBridgingTableValue {
+    boolean popVlan;
+    PortNumber portNumber;
+
+    MockBridgingTableValue(boolean popVlan, PortNumber portNumber) {
+        this.popVlan = popVlan;
+        this.portNumber = portNumber;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof MockBridgingTableValue)) {
+            return false;
+        }
+        final MockBridgingTableValue other = (MockBridgingTableValue) obj;
+        return Objects.equals(this.popVlan, other.popVlan) &&
+                Objects.equals(this.portNumber, other.portNumber);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(popVlan, portNumber);
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockDefaultRoutingHandler.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockDefaultRoutingHandler.java
new file mode 100644
index 0000000..ec07238
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockDefaultRoutingHandler.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2017-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;
+
+import org.onlab.packet.IpPrefix;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Mock Default Routing Handler.
+ */
+public class MockDefaultRoutingHandler extends DefaultRoutingHandler {
+    private Map<ConnectPoint, Set<IpPrefix>> subnetTable;
+
+    MockDefaultRoutingHandler(SegmentRoutingManager srManager,
+                              Map<ConnectPoint, Set<IpPrefix>> subnetTable) {
+        super(srManager);
+        this.subnetTable = subnetTable;
+    }
+
+    @Override
+    protected void populateSubnet(Set<ConnectPoint> cpts, Set<IpPrefix> subnets) {
+        subnetTable.forEach((k, v) -> {
+            if (!cpts.contains(k)) {
+                subnetTable.get(k).removeAll(subnets);
+                if (subnetTable.get(k).isEmpty()) {
+                    subnetTable.remove(k);
+                }
+            }
+        });
+
+        cpts.forEach(cpt -> subnetTable.put(cpt, subnets));
+    }
+
+    @Override
+    protected boolean revokeSubnet(Set<IpPrefix> subnets) {
+        for (Map.Entry<ConnectPoint, Set<IpPrefix>> entry : subnetTable.entrySet()) {
+            entry.getValue().removeAll(subnets);
+            if (entry.getValue().isEmpty()) {
+                subnetTable.remove(entry.getKey());
+            }
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockDevice.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockDevice.java
new file mode 100644
index 0000000..0abbf2a
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockDevice.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.segmentrouting;
+
+import org.onosproject.net.Annotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DeviceId;
+/**
+ * Test fixture for the device service.
+ */
+public class MockDevice extends DefaultDevice {
+
+        public MockDevice(DeviceId id, Annotations annotations) {
+            super(null, id, null, null, null, null, null, null, annotations);
+        }
+ }
+
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockDeviceService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockDeviceService.java
new file mode 100644
index 0000000..1d173f6
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockDeviceService.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.segmentrouting;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+
+/**
+ * Test fixture for the device service.
+ */
+public class MockDeviceService extends DeviceServiceAdapter {
+    private List<Device> devices = new LinkedList<>();
+    private DeviceListener listener;
+
+    public void addDevice(Device dev) {
+        devices.add(dev);
+    }
+
+    public void addMultipleDevices(Set<Device> devicesToAdd) {
+        devicesToAdd.forEach(dev -> devices.add(dev));
+    }
+
+    @Override
+    public Device getDevice(DeviceId deviceId) {
+        for (Device dev : devices) {
+            if (dev.id().equals(deviceId)) {
+                return dev;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Port getPort(ConnectPoint cp) {
+        return new DefaultPort(null, null, false);
+    }
+
+    @Override
+    public Iterable<Device> getAvailableDevices() {
+        return devices;
+    }
+
+    @Override
+    public void addListener(DeviceListener listener) {
+        this.listener = listener;
+    }
+
+    /**
+     * Get the listener.
+     */
+    public DeviceListener getListener() {
+        return listener;
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockFlowObjectiveService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockFlowObjectiveService.java
new file mode 100644
index 0000000..138b98a
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockFlowObjectiveService.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2017-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;
+
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+
+import java.util.Map;
+
+/**
+ * Mock Flow Objective Service.
+ */
+public class MockFlowObjectiveService extends FlowObjectiveServiceAdapter {
+    private Map<MockBridgingTableKey, MockBridgingTableValue> bridgingTable;
+    private Map<Integer, TrafficTreatment> nextTable;
+
+    MockFlowObjectiveService(Map<MockBridgingTableKey, MockBridgingTableValue> bridgingTable,
+                             Map<Integer, TrafficTreatment> nextTable) {
+        this.bridgingTable = bridgingTable;
+        this.nextTable = nextTable;
+    }
+
+    @Override
+    public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
+        TrafficSelector selector = forwardingObjective.selector();
+        TrafficTreatment treatment = nextTable.get(forwardingObjective.nextId());
+        MacAddress macAddress = ((EthCriterion) selector.getCriterion(Criterion.Type.ETH_DST)).mac();
+        VlanId vlanId = ((VlanIdCriterion) selector.getCriterion(Criterion.Type.VLAN_VID)).vlanId();
+
+        boolean popVlan = treatment.allInstructions().stream()
+                .filter(instruction -> instruction.type().equals(Instruction.Type.L2MODIFICATION))
+                .anyMatch(instruction -> ((L2ModificationInstruction) instruction).subtype()
+                        .equals(L2ModificationInstruction.L2SubType.VLAN_POP));
+        PortNumber portNumber = treatment.allInstructions().stream()
+                .filter(instruction -> instruction.type().equals(Instruction.Type.OUTPUT))
+                .map(instruction -> ((Instructions.OutputInstruction) instruction).port()).findFirst().orElse(null);
+        if (portNumber == null) {
+            throw new IllegalArgumentException();
+        }
+
+        Objective.Operation op = forwardingObjective.op();
+
+        MockBridgingTableKey btKey = new MockBridgingTableKey(deviceId, macAddress, vlanId);
+        MockBridgingTableValue btValue = new MockBridgingTableValue(popVlan, portNumber);
+
+        if (op.equals(Objective.Operation.ADD)) {
+            bridgingTable.put(btKey, btValue);
+        } else if (op.equals(Objective.Operation.REMOVE)) {
+            bridgingTable.remove(btKey, btValue);
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockHostService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockHostService.java
new file mode 100644
index 0000000..e8c4701
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockHostService.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017-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;
+
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.host.HostServiceAdapter;
+
+import java.util.Set;
+
+/**
+ * Mock Host Service.
+ */
+public class MockHostService extends HostServiceAdapter {
+    private Set<Host> hosts;
+
+    MockHostService(Set<Host> hosts) {
+        this.hosts = ImmutableSet.copyOf(hosts);
+    }
+
+    @Override
+    public Set<Host> getHosts() {
+        return hosts;
+    }
+
+    @Override
+    public Host getHost(HostId hostId) {
+        return hosts.stream().filter(host -> hostId.equals(host.id())).findFirst().orElse(null);
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockInterfaceService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockInterfaceService.java
new file mode 100644
index 0000000..f8d04ca
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockInterfaceService.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017-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;
+
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceServiceAdapter;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Mock Interface Service.
+ */
+public class MockInterfaceService extends InterfaceServiceAdapter {
+    private Set<Interface> interfaces;
+
+    MockInterfaceService(Set<Interface> interfaces) {
+        this.interfaces = ImmutableSet.copyOf(interfaces);
+    }
+
+    @Override
+    public Set<Interface> getInterfacesByPort(ConnectPoint cp) {
+        return interfaces.stream().filter(intf -> cp.equals(intf.connectPoint()))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Set<Interface> getInterfaces() {
+        return interfaces;
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockLinkHandler.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockLinkHandler.java
new file mode 100644
index 0000000..2819c9d
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockLinkHandler.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017-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;
+
+import org.onosproject.net.HostLocation;
+
+/**
+ * Mocks the LinkHandler in SR.
+ *
+ */
+public class MockLinkHandler extends LinkHandler {
+
+    MockLinkHandler(SegmentRoutingManager srManager) {
+        super(srManager, null);
+    }
+
+    @Override
+    void checkUplinksForDualHomedHosts(HostLocation loc) {
+        // currently does nothing - can be extended to be a useful mock when
+        // implementing unit tests for link handling
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockLocationProbingService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockLocationProbingService.java
new file mode 100644
index 0000000..b0cdf43
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockLocationProbingService.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017-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;
+
+import com.google.common.collect.Lists;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostLocationProbingService;
+
+import java.util.List;
+import java.util.Objects;
+
+public class MockLocationProbingService implements HostLocationProbingService {
+    List<Probe> probes;
+
+    private class Probe {
+        private Host host;
+        private ConnectPoint connectPoint;
+        private ProbeMode probeMode;
+
+        Probe(Host host, ConnectPoint connectPoint, ProbeMode probeMode) {
+            this.host = host;
+            this.connectPoint = connectPoint;
+            this.probeMode = probeMode;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof Probe)) {
+                return false;
+            }
+            Probe that = (Probe) o;
+            return (Objects.equals(this.host, that.host) &&
+                    Objects.equals(this.connectPoint, that.connectPoint) &&
+                    Objects.equals(this.probeMode, that.probeMode));
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(host, connectPoint, probeMode);
+        }
+    }
+
+    MockLocationProbingService() {
+        probes = Lists.newArrayList();
+    }
+
+    boolean verifyProbe(Host host, ConnectPoint connectPoint, ProbeMode probeMode) {
+        Probe probe = new Probe(host, connectPoint, probeMode);
+        return probes.contains(probe);
+    }
+
+    @Override
+    public void probeHostLocation(Host host, ConnectPoint connectPoint, ProbeMode probeMode) {
+        probes.add(new Probe(host, connectPoint, probeMode));
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockMastershipService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockMastershipService.java
new file mode 100644
index 0000000..5494e27
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockMastershipService.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017-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;
+
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.DeviceId;
+
+import java.util.Set;
+
+/**
+ * Mock Mastership Service.
+ */
+public class MockMastershipService extends MastershipServiceAdapter {
+    // A set of devices of which we have mastership.
+    private Set<DeviceId> localDevices;
+
+    MockMastershipService(Set<DeviceId> localDevices) {
+        this.localDevices = ImmutableSet.copyOf(localDevices);
+    }
+
+    @Override
+    public boolean isLocalMaster(DeviceId deviceId) {
+        return localDevices.contains(deviceId);
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockNetworkConfigRegistry.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockNetworkConfigRegistry.java
new file mode 100644
index 0000000..09f8da2
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockNetworkConfigRegistry.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-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;
+
+import com.google.common.collect.Sets;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+
+import java.util.Set;
+
+/**
+ * Mock Network Config Registry.
+ */
+class MockNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
+    private Set<Config> configs = Sets.newHashSet();
+
+    public void applyConfig(Config config) {
+        configs.add(config);
+    }
+
+    @Override
+    public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+        Config c = configs.stream()
+                .filter(config -> subject.equals(config.subject()))
+                .filter(config -> configClass.equals(config.getClass()))
+                .findFirst().orElse(null);
+        return (C) c;
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRouteService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRouteService.java
new file mode 100644
index 0000000..7927636
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRouteService.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017-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;
+
+import com.google.common.collect.Sets;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.routeservice.ResolvedRoute;
+import org.onosproject.routeservice.Route;
+import org.onosproject.routeservice.RouteInfo;
+import org.onosproject.routeservice.RouteServiceAdapter;
+import org.onosproject.routeservice.RouteTableId;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Mock Route Service.
+ * We assume there is only one routing table named "default".
+ */
+public class MockRouteService extends RouteServiceAdapter {
+    private Map<MockRoutingTableKey, MockRoutingTableValue> routingTable;
+
+    MockRouteService(Map<MockRoutingTableKey, MockRoutingTableValue> routingTable) {
+        this.routingTable = routingTable;
+    }
+
+    @Override
+    public Collection<RouteInfo> getRoutes(RouteTableId id) {
+        return routingTable.entrySet().stream().map(e -> {
+            IpPrefix prefix = e.getKey().ipPrefix;
+            IpAddress nextHop = IpAddress.valueOf(0); // dummy
+            MacAddress mac = e.getValue().macAddress;
+            VlanId vlan = e.getValue().vlanId;
+            Route route = new Route(Route.Source.STATIC, prefix, nextHop);
+            ResolvedRoute rr = new ResolvedRoute(route, mac, vlan);
+
+            return new RouteInfo(prefix, rr, Sets.newHashSet(rr));
+        }).collect(Collectors.toSet());
+    }
+
+    @Override
+    public Collection<RouteTableId> getRouteTables() {
+        return Sets.newHashSet(new RouteTableId("default"));
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRoutingRulePopulator.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRoutingRulePopulator.java
new file mode 100644
index 0000000..4eab7c0
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRoutingRulePopulator.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017-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;
+
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+import java.util.Map;
+
+/**
+ * Mock Routing Rule Populator.
+ */
+public class MockRoutingRulePopulator extends RoutingRulePopulator {
+    private Map<MockRoutingTableKey, MockRoutingTableValue> routingTable;
+
+    MockRoutingRulePopulator(SegmentRoutingManager srManager,
+                             Map<MockRoutingTableKey, MockRoutingTableValue> routingTable) {
+        super(srManager);
+        this.routingTable = routingTable;
+    }
+
+    @Override
+    public void populateRoute(DeviceId deviceId, IpPrefix prefix,
+                              MacAddress hostMac, VlanId hostVlanId, PortNumber outPort) {
+        MockRoutingTableKey rtKey = new MockRoutingTableKey(deviceId, prefix);
+        MockRoutingTableValue rtValue = new MockRoutingTableValue(outPort, hostMac, hostVlanId);
+        routingTable.put(rtKey, rtValue);
+    }
+
+    @Override
+    public void revokeRoute(DeviceId deviceId, IpPrefix prefix,
+                            MacAddress hostMac, VlanId hostVlanId, PortNumber outPort) {
+        MockRoutingTableKey rtKey = new MockRoutingTableKey(deviceId, prefix);
+        MockRoutingTableValue rtValue = new MockRoutingTableValue(outPort, hostMac, hostVlanId);
+        routingTable.remove(rtKey, rtValue);
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRoutingTableKey.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRoutingTableKey.java
new file mode 100644
index 0000000..4f09c2a
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRoutingTableKey.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2017-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;
+
+import org.onlab.packet.IpPrefix;
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+/**
+ * Mock Routing Table Key.
+ */
+class MockRoutingTableKey {
+    DeviceId deviceId;
+    IpPrefix ipPrefix;
+
+    MockRoutingTableKey(DeviceId deviceId, IpPrefix ipPrefix) {
+        this.deviceId = deviceId;
+        this.ipPrefix = ipPrefix;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof MockRoutingTableKey)) {
+            return false;
+        }
+        final MockRoutingTableKey other = (MockRoutingTableKey) obj;
+        return Objects.equals(this.deviceId, other.deviceId) &&
+                Objects.equals(this.ipPrefix, other.ipPrefix);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(deviceId, ipPrefix);
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRoutingTableValue.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRoutingTableValue.java
new file mode 100644
index 0000000..5842d2d
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRoutingTableValue.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017-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;
+
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.PortNumber;
+
+import java.util.Objects;
+
+/**
+ * Mock Routing Table Value.
+ */
+class MockRoutingTableValue {
+    PortNumber portNumber;
+    MacAddress macAddress;
+    VlanId vlanId;
+
+    MockRoutingTableValue(PortNumber portNumber, MacAddress macAddress, VlanId vlanId) {
+        this.portNumber = portNumber;
+        this.macAddress = macAddress;
+        this.vlanId = vlanId;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof MockRoutingTableValue)) {
+            return false;
+        }
+        final MockRoutingTableValue other = (MockRoutingTableValue) obj;
+        return Objects.equals(this.portNumber, other.portNumber) &&
+                Objects.equals(this.macAddress, other.macAddress) &&
+                Objects.equals(this.vlanId, other.vlanId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(portNumber, macAddress, vlanId);
+    }
+}
+
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockSegmentRoutingManager.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockSegmentRoutingManager.java
new file mode 100644
index 0000000..ad098b4
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockSegmentRoutingManager.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2017-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;
+
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Mock Segment Routing Manager.
+ */
+public class MockSegmentRoutingManager extends SegmentRoutingManager {
+    private Map<Integer, TrafficTreatment> nextTable;
+    private AtomicInteger atomicNextId = new AtomicInteger();
+
+    MockSegmentRoutingManager(Map<Integer, TrafficTreatment> nextTable) {
+        appId = new DefaultApplicationId(1, SegmentRoutingManager.APP_NAME);
+        this.nextTable = nextTable;
+    }
+
+    @Override
+    public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum,
+                                      TrafficTreatment treatment,
+                                      TrafficSelector meta,
+                                      boolean createIfMissing) {
+        int nextId = atomicNextId.incrementAndGet();
+        nextTable.put(nextId, treatment);
+        return nextId;
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/PortAuthTrackerTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/PortAuthTrackerTest.java
new file mode 100644
index 0000000..6ab4bad
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/PortAuthTrackerTest.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2017-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;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.segmentrouting.PortAuthTracker.BlockState;
+import org.onosproject.segmentrouting.config.BlockedPortsConfig;
+import org.onosproject.segmentrouting.config.BlockedPortsConfigTest;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.ConnectPoint.deviceConnectPoint;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.portNumber;
+import static org.onosproject.segmentrouting.PortAuthTracker.BlockState.AUTHENTICATED;
+import static org.onosproject.segmentrouting.PortAuthTracker.BlockState.BLOCKED;
+import static org.onosproject.segmentrouting.PortAuthTracker.BlockState.UNCHECKED;
+
+/**
+ * Unit Tests for {@link PortAuthTracker}.
+ */
+public class PortAuthTrackerTest {
+    private static final ApplicationId APP_ID = new DefaultApplicationId(1, "foo");
+    private static final String KEY = "blocked";
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+    private static final String PATH_CFG = "/blocked-ports.json";
+    private static final String PATH_CFG_ALT = "/blocked-ports-alt.json";
+
+    private static final String DEV1 = "of:0000000000000001";
+    private static final String DEV3 = "of:0000000000000003";
+    private static final String DEV4 = "of:0000000000000004";
+
+    private BlockedPortsConfig cfg;
+    private AugmentedPortAuthTracker tracker;
+
+    private void print(String s) {
+        System.out.println(s);
+    }
+
+    private void print(Object o) {
+        print(o.toString());
+    }
+
+    private void print(String fmt, Object... params) {
+        print(String.format(fmt, params));
+    }
+
+    private void title(String s) {
+        print("=== %s ===", s);
+    }
+
+    private BlockedPortsConfig makeConfig(String path) throws IOException {
+        InputStream blockedPortsJson = BlockedPortsConfigTest.class
+                .getResourceAsStream(path);
+        JsonNode node = MAPPER.readTree(blockedPortsJson);
+        BlockedPortsConfig cfg = new BlockedPortsConfig();
+        cfg.init(APP_ID, KEY, node, MAPPER, null);
+        return cfg;
+    }
+
+    ConnectPoint cp(String devId, int port) {
+        return ConnectPoint.deviceConnectPoint(devId + "/" + port);
+    }
+
+    @Before
+    public void setUp() throws IOException {
+        cfg = makeConfig(PATH_CFG);
+        tracker = new AugmentedPortAuthTracker();
+    }
+
+    private void verifyPortState(String devId, int first, BlockState... states) {
+        DeviceId dev = deviceId(devId);
+        int last = first + states.length;
+        int pn = first;
+        int i = 0;
+        while (pn < last) {
+            PortNumber pnum = portNumber(pn);
+            BlockState actual = tracker.currentState(dev, pnum);
+            print("%s/%s [%s]  --> %s", devId, pn, states[i], actual);
+            assertEquals("oops: " + devId + "/" + pn + "~" + actual,
+                         states[i], actual);
+            pn++;
+            i++;
+        }
+    }
+
+    @Test
+    public void basic() {
+        title("basic");
+        print(tracker);
+        print(cfg);
+
+        assertEquals("wrong entry count", 0, tracker.entryCount());
+
+        // let's assume that the net config just got loaded..
+        tracker.configurePortBlocking(cfg);
+        assertEquals("wrong entry count", 13, tracker.entryCount());
+
+        verifyPortState(DEV1, 1, BLOCKED, BLOCKED, BLOCKED, BLOCKED, UNCHECKED);
+        verifyPortState(DEV1, 6, UNCHECKED, BLOCKED, BLOCKED, BLOCKED, UNCHECKED);
+
+        verifyPortState(DEV3, 1, UNCHECKED, UNCHECKED, UNCHECKED);
+        verifyPortState(DEV3, 6, UNCHECKED, BLOCKED, BLOCKED, BLOCKED, UNCHECKED);
+
+        verifyPortState(DEV4, 1, BLOCKED, UNCHECKED, UNCHECKED, UNCHECKED, BLOCKED);
+    }
+
+    @Test
+    public void logonLogoff() {
+        title("logonLogoff");
+
+        tracker.configurePortBlocking(cfg);
+        assertEquals("wrong entry count", 13, tracker.entryCount());
+        verifyPortState(DEV1, 1, BLOCKED, BLOCKED, BLOCKED);
+
+        ConnectPoint cp = deviceConnectPoint(DEV1 + "/2");
+        tracker.radiusAuthorize(cp);
+        print("");
+        verifyPortState(DEV1, 1, BLOCKED, AUTHENTICATED, BLOCKED);
+
+        tracker.radiusLogoff(cp);
+        print("");
+        verifyPortState(DEV1, 1, BLOCKED, BLOCKED, BLOCKED);
+    }
+
+    @Test
+    public void installedFlows() {
+        title("installed flows");
+
+        assertEquals(0, tracker.installed.size());
+        tracker.configurePortBlocking(cfg);
+        assertEquals(13, tracker.installed.size());
+
+        assertTrue(tracker.installed.contains(cp(DEV1, 1)));
+        assertTrue(tracker.installed.contains(cp(DEV3, 7)));
+        assertTrue(tracker.installed.contains(cp(DEV4, 5)));
+    }
+
+    @Test
+    public void flowsLogonLogoff() {
+        title("flows logon logoff");
+
+        tracker.configurePortBlocking(cfg);
+
+        // let's pick a connect point from the configuration
+        ConnectPoint cp = cp(DEV4, 5);
+
+        assertTrue(tracker.installed.contains(cp));
+        assertEquals(0, tracker.cleared.size());
+
+        tracker.resetMetrics();
+        tracker.radiusAuthorize(cp);
+        // verify we requested the blocking flow to be cleared
+        assertTrue(tracker.cleared.contains(cp));
+
+        tracker.resetMetrics();
+        assertEquals(0, tracker.installed.size());
+        tracker.radiusLogoff(cp);
+        // verify we requested the blocking flow to be reinstated
+        assertTrue(tracker.installed.contains(cp));
+    }
+
+    @Test
+    public void uncheckedPortIgnored() {
+        title("unchecked port ignored");
+
+        tracker.configurePortBlocking(cfg);
+        tracker.resetMetrics();
+
+        // let's pick a connect point NOT in the configuration
+        ConnectPoint cp = cp(DEV4, 2);
+        assertEquals(BlockState.UNCHECKED, tracker.currentState(cp));
+
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+        tracker.radiusAuthorize(cp);
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+        tracker.radiusLogoff(cp);
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+    }
+
+    @Test
+    public void reconfiguration() throws IOException {
+        title("reconfiguration");
+
+        /* see 'blocked-ports.json' and 'blocked-ports-alt.json'
+
+          cfg:  "1": ["1-4", "7-9"],
+                "3": ["7-9"],
+                "4": ["1", "5", "9"]
+
+          alt:  "1": ["1-9"],
+                "3": ["7"],
+                "4": ["1"]
+         */
+        tracker.configurePortBlocking(cfg);
+        // dev1: ports 5 and 6 are NOT configured in the original CFG
+        assertFalse(tracker.installed.contains(cp(DEV1, 5)));
+        assertFalse(tracker.installed.contains(cp(DEV1, 6)));
+
+        tracker.resetMetrics();
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+
+        BlockedPortsConfig alt = makeConfig(PATH_CFG_ALT);
+        tracker.configurePortBlocking(alt);
+
+        // dev1: ports 5 and 6 ARE configured in the alternate CFG
+        assertTrue(tracker.installed.contains(cp(DEV1, 5)));
+        assertTrue(tracker.installed.contains(cp(DEV1, 6)));
+
+        // also, check for the ports that were decommissioned
+        assertTrue(tracker.cleared.contains(cp(DEV3, 8)));
+        assertTrue(tracker.cleared.contains(cp(DEV3, 9)));
+        assertTrue(tracker.cleared.contains(cp(DEV4, 5)));
+        assertTrue(tracker.cleared.contains(cp(DEV4, 9)));
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/PwaasConfigTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/PwaasConfigTest.java
new file mode 100644
index 0000000..23d1233
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/PwaasConfigTest.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.segmentrouting.config.PwaasConfig;
+
+import org.onosproject.segmentrouting.pwaas.L2Tunnel;
+import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
+import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.L2Mode;
+
+import java.io.InputStream;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.*;
+
+/**
+ * Unit tests for class {@link PwaasConfig}.
+ */
+public class PwaasConfigTest {
+
+    private static final String TUNNEL_ID_1 = "1";
+    private static final String TUNNEL_ID_2 = "20";
+    private static final String NOT_PRESENT_TUNNEL_ID = "2";
+    private static final ConnectPoint INGRESS_1 = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
+    private static final ConnectPoint INGRESS_2 = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
+    private static final ConnectPoint EGRESS_1 = ConnectPoint.deviceConnectPoint("of:0000000000000002/1");
+    private static final ConnectPoint EGRESS_2 = ConnectPoint.deviceConnectPoint("of:0000000000000002/1");
+    private static final VlanId INGRESS_INNER_TAG_1 = VlanId.vlanId("10");
+    private static final VlanId INGRESS_INNER_TAG_2 = VlanId.vlanId("100");
+    private static final VlanId INGRESS_OUTER_TAG_1 = VlanId.vlanId("20");
+    private static final VlanId INGRESS_OUTER_TAG_2 = VlanId.vlanId("200");
+    private static final VlanId EGRESS_INNER_TAG_1 = VlanId.vlanId("10");
+    private static final VlanId EGRESS_INNER_TAG_2 = VlanId.vlanId("100");
+    private static final VlanId EGRESS_OUTER_TAG_1 = VlanId.vlanId("21");
+    private static final VlanId EGRESS_OUTER_TAG_2 = VlanId.vlanId("210");
+    private static final String MODE_1 = "RAW";
+    private static final String MODE_2 = "RAW";
+    private static final VlanId SD_TAG_1 = VlanId.NONE;
+    private static final VlanId SD_TAG_2 = VlanId.NONE;
+    private static final MplsLabel PW_LABEL_1 = MplsLabel.mplsLabel("255");
+    private static final MplsLabel PW_LABEL_2 = MplsLabel.mplsLabel("1255");
+
+    /*
+     * Configuration below copied from host handler test.
+     */
+
+    // Host Mac, VLAN
+    private static final ProviderId PROVIDER_ID = ProviderId.NONE;
+    private static final MacAddress HOST_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final VlanId HOST_VLAN_UNTAGGED = VlanId.NONE;
+    private static final HostId HOST_ID_UNTAGGED = HostId.hostId(HOST_MAC, HOST_VLAN_UNTAGGED);
+    private static final VlanId HOST_VLAN_TAGGED = VlanId.vlanId((short) 20);
+    private static final HostId HOST_ID_TAGGED = HostId.hostId(HOST_MAC, HOST_VLAN_TAGGED);
+    // Host IP
+    private static final IpAddress HOST_IP11 = IpAddress.valueOf("10.0.1.1");
+    private static final IpAddress HOST_IP21 = IpAddress.valueOf("10.0.2.1");
+    private static final IpAddress HOST_IP12 = IpAddress.valueOf("10.0.1.2");
+    private static final IpAddress HOST_IP13 = IpAddress.valueOf("10.0.1.3");
+    private static final IpAddress HOST_IP14 = IpAddress.valueOf("10.0.1.4");
+    private static final IpAddress HOST_IP32 = IpAddress.valueOf("10.0.3.2");
+    // Device
+    private static final DeviceId DEV1 = DeviceId.deviceId("of:0000000000000001");
+    private static final DeviceId DEV2 = DeviceId.deviceId("of:0000000000000002");
+    private static final DeviceId DEV3 = DeviceId.deviceId("of:0000000000000003");
+    private static final DeviceId DEV4 = DeviceId.deviceId("of:0000000000000004");
+    private static final DeviceId DEV5 = DeviceId.deviceId("of:0000000000000005");
+    private static final DeviceId DEV6 = DeviceId.deviceId("of:0000000000000006");
+    // Port
+    private static final PortNumber P1 = PortNumber.portNumber(1);
+    private static final PortNumber P2 = PortNumber.portNumber(2);
+    private static final PortNumber P3 = PortNumber.portNumber(3);
+    private static final PortNumber P9 = PortNumber.portNumber(9);
+    // Connect Point
+    private static final ConnectPoint CP11 = new ConnectPoint(DEV1, P1);
+    private static final HostLocation HOST_LOC11 = new HostLocation(CP11, 0);
+    private static final ConnectPoint CP12 = new ConnectPoint(DEV1, P2);
+    private static final HostLocation HOST_LOC12 = new HostLocation(CP12, 0);
+    private static final ConnectPoint CP13 = new ConnectPoint(DEV1, P3);
+    private static final HostLocation HOST_LOC13 = new HostLocation(CP13, 0);
+    private static final ConnectPoint CP21 = new ConnectPoint(DEV2, P1);
+    private static final HostLocation HOST_LOC21 = new HostLocation(CP21, 0);
+    private static final ConnectPoint CP22 = new ConnectPoint(DEV2, P2);
+    private static final HostLocation HOST_LOC22 = new HostLocation(CP22, 0);
+    // Connect Point for dual-homed host failover
+    private static final ConnectPoint CP31 = new ConnectPoint(DEV3, P1);
+    private static final HostLocation HOST_LOC31 = new HostLocation(CP31, 0);
+    private static final ConnectPoint CP32 = new ConnectPoint(DEV3, P2);
+    private static final HostLocation HOST_LOC32 = new HostLocation(CP32, 0);
+    private static final ConnectPoint CP41 = new ConnectPoint(DEV4, P1);
+    private static final HostLocation HOST_LOC41 = new HostLocation(CP41, 0);
+    private static final ConnectPoint CP39 = new ConnectPoint(DEV3, P9);
+    private static final ConnectPoint CP49 = new ConnectPoint(DEV4, P9);
+    // Conenct Point for mastership test
+    private static final ConnectPoint CP51 = new ConnectPoint(DEV5, P1);
+    private static final HostLocation HOST_LOC51 = new HostLocation(CP51, 0);
+    private static final ConnectPoint CP61 = new ConnectPoint(DEV6, P1);
+    private static final HostLocation HOST_LOC61 = new HostLocation(CP61, 0);
+    // Interface VLAN
+    private static final VlanId INTF_VLAN_UNTAGGED = VlanId.vlanId((short) 10);
+    private static final Set<VlanId> INTF_VLAN_TAGGED = Sets.newHashSet(VlanId.vlanId((short) 20));
+    private static final VlanId INTF_VLAN_NATIVE = VlanId.vlanId((short) 30);
+    private static final Set<VlanId> INTF_VLAN_PAIR = Sets.newHashSet(VlanId.vlanId((short) 10),
+                                     VlanId.vlanId((short) 20), VlanId.vlanId((short) 30));
+    private static final VlanId INTF_VLAN_OTHER = VlanId.vlanId((short) 40);
+    // Interface subnet
+    private static final IpPrefix INTF_PREFIX1 = IpPrefix.valueOf("10.0.1.254/24");
+    private static final IpPrefix INTF_PREFIX2 = IpPrefix.valueOf("10.0.2.254/24");
+    private static final IpPrefix INTF_PREFIX3 = IpPrefix.valueOf("10.0.3.254/24");
+    private static final InterfaceIpAddress INTF_IP1 =
+            new InterfaceIpAddress(INTF_PREFIX1.address(), INTF_PREFIX1);
+    private static final InterfaceIpAddress INTF_IP2 =
+            new InterfaceIpAddress(INTF_PREFIX2.address(), INTF_PREFIX2);
+    private static final InterfaceIpAddress INTF_IP3 =
+            new InterfaceIpAddress(INTF_PREFIX3.address(), INTF_PREFIX3);
+    // Interfaces
+    private static final Interface INTF11 =
+            new Interface(null, CP11, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                          INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF12 =
+            new Interface(null, CP12, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                          INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF13 =
+            new Interface(null, CP13, Lists.newArrayList(INTF_IP2), MacAddress.NONE, null,
+                          null, INTF_VLAN_TAGGED, INTF_VLAN_NATIVE);
+    private static final Interface INTF21 =
+            new Interface(null, CP21, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                          INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF22 =
+            new Interface(null, CP22, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                          INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF31 =
+            new Interface(null, CP31, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                          INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF32 =
+            new Interface(null, CP32, Lists.newArrayList(INTF_IP3), MacAddress.NONE, null,
+                          INTF_VLAN_OTHER, null, null);
+    private static final Interface INTF39 =
+            new Interface(null, CP39, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                          null, INTF_VLAN_PAIR, null);
+    private static final Interface INTF41 =
+            new Interface(null, CP41, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                          INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF49 =
+            new Interface(null, CP49, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                          null, INTF_VLAN_PAIR, null);
+    // Host
+    private static final Host HOST1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC,
+                                                      HOST_VLAN_UNTAGGED,
+                                                      Sets.newHashSet(HOST_LOC11, HOST_LOC21),
+                                                      Sets.newHashSet(HOST_IP11),
+                                                      false);
+
+    // A set of hosts
+    private static final Set<Host> HOSTS = Sets.newHashSet(HOST1);
+    // A set of devices of which we have mastership
+    private static final Set<DeviceId> LOCAL_DEVICES = Sets.newHashSet(DEV1, DEV2, DEV3, DEV4);
+    // A set of interfaces
+    private static final Set<Interface> INTERFACES = Sets.newHashSet(INTF11, INTF12, INTF13, INTF21,
+                                                                     INTF22, INTF31, INTF32, INTF39, INTF41, INTF49);
+
+    private PwaasConfig config;
+    private PwaasConfig invalidConfigVlan;
+    private PwaasConfig invalidConfigMode;
+    private PwaasConfig invalidConfigLabel;
+    private PwaasConfig invalidConfigConflictingVlan;
+
+    @Before
+    public void setUp() throws Exception {
+        InputStream jsonStream = PwaasConfig.class
+                .getResourceAsStream("/pwaas.json");
+        InputStream jsonStreamInvalid1 = PwaasConfig.class
+                .getResourceAsStream("/pwaas-invalid-mode.json");
+        InputStream jsonStreamInvalid2 = PwaasConfig.class
+                .getResourceAsStream("/pwaas-invalid-pwlabel.json");
+        InputStream jsonStreamInvalid3 = PwaasConfig.class
+                .getResourceAsStream("/pwaas-invalid-vlan.json");
+        InputStream jsonStreamInvalid4 = PwaasConfig.class
+                .getResourceAsStream("/pwaas-conflicting-vlan.json");
+
+        String key = SegmentRoutingManager.APP_NAME;
+        ApplicationId subject = new TestApplicationId(key);
+        ObjectMapper mapper = new ObjectMapper();
+
+        JsonNode jsonNode = mapper.readTree(jsonStream);
+        JsonNode jsonNodeInvalid1 = mapper.readTree(jsonStreamInvalid1);
+        JsonNode jsonNodeInvalid2 = mapper.readTree(jsonStreamInvalid2);
+        JsonNode jsonNodeInvalid3 = mapper.readTree(jsonStreamInvalid3);
+        JsonNode jsonNodeInvalid4 = mapper.readTree(jsonStreamInvalid4);
+
+        ConfigApplyDelegate delegate = new MockDelegate();
+
+        DeviceService devService = new MockDeviceService();
+        InterfaceService infService = new MockInterfaceService(INTERFACES);
+
+        // create two devices and add them
+        DefaultAnnotations.Builder builderDev1 = DefaultAnnotations.builder();
+        DefaultAnnotations.Builder builderDev2 = DefaultAnnotations.builder();
+
+        Device dev1 = new MockDevice(DEV1, builderDev1.build());
+        Device dev2 = new MockDevice(DEV2, builderDev2.build());
+        ((MockDeviceService) devService).addDevice(dev1);
+        ((MockDeviceService) devService).addDevice(dev2);
+
+        config = new PwaasConfig(devService, infService);
+        invalidConfigVlan = new PwaasConfig(devService, infService);
+        invalidConfigMode = new PwaasConfig(devService, infService);
+        invalidConfigLabel = new PwaasConfig(devService, infService);
+        invalidConfigConflictingVlan = new PwaasConfig(devService, infService);
+
+        config.init(subject, key, jsonNode, mapper, delegate);
+        invalidConfigVlan.init(subject, key, jsonNodeInvalid1, mapper, delegate);
+        invalidConfigMode.init(subject, key, jsonNodeInvalid2, mapper, delegate);
+        invalidConfigLabel.init(subject, key, jsonNodeInvalid3, mapper, delegate);
+        invalidConfigConflictingVlan.init(subject, key, jsonNodeInvalid4, mapper, delegate);
+
+        config.deviceService = devService;
+        config.intfService = infService;
+
+        invalidConfigVlan.deviceService = devService;
+        invalidConfigVlan.intfService = infService;
+
+        invalidConfigLabel.deviceService = devService;
+        invalidConfigLabel.intfService = infService;
+
+        invalidConfigMode.deviceService = devService;
+        invalidConfigMode.intfService = infService;
+
+        invalidConfigConflictingVlan.deviceService = devService;
+        invalidConfigConflictingVlan.intfService = infService;
+    }
+
+    /**
+     * Tests config validity.
+     */
+    @Test
+    public void testIsValid() {
+        try {
+            assertTrue(config.isValid());
+        } catch (IllegalArgumentException e) {
+            assertTrue(false);
+        }
+    }
+
+    /**
+     * Tests config in-validity.
+     */
+    @Test
+    public void testValid1() {
+        assertFalse(invalidConfigVlan.isValid());
+    }
+
+    @Test
+    public void testValid2() {
+        assertFalse(invalidConfigMode.isValid());
+    }
+
+    @Test
+    public void testValid3() {
+        assertFalse(invalidConfigLabel.isValid());
+    }
+
+    @Test
+    public void testValid4() {
+        assertFalse(invalidConfigConflictingVlan.isValid());
+    }
+
+    /**
+     * Tests getPwIds.
+     */
+    @Test
+    public void testGetPwIds() {
+        Set<Long> pwIds = config.getPwIds();
+
+        assertThat(pwIds.size(), is(2));
+        assertTrue(pwIds.contains(Long.parseLong(TUNNEL_ID_1)));
+        assertTrue(pwIds.contains(Long.parseLong(TUNNEL_ID_2)));
+        assertFalse(pwIds.contains(Long.parseLong(NOT_PRESENT_TUNNEL_ID)));
+    }
+
+    /**
+     * Tests getPwDescription.
+     */
+    @Test
+    public void testGetPwDescription() {
+        L2TunnelDescription l2TunnelDescription = null;
+
+        L2Tunnel l2Tunnel = new DefaultL2Tunnel(
+            L2Mode.valueOf(MODE_1),
+            SD_TAG_1,
+            Long.parseLong(TUNNEL_ID_1),
+            PW_LABEL_1
+        );
+        L2TunnelPolicy l2TunnelPolicy = new DefaultL2TunnelPolicy(
+                Long.parseLong(TUNNEL_ID_1),
+                INGRESS_1,
+                INGRESS_INNER_TAG_1,
+                INGRESS_OUTER_TAG_1,
+                EGRESS_1,
+                EGRESS_INNER_TAG_1,
+                EGRESS_OUTER_TAG_1
+        );
+
+        l2TunnelDescription = config.getPwDescription(Long.parseLong(TUNNEL_ID_1));
+        assertThat(l2TunnelDescription.l2Tunnel().pwMode(), is(l2Tunnel.pwMode()));
+        assertThat(l2TunnelDescription.l2Tunnel().sdTag(), is(l2Tunnel.sdTag()));
+        assertThat(l2TunnelDescription.l2Tunnel().tunnelId(), is(l2Tunnel.tunnelId()));
+        assertThat(l2TunnelDescription.l2Tunnel().pwLabel(), is(l2Tunnel.pwLabel()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().tunnelId(), is(l2TunnelPolicy.tunnelId()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP1InnerTag(), is(l2TunnelPolicy.cP1InnerTag()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP1OuterTag(), is(l2TunnelPolicy.cP1OuterTag()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP2InnerTag(), is(l2TunnelPolicy.cP2InnerTag()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP2OuterTag(), is(l2TunnelPolicy.cP2OuterTag()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP1(), is(l2TunnelPolicy.cP1()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP2(), is(l2TunnelPolicy.cP2()));
+
+        l2Tunnel = new DefaultL2Tunnel(
+                L2Mode.valueOf(MODE_2),
+                SD_TAG_2,
+                Long.parseLong(TUNNEL_ID_2),
+                PW_LABEL_2
+        );
+        l2TunnelPolicy = new DefaultL2TunnelPolicy(
+                Long.parseLong(TUNNEL_ID_2),
+                INGRESS_2,
+                INGRESS_INNER_TAG_2,
+                INGRESS_OUTER_TAG_2,
+                EGRESS_2,
+                EGRESS_INNER_TAG_2,
+                EGRESS_OUTER_TAG_2
+        );
+
+        l2TunnelDescription = config.getPwDescription(Long.parseLong(TUNNEL_ID_2));
+        assertThat(l2TunnelDescription.l2Tunnel().pwMode(), is(l2Tunnel.pwMode()));
+        assertThat(l2TunnelDescription.l2Tunnel().sdTag(), is(l2Tunnel.sdTag()));
+        assertThat(l2TunnelDescription.l2Tunnel().tunnelId(), is(l2Tunnel.tunnelId()));
+        assertThat(l2TunnelDescription.l2Tunnel().pwLabel(), is(l2Tunnel.pwLabel()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().tunnelId(), is(l2TunnelPolicy.tunnelId()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP1InnerTag(), is(l2TunnelPolicy.cP1InnerTag()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP1OuterTag(), is(l2TunnelPolicy.cP1OuterTag()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP2OuterTag(), is(l2TunnelPolicy.cP2OuterTag()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP2OuterTag(), is(l2TunnelPolicy.cP2OuterTag()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP1(), is(l2TunnelPolicy.cP1()));
+        assertThat(l2TunnelDescription.l2TunnelPolicy().cP2(), is(l2TunnelPolicy.cP2()));
+    }
+
+    private class MockDelegate implements ConfigApplyDelegate {
+        @Override
+        public void onApply(Config config) {
+        }
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java
new file mode 100644
index 0000000..843ba6b
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java
@@ -0,0 +1,459 @@
+/*
+ * Copyright 2017-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;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.routeservice.ResolvedRoute;
+import org.onosproject.routeservice.Route;
+import org.onosproject.routeservice.RouteEvent;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.reset;
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * Unit test for {@link RouteHandler}.
+ */
+public class RouteHandlerTest {
+    private SegmentRoutingManager srManager;
+    private RouteHandler routeHandler;
+    private HostService hostService;
+
+    // Mocked routing and bridging tables
+    private static final Map<MockBridgingTableKey, MockBridgingTableValue> BRIDGING_TABLE =
+            Maps.newConcurrentMap();
+    private static final Map<MockRoutingTableKey, MockRoutingTableValue> ROUTING_TABLE =
+            Maps.newConcurrentMap();
+    private static final Map<ConnectPoint, Set<IpPrefix>> SUBNET_TABLE = Maps.newConcurrentMap();
+    // Mocked Next Id
+    private static final Map<Integer, TrafficTreatment> NEXT_TABLE = Maps.newConcurrentMap();
+
+    private static final IpPrefix P1 = IpPrefix.valueOf("10.0.0.0/24");
+
+    // Single homed router 1
+    private static final IpAddress N1 = IpAddress.valueOf("10.0.1.254");
+    private static final MacAddress M1 = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final VlanId V1 = VlanId.vlanId((short) 1);
+    private static final ConnectPoint CP1 = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
+    private static final Route R1 = new Route(Route.Source.STATIC, P1, N1);
+    private static final ResolvedRoute RR1 = new ResolvedRoute(R1, M1, V1);
+
+    // Single homed router 2
+    private static final IpAddress N2 = IpAddress.valueOf("10.0.2.254");
+    private static final MacAddress M2 = MacAddress.valueOf("00:00:00:00:00:02");
+    private static final VlanId V2 = VlanId.vlanId((short) 2);
+    private static final ConnectPoint CP2 = ConnectPoint.deviceConnectPoint("of:0000000000000002/2");
+    private static final Route R2 = new Route(Route.Source.STATIC, P1, N2);
+    private static final ResolvedRoute RR2 = new ResolvedRoute(R2, M2, V2);
+
+    // Dual homed router 1
+    private static final IpAddress N3 = IpAddress.valueOf("10.0.3.254");
+    private static final MacAddress M3 = MacAddress.valueOf("00:00:00:00:00:03");
+    private static final VlanId V3 = VlanId.vlanId((short) 3);
+    private static final Route R3 = new Route(Route.Source.STATIC, P1, N3);
+    private static final ResolvedRoute RR3 = new ResolvedRoute(R3, M3, V3);
+
+    // Hosts
+    private static final Host H1 = new DefaultHost(ProviderId.NONE, HostId.hostId(M1, V1), M1, V1,
+            Sets.newHashSet(new HostLocation(CP1, 0)), Sets.newHashSet(N1), false);
+    private static final Host H2 = new DefaultHost(ProviderId.NONE, HostId.hostId(M2, V2), M2, V2,
+            Sets.newHashSet(new HostLocation(CP2, 0)), Sets.newHashSet(N2), false);
+    private static final Host H3D = new DefaultHost(ProviderId.NONE, HostId.hostId(M3, V3), M3, V3,
+            Sets.newHashSet(new HostLocation(CP1, 0), new HostLocation(CP2, 0)), Sets.newHashSet(N3), false);
+    private static final Host H3S = new DefaultHost(ProviderId.NONE, HostId.hostId(M3, V3), M3, V3,
+            Sets.newHashSet(new HostLocation(CP1, 0)), Sets.newHashSet(N3), false);
+
+    // Pair Local Port
+    private static final PortNumber P9 = PortNumber.portNumber(9);
+
+    // A set of hosts
+    private static final Set<Host> HOSTS = Sets.newHashSet(H1, H2, H3D);
+    private static final Set<Host> HOSTS_ONE_FAIL = Sets.newHashSet(H1, H2, H3S);
+    private static final Set<Host> HOSTS_BOTH_FAIL = Sets.newHashSet(H1, H2);
+    // A set of devices of which we have mastership
+    private static final Set<DeviceId> LOCAL_DEVICES = Sets.newHashSet(CP1.deviceId(), CP2.deviceId());
+    // A set of interfaces
+    private static final Set<Interface> INTERFACES = Sets.newHashSet();
+
+    @Before
+    public void setUp() throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        ConfigApplyDelegate delegate = config -> { };
+
+        SegmentRoutingDeviceConfig dev1Config = new SegmentRoutingDeviceConfig();
+        JsonNode dev1Tree = mapper.createObjectNode();
+        dev1Config.init(CP1.deviceId(), "host-handler-test", dev1Tree, mapper, delegate);
+        dev1Config.setPairDeviceId(CP2.deviceId()).setPairLocalPort(P9);
+
+        SegmentRoutingDeviceConfig dev2Config = new SegmentRoutingDeviceConfig();
+        JsonNode dev2Tree = mapper.createObjectNode();
+        dev2Config.init(CP2.deviceId(), "host-handler-test", dev2Tree, mapper, delegate);
+        dev2Config.setPairDeviceId(CP1.deviceId()).setPairLocalPort(P9);
+
+        MockNetworkConfigRegistry mockNetworkConfigRegistry = new MockNetworkConfigRegistry();
+        mockNetworkConfigRegistry.applyConfig(dev1Config);
+        mockNetworkConfigRegistry.applyConfig(dev2Config);
+
+        // Initialize Segment Routing Manager
+        srManager = new MockSegmentRoutingManager(NEXT_TABLE);
+        srManager.cfgService = new NetworkConfigRegistryAdapter();
+        srManager.deviceConfiguration = createMock(DeviceConfiguration.class);
+        srManager.flowObjectiveService = new MockFlowObjectiveService(BRIDGING_TABLE, NEXT_TABLE);
+        srManager.routingRulePopulator = new MockRoutingRulePopulator(srManager, ROUTING_TABLE);
+        srManager.defaultRoutingHandler = new MockDefaultRoutingHandler(srManager, SUBNET_TABLE);
+        srManager.interfaceService = new MockInterfaceService(INTERFACES);
+        srManager.mastershipService = new MockMastershipService(LOCAL_DEVICES);
+        hostService = new MockHostService(HOSTS);
+        srManager.hostService = hostService;
+        srManager.cfgService = mockNetworkConfigRegistry;
+        srManager.routeService = new MockRouteService(ROUTING_TABLE);
+
+        routeHandler = new RouteHandler(srManager) {
+            // routeEventCache is not necessary for unit tests
+            @Override
+            void enqueueRouteEvent(RouteEvent routeEvent) {
+                dequeueRouteEvent(routeEvent);
+            }
+        };
+
+        ROUTING_TABLE.clear();
+        BRIDGING_TABLE.clear();
+        SUBNET_TABLE.clear();
+    }
+
+    @Test
+    public void init() throws Exception {
+        MockRoutingTableKey rtk = new MockRoutingTableKey(CP1.deviceId(), P1);
+        MockRoutingTableValue rtv = new MockRoutingTableValue(CP1.port(), M1, V1);
+        ROUTING_TABLE.put(rtk, rtv);
+
+        routeHandler.init(CP1.deviceId());
+
+        assertEquals(1, ROUTING_TABLE.size());
+        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
+        assertEquals(M1, rtv1.macAddress);
+        assertEquals(V1, rtv1.vlanId);
+        assertEquals(CP1.port(), rtv1.portNumber);
+
+        assertEquals(1, SUBNET_TABLE.size());
+        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
+    }
+
+    @Test
+    public void processRouteAdded() throws Exception {
+        reset(srManager.deviceConfiguration);
+        srManager.deviceConfiguration.addSubnet(CP1, P1);
+        expectLastCall().once();
+        replay(srManager.deviceConfiguration);
+
+        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_ADDED, RR1, Sets.newHashSet(RR1));
+        routeHandler.processRouteAdded(re);
+
+        assertEquals(1, ROUTING_TABLE.size());
+        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
+        assertEquals(M1, rtv1.macAddress);
+        assertEquals(V1, rtv1.vlanId);
+        assertEquals(CP1.port(), rtv1.portNumber);
+
+        assertEquals(1, SUBNET_TABLE.size());
+        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
+
+        verify(srManager.deviceConfiguration);
+    }
+
+    @Test
+    public void processRouteUpdated() throws Exception {
+        processRouteAdded();
+
+        reset(srManager.deviceConfiguration);
+        srManager.deviceConfiguration.removeSubnet(CP1, P1);
+        expectLastCall().once();
+        srManager.deviceConfiguration.addSubnet(CP2, P1);
+        expectLastCall().once();
+        replay(srManager.deviceConfiguration);
+
+        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_UPDATED, RR2, RR1, Sets.newHashSet(RR2),
+                Sets.newHashSet(RR1));
+        routeHandler.processRouteUpdated(re);
+
+        // Note: We shouldn't remove the old nexthop during the occasion of route update
+        //       since the populate subnet will take care of it and point it to an ECMP group
+        assertEquals(2, ROUTING_TABLE.size());
+        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
+        assertEquals(M2, rtv2.macAddress);
+        assertEquals(V2, rtv2.vlanId);
+        assertEquals(CP2.port(), rtv2.portNumber);
+
+        assertEquals(1, SUBNET_TABLE.size());
+        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));
+
+        verify(srManager.deviceConfiguration);
+    }
+
+    @Test
+    public void processRouteRemoved() throws Exception {
+        processRouteAdded();
+
+        reset(srManager.deviceConfiguration);
+        srManager.deviceConfiguration.removeSubnet(CP1, P1);
+        expectLastCall().once();
+        replay(srManager.deviceConfiguration);
+
+        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, RR1, Sets.newHashSet(RR1));
+        routeHandler.processRouteRemoved(re);
+
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, SUBNET_TABLE.size());
+
+        verify(srManager.deviceConfiguration);
+    }
+
+    @Test
+    public void testTwoSingleHomedAdded() throws Exception {
+        reset(srManager.deviceConfiguration);
+        srManager.deviceConfiguration.addSubnet(CP1, P1);
+        expectLastCall().once();
+        srManager.deviceConfiguration.addSubnet(CP2, P1);
+        expectLastCall().once();
+        replay(srManager.deviceConfiguration);
+
+        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_ADDED, RR1, Sets.newHashSet(RR1, RR2));
+        routeHandler.processRouteAdded(re);
+
+        assertEquals(2, ROUTING_TABLE.size());
+        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
+        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
+        assertEquals(M1, rtv1.macAddress);
+        assertEquals(M2, rtv2.macAddress);
+        assertEquals(V1, rtv1.vlanId);
+        assertEquals(V2, rtv2.vlanId);
+        assertEquals(CP1.port(), rtv1.portNumber);
+        assertEquals(CP2.port(), rtv2.portNumber);
+
+        assertEquals(2, SUBNET_TABLE.size());
+        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
+        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));
+
+        verify(srManager.deviceConfiguration);
+    }
+
+    @Test
+    public void testOneDualHomedAdded() throws Exception {
+        reset(srManager.deviceConfiguration);
+        srManager.deviceConfiguration.addSubnet(CP1, P1);
+        expectLastCall().once();
+        srManager.deviceConfiguration.addSubnet(CP2, P1);
+        expectLastCall().once();
+        replay(srManager.deviceConfiguration);
+
+        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_ADDED, RR3, Sets.newHashSet(RR3));
+        routeHandler.processRouteAdded(re);
+
+        assertEquals(2, ROUTING_TABLE.size());
+        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
+        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
+        assertEquals(M3, rtv1.macAddress);
+        assertEquals(M3, rtv2.macAddress);
+        assertEquals(V3, rtv1.vlanId);
+        assertEquals(V3, rtv2.vlanId);
+        assertEquals(CP1.port(), rtv1.portNumber);
+        assertEquals(CP2.port(), rtv2.portNumber);
+
+        assertEquals(2, SUBNET_TABLE.size());
+        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
+        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));
+
+        verify(srManager.deviceConfiguration);
+    }
+
+    @Test
+    public void testOneSingleHomedToTwoSingleHomed() throws Exception {
+        processRouteAdded();
+
+        reset(srManager.deviceConfiguration);
+        srManager.deviceConfiguration.addSubnet(CP2, P1);
+        expectLastCall().once();
+        replay(srManager.deviceConfiguration);
+
+        RouteEvent re = new RouteEvent(RouteEvent.Type.ALTERNATIVE_ROUTES_CHANGED, RR1, null,
+                Sets.newHashSet(RR1, RR2), Sets.newHashSet(RR1));
+        routeHandler.processAlternativeRoutesChanged(re);
+
+        assertEquals(2, ROUTING_TABLE.size());
+        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
+        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
+        assertEquals(M1, rtv1.macAddress);
+        assertEquals(M2, rtv2.macAddress);
+        assertEquals(V1, rtv1.vlanId);
+        assertEquals(V2, rtv2.vlanId);
+        assertEquals(CP1.port(), rtv1.portNumber);
+        assertEquals(CP2.port(), rtv2.portNumber);
+
+        assertEquals(2, SUBNET_TABLE.size());
+        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
+        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));
+
+        verify(srManager.deviceConfiguration);
+    }
+
+    @Test
+    public void testTwoSingleHomedToOneSingleHomed() throws Exception {
+        testTwoSingleHomedAdded();
+
+        reset(srManager.deviceConfiguration);
+        srManager.deviceConfiguration.removeSubnet(CP2, P1);
+        expectLastCall().once();
+        replay(srManager.deviceConfiguration);
+
+        RouteEvent re = new RouteEvent(RouteEvent.Type.ALTERNATIVE_ROUTES_CHANGED, RR1, null,
+                Sets.newHashSet(RR1), Sets.newHashSet(RR1, RR2));
+        routeHandler.processAlternativeRoutesChanged(re);
+
+        // Note: We shouldn't remove the old nexthop during the occasion of route update
+        //       since the populate subnet will take care of it and point it to an ECMP group
+        assertEquals(2, ROUTING_TABLE.size());
+        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
+        assertEquals(M1, rtv1.macAddress);
+        assertEquals(V1, rtv1.vlanId);
+        assertEquals(CP1.port(), rtv1.portNumber);
+
+        assertEquals(1, SUBNET_TABLE.size());
+        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
+
+        verify(srManager.deviceConfiguration);
+    }
+
+    // TODO Add test cases for two single homed next hop at same location
+
+    @Test
+    public void testDualHomedSingleLocationFail() throws Exception {
+        testOneDualHomedAdded();
+
+        HostEvent he = new HostEvent(HostEvent.Type.HOST_MOVED, H3S, H3D);
+        routeHandler.processHostMovedEvent(he);
+
+        assertEquals(2, ROUTING_TABLE.size());
+        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
+        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
+        assertEquals(M3, rtv1.macAddress);
+        assertEquals(M3, rtv2.macAddress);
+        assertEquals(V3, rtv1.vlanId);
+        assertEquals(V3, rtv2.vlanId);
+        assertEquals(CP1.port(), rtv1.portNumber);
+        assertEquals(P9, rtv2.portNumber);
+
+        // ECMP route table hasn't changed
+        assertEquals(2, SUBNET_TABLE.size());
+        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
+        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));
+    }
+
+    @Test
+    public void testDualHomedBothLocationFail() throws Exception {
+        testDualHomedSingleLocationFail();
+
+        hostService = new MockHostService(HOSTS_ONE_FAIL);
+
+        reset(srManager.deviceConfiguration);
+        srManager.deviceConfiguration.removeSubnet(CP1, P1);
+        expectLastCall().once();
+        srManager.deviceConfiguration.removeSubnet(CP2, P1);
+        expectLastCall().once();
+        replay(srManager.deviceConfiguration);
+
+        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, RR3, Sets.newHashSet(RR3));
+        routeHandler.processRouteRemoved(re);
+
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, SUBNET_TABLE.size());
+
+        verify(srManager.deviceConfiguration);
+    }
+
+    @Test
+    public void testTwoSingleHomedRemoved() throws Exception {
+        testTwoSingleHomedAdded();
+
+        hostService = new MockHostService(HOSTS_BOTH_FAIL);
+
+        reset(srManager.deviceConfiguration);
+        srManager.deviceConfiguration.removeSubnet(CP1, P1);
+        expectLastCall().once();
+        srManager.deviceConfiguration.removeSubnet(CP2, P1);
+        expectLastCall().once();
+        replay(srManager.deviceConfiguration);
+
+        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, RR1, Sets.newHashSet(RR1, RR2));
+        routeHandler.processRouteRemoved(re);
+
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, SUBNET_TABLE.size());
+
+        verify(srManager.deviceConfiguration);
+    }
+
+    @Test
+    public void testOneDualHomeRemoved() throws Exception {
+        testOneDualHomedAdded();
+
+        reset(srManager.deviceConfiguration);
+        srManager.deviceConfiguration.removeSubnet(CP1, P1);
+        expectLastCall().once();
+        srManager.deviceConfiguration.removeSubnet(CP2, P1);
+        expectLastCall().once();
+        replay(srManager.deviceConfiguration);
+
+        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, RR3, Sets.newHashSet(RR3));
+        routeHandler.processRouteRemoved(re);
+
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, SUBNET_TABLE.size());
+
+        verify(srManager.deviceConfiguration);
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/BlockedPortsConfigTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/BlockedPortsConfigTest.java
new file mode 100644
index 0000000..e457896
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/BlockedPortsConfigTest.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2017-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.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Unit tests for {@link BlockedPortsConfig}.
+ */
+public class BlockedPortsConfigTest {
+
+    private static final ApplicationId APP_ID = new DefaultApplicationId(1, "foo");
+    private static final String KEY = "blocked";
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
+    private static final String DEV1 = "of:0000000000000001";
+    private static final String DEV2 = "of:0000000000000002";
+    private static final String DEV3 = "of:0000000000000003";
+    private static final String DEV4 = "of:0000000000000004";
+    private static final String RANGE_14 = "1-4";
+    private static final String RANGE_79 = "7-9";
+    private static final String P1 = "1";
+    private static final String P5 = "5";
+    private static final String P9 = "9";
+
+    private BlockedPortsConfig cfg;
+    private BlockedPortsConfig.Range range;
+
+    private void print(String s) {
+        System.out.println(s);
+    }
+
+    private void print(Object o) {
+        print(o.toString());
+    }
+
+    @Before
+    public void setUp() throws IOException {
+        InputStream blockedPortsJson = BlockedPortsConfigTest.class
+                .getResourceAsStream("/blocked-ports.json");
+        JsonNode node = MAPPER.readTree(blockedPortsJson);
+        cfg = new BlockedPortsConfig();
+        cfg.init(APP_ID, KEY, node, MAPPER, null);
+    }
+
+    @Test
+    public void basic() {
+        cfg = new BlockedPortsConfig();
+        print(cfg);
+
+        assertEquals("non-empty devices list", 0, cfg.deviceIds().size());
+        assertEquals("non-empty port-ranges list", 0, cfg.portRanges("non-exist").size());
+    }
+
+
+    @Test
+    public void overIteratePort() {
+        Iterator<Long> iterator = cfg.portIterator(DEV3);
+        while (iterator.hasNext()) {
+            print(iterator.next());
+        }
+
+        try {
+            print(iterator.next());
+            fail("NoSuchElement exception NOT thrown");
+        } catch (NoSuchElementException e) {
+            print("<good> " + e);
+        }
+    }
+
+    @Test
+    public void overIterateRange() {
+        range = new BlockedPortsConfig.Range("4-6");
+
+        Iterator<Long> iterator = range.iterator();
+        while (iterator.hasNext()) {
+            print(iterator.next());
+        }
+
+        try {
+            print(iterator.next());
+            fail("NoSuchElement exception NOT thrown");
+        } catch (NoSuchElementException e) {
+            print("<good> " + e);
+        }
+    }
+
+
+    @Test
+    public void simple() {
+        List<String> devIds = cfg.deviceIds();
+        print(devIds);
+        assertEquals("wrong dev id count", 3, devIds.size());
+        assertEquals("missing dev 1", true, devIds.contains(DEV1));
+        assertEquals("dev 2??", false, devIds.contains(DEV2));
+        assertEquals("missing dev 3", true, devIds.contains(DEV3));
+
+        List<String> d1ranges = cfg.portRanges(DEV1);
+        print(d1ranges);
+        assertEquals("wrong d1 range count", 2, d1ranges.size());
+        assertEquals("missing 1-4", true, d1ranges.contains(RANGE_14));
+        assertEquals("missing 7-9", true, d1ranges.contains(RANGE_79));
+
+        List<String> d2ranges = cfg.portRanges(DEV2);
+        print(d2ranges);
+        assertEquals("wrong d2 range count", 0, d2ranges.size());
+
+        List<String> d3ranges = cfg.portRanges(DEV3);
+        print(d3ranges);
+        assertEquals("wrong d3 range count", 1, d3ranges.size());
+        assertEquals("range 1-4?", false, d3ranges.contains(RANGE_14));
+        assertEquals("missing 7-9", true, d3ranges.contains(RANGE_79));
+    }
+
+
+    private void verifyPorts(List<Long> ports, long... exp) {
+        assertEquals("Wrong port count", exp.length, ports.size());
+        for (long e : exp) {
+            assertEquals("missing port", true, ports.contains(e));
+        }
+    }
+
+    private void verifyPortIterator(String devid, long... exp) {
+        List<Long> ports = new ArrayList<>();
+        Iterator<Long> iter = cfg.portIterator(devid);
+        iter.forEachRemaining(ports::add);
+        print(ports);
+        verifyPorts(ports, exp);
+    }
+
+    @Test
+    public void rangeIterators() {
+        verifyPortIterator(DEV1, 1, 2, 3, 4, 7, 8, 9);
+        verifyPortIterator(DEV2);
+        verifyPortIterator(DEV3, 7, 8, 9);
+    }
+
+    @Test
+    public void singlePorts() {
+        List<String> devIds = cfg.deviceIds();
+        print(devIds);
+        assertEquals("wrong dev id count", 3, devIds.size());
+        assertEquals("missing dev 4", true, devIds.contains(DEV4));
+
+        List<String> d1ranges = cfg.portRanges(DEV4);
+        print(d1ranges);
+        assertEquals("wrong d4 range count", 3, d1ranges.size());
+        assertEquals("missing 1", true, d1ranges.contains(P1));
+        assertEquals("missing 5", true, d1ranges.contains(P5));
+        assertEquals("missing 9", true, d1ranges.contains(P9));
+
+        verifyPortIterator(DEV4, 1, 5, 9);
+    }
+
+
+    // test Range inner class
+
+    @Test
+    public void rangeBadFormat() {
+        try {
+            range = new BlockedPortsConfig.Range("not-a-range-format");
+            fail("no exception thrown");
+        } catch (IllegalArgumentException iar) {
+            print(iar);
+            assertEquals("wrong msg", "Bad Range Format not-a-range-format", iar.getMessage());
+        }
+    }
+
+    @Test
+    public void rangeBadHi() {
+        try {
+            range = new BlockedPortsConfig.Range("2-nine");
+            fail("no exception thrown");
+        } catch (IllegalArgumentException iar) {
+            print(iar);
+            assertEquals("wrong msg", "Bad Range Format 2-nine", iar.getMessage());
+        }
+    }
+
+    @Test
+    public void rangeHiLessThanLo() {
+        try {
+            range = new BlockedPortsConfig.Range("9-5");
+            fail("no exception thrown");
+        } catch (IllegalArgumentException iar) {
+            print(iar);
+            assertEquals("wrong msg", "Bad Range Format 9-5", iar.getMessage());
+        }
+    }
+
+    @Test
+    public void rangeNegative() {
+        try {
+            range = new BlockedPortsConfig.Range("-2-4");
+            fail("no exception thrown");
+        } catch (IllegalArgumentException iar) {
+            print(iar);
+            assertEquals("wrong msg", "Bad Range Format -2-4", iar.getMessage());
+        }
+    }
+
+    @Test
+    public void rangeGood() {
+        range = new BlockedPortsConfig.Range("100-104");
+        List<Long> values = new ArrayList<>();
+        range.iterator().forEachRemaining(values::add);
+        print(values);
+        verifyPorts(values, 100, 101, 102, 103, 104);
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfigTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfigTest.java
new file mode 100644
index 0000000..72b1ef5
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfigTest.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+
+import java.io.InputStream;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.*;
+
+/**
+ * Tests for class {@link SegmentRoutingAppConfig}.
+ */
+public class SegmentRoutingAppConfigTest {
+    private SegmentRoutingAppConfig config;
+    private SegmentRoutingAppConfig invalidConfig;
+    private SegmentRoutingAppConfig mplsEcmpConfig;
+
+    private static final MacAddress ROUTER_MAC_1 = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final MacAddress ROUTER_MAC_2 = MacAddress.valueOf("00:00:00:00:00:02");
+    private static final MacAddress ROUTER_MAC_3 = MacAddress.valueOf("00:00:00:00:00:03");
+    private static final ConnectPoint PORT_1 = ConnectPoint.deviceConnectPoint("of:1/1");
+    private static final ConnectPoint PORT_2 = ConnectPoint.deviceConnectPoint("of:1/2");
+    private static final ConnectPoint PORT_3 = ConnectPoint.deviceConnectPoint("of:1/3");
+    private static final DeviceId VROUTER_ID_1 = DeviceId.deviceId("of:1");
+    private static final DeviceId VROUTER_ID_2 = DeviceId.deviceId("of:2");
+    private static final String PROVIDER_1 = "org.onosproject.provider.host";
+    private static final String PROVIDER_2 = "org.onosproject.netcfghost";
+    private static final String PROVIDER_3 = "org.onosproject.anotherprovider";
+
+    /**
+     * Initialize test related variables.
+     *
+     * @throws Exception
+     */
+    @Before
+    public void setUp() throws Exception {
+        InputStream jsonStream = SegmentRoutingAppConfigTest.class
+                .getResourceAsStream("/app.json");
+        InputStream invalidJsonStream = SegmentRoutingAppConfigTest.class
+                .getResourceAsStream("/app-invalid.json");
+        InputStream mplsEcmpJsonStream = SegmentRoutingAppConfigTest.class
+                .getResourceAsStream("/app-ecmp.json");
+
+        String key = SegmentRoutingManager.APP_NAME;
+        ApplicationId subject = new TestApplicationId(key);
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode jsonNode = mapper.readTree(jsonStream);
+        JsonNode invalidJsonNode = mapper.readTree(invalidJsonStream);
+        JsonNode mplsEcmpJsonNode = mapper.readTree(mplsEcmpJsonStream);
+        ConfigApplyDelegate delegate = new MockDelegate();
+
+        config = new SegmentRoutingAppConfig();
+        config.init(subject, key, jsonNode, mapper, delegate);
+        invalidConfig = new SegmentRoutingAppConfig();
+        invalidConfig.init(subject, key, invalidJsonNode, mapper, delegate);
+        mplsEcmpConfig = new SegmentRoutingAppConfig();
+        mplsEcmpConfig.init(subject, key, mplsEcmpJsonNode, mapper, delegate);
+    }
+
+    /**
+     * Tests config validity.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testIsValid() throws Exception {
+        assertTrue(config.isValid());
+        assertFalse(invalidConfig.isValid());
+        assertTrue(mplsEcmpConfig.isValid());
+    }
+
+    /**
+     * Test MPLS-ECMP default getter. By-default
+     * MPLS-ECMPS is false.
+     */
+    @Test
+    public void testDefaultMplsEcmp() {
+        boolean mplsEcmp = config.mplsEcmp();
+        assertThat(mplsEcmp, is(false));
+    }
+
+    /**
+     * Test MPLS-ECMP getter.
+     */
+    @Test
+    public void testMplsEcmp() {
+        boolean mplsEcmp = mplsEcmpConfig.mplsEcmp();
+        assertThat(mplsEcmp, is(true));
+    }
+
+    /**
+     * Test MPLS-ECMP setter.
+     */
+    @Test
+    public void testSetMplsEcmp() {
+        /*
+         * In the config the value is not set.
+         */
+        boolean mplsEcmp = config.mplsEcmp();
+        assertThat(mplsEcmp, is(false));
+        config.setMplsEcmp(true);
+        mplsEcmp = config.mplsEcmp();
+        assertThat(mplsEcmp, is(true));
+        /*
+         * In the mplsEcmpConfig the value is true,
+         */
+        mplsEcmp = mplsEcmpConfig.mplsEcmp();
+        assertThat(mplsEcmp, is(true));
+        config.setMplsEcmp(false);
+        mplsEcmp = config.mplsEcmp();
+        assertThat(mplsEcmp, is(false));
+    }
+
+    /**
+     * Tests vRouterMacs getter.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVRouterMacs() throws Exception {
+        Set<MacAddress> vRouterMacs = config.vRouterMacs();
+        assertNotNull("vRouterMacs should not be null", vRouterMacs);
+        assertThat(vRouterMacs.size(), is(2));
+        assertTrue(vRouterMacs.contains(ROUTER_MAC_1));
+        assertTrue(vRouterMacs.contains(ROUTER_MAC_2));
+    }
+
+    /**
+     * Tests vRouterMacs setter.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testSetVRouterMacs() throws Exception {
+        ImmutableSet.Builder<MacAddress> builder = ImmutableSet.builder();
+        builder.add(ROUTER_MAC_3);
+        config.setVRouterMacs(builder.build());
+
+        Set<MacAddress> vRouterMacs = config.vRouterMacs();
+        assertThat(vRouterMacs.size(), is(1));
+        assertTrue(vRouterMacs.contains(ROUTER_MAC_3));
+    }
+
+    /**
+     * Tests suppressSubnet getter.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testSuppressSubnet() throws Exception {
+        Set<ConnectPoint> suppressSubnet = config.suppressSubnet();
+        assertNotNull("suppressSubnet should not be null", suppressSubnet);
+        assertThat(suppressSubnet.size(), is(2));
+        assertTrue(suppressSubnet.contains(PORT_1));
+        assertTrue(suppressSubnet.contains(PORT_2));
+    }
+
+    /**
+     * Tests suppressSubnet setter.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testSetSuppressSubnet() throws Exception {
+        ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
+        builder.add(PORT_3);
+        config.setSuppressSubnet(builder.build());
+
+        Set<ConnectPoint> suppressSubnet = config.suppressSubnet();
+        assertNotNull("suppressSubnet should not be null", suppressSubnet);
+        assertThat(suppressSubnet.size(), is(1));
+        assertTrue(suppressSubnet.contains(PORT_3));
+    }
+
+    /**
+     * Tests suppressHostByPort getter.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testSuppressHostByPort() throws Exception {
+        Set<ConnectPoint> suppressHostByPort = config.suppressHostByPort();
+        assertNotNull("suppressHostByPort should not be null", suppressHostByPort);
+        assertThat(suppressHostByPort.size(), is(2));
+        assertTrue(suppressHostByPort.contains(PORT_1));
+        assertTrue(suppressHostByPort.contains(PORT_2));
+    }
+
+    /**
+     * Tests suppressHostByPort setter.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testSetSuppressHostByPort() throws Exception {
+        ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
+        builder.add(PORT_3);
+        config.setSuppressHostByPort(builder.build());
+
+        Set<ConnectPoint> suppressHostByPort = config.suppressHostByPort();
+        assertNotNull("suppressHostByPort should not be null", suppressHostByPort);
+        assertThat(suppressHostByPort.size(), is(1));
+        assertTrue(suppressHostByPort.contains(PORT_3));
+    }
+
+    /**
+     * Tests suppressHostByProvider getter.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testSuppressHostByProvider() throws Exception {
+        Set<String> supprsuppressHostByProvider = config.suppressHostByProvider();
+        assertNotNull("suppressHostByProvider should not be null", supprsuppressHostByProvider);
+        assertThat(supprsuppressHostByProvider.size(), is(2));
+        assertTrue(supprsuppressHostByProvider.contains(PROVIDER_1));
+        assertTrue(supprsuppressHostByProvider.contains(PROVIDER_2));
+    }
+
+    /**
+     * Tests suppressHostByProvider setter.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testSetHostLearning() throws Exception {
+        ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+        builder.add(PROVIDER_3);
+        config.setSuppressHostByProvider(builder.build());
+
+        Set<String> supprsuppressHostByProvider = config.suppressHostByProvider();
+        assertNotNull("suppressHostByProvider should not be null", supprsuppressHostByProvider);
+        assertThat(supprsuppressHostByProvider.size(), is(1));
+        assertTrue(supprsuppressHostByProvider.contains(PROVIDER_3));
+    }
+
+    private class MockDelegate implements ConfigApplyDelegate {
+        @Override
+        public void onApply(Config config) {
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingDeviceConfigTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingDeviceConfigTest.java
new file mode 100644
index 0000000..ddf90bb
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingDeviceConfigTest.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for class {@link SegmentRoutingDeviceConfig}.
+ */
+public class SegmentRoutingDeviceConfigTest {
+    private SegmentRoutingDeviceConfig config;
+    private SegmentRoutingDeviceConfig ipv6Config;
+    private SegmentRoutingDeviceConfig pairConfig;
+    private SegmentRoutingDeviceConfig invalidConfig;
+    private Map<Integer, Set<Integer>> adjacencySids1;
+    private Map<Integer, Set<Integer>> adjacencySids2;
+    private static final DeviceId PAIR_DEVICE_ID = DeviceId.deviceId("of:123456789ABCDEF0");
+    private static final PortNumber PAIR_LOCAL_PORT = PortNumber.portNumber(10);
+
+    @Before
+    public void setUp() throws Exception {
+        InputStream jsonStream = SegmentRoutingDeviceConfigTest.class
+                .getResourceAsStream("/device.json");
+        InputStream ipv6JsonStream = SegmentRoutingDeviceConfigTest.class
+                .getResourceAsStream("/device-ipv6.json");
+        InputStream pairJsonStream = SegmentRoutingDeviceConfigTest.class
+                .getResourceAsStream("/device-pair.json");
+        InputStream invalidJsonStream = SegmentRoutingDeviceConfigTest.class
+                .getResourceAsStream("/device-invalid.json");
+
+        adjacencySids1 = new HashMap<>();
+        Set<Integer> ports1 = new HashSet<>();
+        ports1.add(2);
+        ports1.add(3);
+        adjacencySids1.put(100, ports1);
+        Set<Integer> ports2 = new HashSet<>();
+        ports2.add(4);
+        ports2.add(5);
+        adjacencySids1.put(200, ports2);
+
+        adjacencySids2 = new HashMap<>();
+        Set<Integer> ports3 = new HashSet<>();
+        ports3.add(6);
+        adjacencySids2.put(300, ports3);
+
+        DeviceId subject = DeviceId.deviceId("of:0000000000000001");
+        String key = "segmentrouting";
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode jsonNode = mapper.readTree(jsonStream);
+        JsonNode ipv6JsonNode = mapper.readTree(ipv6JsonStream);
+        JsonNode pairJsonNode = mapper.readTree(pairJsonStream);
+        JsonNode invalidJsonNode = mapper.readTree(invalidJsonStream);
+        ConfigApplyDelegate delegate = new MockDelegate();
+
+        config = new SegmentRoutingDeviceConfig();
+        config.init(subject, key, jsonNode, mapper, delegate);
+
+        ipv6Config = new SegmentRoutingDeviceConfig();
+        ipv6Config.init(subject, key, ipv6JsonNode, mapper, delegate);
+
+        pairConfig = new SegmentRoutingDeviceConfig();
+        pairConfig.init(subject, key, pairJsonNode, mapper, delegate);
+
+        invalidConfig = new SegmentRoutingDeviceConfig();
+        invalidConfig.init(subject, key, invalidJsonNode, mapper, delegate);
+    }
+
+    @Test
+    public void testIsValid() {
+        assertTrue(config.isValid());
+        assertTrue(ipv6Config.isValid());
+        assertTrue(pairConfig.isValid());
+        assertFalse(invalidConfig.isValid());
+    }
+
+    @Test
+    public void testName() throws Exception {
+        assertTrue(config.name().isPresent());
+        assertThat(config.name().get(), is("Leaf-R1"));
+    }
+
+    @Test
+    public void testSetName() throws Exception {
+        config.setName("Spine-R1");
+        assertTrue(config.name().isPresent());
+        assertThat(config.name().get(), is("Spine-R1"));
+    }
+
+    @Test
+    public void testRouterIp() throws Exception {
+        assertThat(config.routerIpv4(), is(IpAddress.valueOf("10.0.1.254")));
+        assertThat(ipv6Config.routerIpv4(), is(IpAddress.valueOf("10.0.1.254")));
+        assertThat(ipv6Config.routerIpv6(), is(IpAddress.valueOf("2000::c0a8:0101")));
+    }
+
+    @Test
+    public void testSetRouterIp() throws Exception {
+        config.setRouterIpv4("10.0.2.254");
+        assertThat(config.routerIpv4(), is(IpAddress.valueOf("10.0.2.254")));
+        ipv6Config.setRouterIpv4("10.0.2.254");
+        assertThat(ipv6Config.routerIpv4(), is(IpAddress.valueOf("10.0.2.254")));
+        ipv6Config.setRouterIpv6("2000::c0a9:0101");
+        assertThat(ipv6Config.routerIpv6(), is(IpAddress.valueOf("2000::c0a9:0101")));
+    }
+
+    @Test
+    public void testRouterMac() throws Exception {
+        assertThat(config.routerMac(), is(MacAddress.valueOf("00:00:00:00:01:80")));
+    }
+
+    @Test
+    public void testSetRouterMac() throws Exception {
+        config.setRouterMac("00:00:00:00:02:80");
+        assertThat(config.routerMac(), is(MacAddress.valueOf("00:00:00:00:02:80")));
+    }
+
+    @Test
+    public void testNodeSid() throws Exception {
+        assertThat(config.nodeSidIPv4(), is(101));
+        assertThat(ipv6Config.nodeSidIPv4(), is(101));
+        assertThat(ipv6Config.nodeSidIPv6(), is(111));
+    }
+
+    @Test
+    public void testSetNodeSid() throws Exception {
+        config.setNodeSidIPv4(200);
+        assertThat(config.nodeSidIPv4(), is(200));
+        ipv6Config.setNodeSidIPv4(200);
+        assertThat(ipv6Config.nodeSidIPv4(), is(200));
+        ipv6Config.setNodeSidIPv6(201);
+        assertThat(ipv6Config.nodeSidIPv6(), is(201));
+    }
+
+    @Test
+    public void testIsEdgeRouter() throws Exception {
+        assertThat(config.isEdgeRouter(), is(true));
+    }
+
+    @Test
+    public void testSetIsEdgeRouter() throws Exception {
+        config.setIsEdgeRouter(false);
+        assertThat(config.isEdgeRouter(), is(false));
+    }
+
+    @Test
+    public void testAdjacencySids() throws Exception {
+        assertThat(config.adjacencySids(), is(adjacencySids1));
+    }
+
+    @Test
+    public void testSetAdjacencySids() throws Exception {
+        config.setAdjacencySids(adjacencySids2);
+        assertThat(config.adjacencySids(), is(adjacencySids2));
+    }
+
+    @Test
+    public void testPairDeviceId() throws Exception {
+        assertNull(config.pairDeviceId());
+        assertNull(ipv6Config.pairDeviceId());
+        assertThat(pairConfig.pairDeviceId(), is(PAIR_DEVICE_ID));
+    }
+
+    @Test
+    public void testSetPairDeviceId() throws Exception {
+        config.setPairDeviceId(PAIR_DEVICE_ID);
+        assertThat(config.pairDeviceId(), is(PAIR_DEVICE_ID));
+    }
+
+    @Test
+    public void testPairLocalPort() throws Exception {
+        assertNull(config.pairLocalPort());
+        assertNull(ipv6Config.pairLocalPort());
+        assertThat(pairConfig.pairLocalPort(), is(PAIR_LOCAL_PORT));
+    }
+
+    @Test
+    public void testSetPairLocalPort() throws Exception {
+        config.setPairLocalPort(PAIR_LOCAL_PORT);
+        assertThat(config.pairLocalPort(), is(PAIR_LOCAL_PORT));
+    }
+
+    private class MockDelegate implements ConfigApplyDelegate {
+        @Override
+        public void onApply(Config configFile) {
+        }
+    }
+}
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/XConnectConfigTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/XConnectConfigTest.java
new file mode 100644
index 0000000..62d2d86
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/config/XConnectConfigTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.onosproject.segmentrouting.storekey.XConnectStoreKey;
+import java.io.InputStream;
+import java.util.Set;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Tests for class {@link XConnectConfig}.
+ */
+public class XConnectConfigTest {
+    private static final DeviceId DEV1 = DeviceId.deviceId("of:0000000000000001");
+    private static final DeviceId DEV2 = DeviceId.deviceId("of:0000000000000002");
+    private static final VlanId VLAN10 = VlanId.vlanId((short) 10);
+    private static final VlanId VLAN20 = VlanId.vlanId((short) 20);
+    private static final PortNumber PORT3 = PortNumber.portNumber(3);
+    private static final PortNumber PORT4 = PortNumber.portNumber(4);
+    private static final PortNumber PORT5 = PortNumber.portNumber(5);
+    private static final XConnectStoreKey KEY1 = new XConnectStoreKey(DEV1, VLAN10);
+    private static final XConnectStoreKey KEY2 = new XConnectStoreKey(DEV2, VLAN10);
+    private static final XConnectStoreKey KEY3 = new XConnectStoreKey(DEV2, VLAN20);
+    private static final XConnectStoreKey KEY4 = new XConnectStoreKey(DEV2, VlanId.NONE);
+
+    private XConnectConfig config;
+    private XConnectConfig invalidConfig;
+
+    @Before
+    public void setUp() throws Exception {
+        InputStream jsonStream = SegmentRoutingAppConfigTest.class
+                .getResourceAsStream("/xconnect.json");
+        InputStream invalidJsonStream = SegmentRoutingAppConfigTest.class
+                .getResourceAsStream("/xconnect-invalid.json");
+
+        String key = SegmentRoutingManager.APP_NAME;
+        ApplicationId subject = new TestApplicationId(key);
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode jsonNode = mapper.readTree(jsonStream);
+        JsonNode invalidJsonNode = mapper.readTree(invalidJsonStream);
+        ConfigApplyDelegate delegate = new XConnectConfigTest.MockDelegate();
+
+        config = new XConnectConfig();
+        config.init(subject, key, jsonNode, mapper, delegate);
+        invalidConfig = new XConnectConfig();
+        invalidConfig.init(subject, key, invalidJsonNode, mapper, delegate);
+    }
+
+    /**
+     * Tests config validity.
+     */
+    @Test
+    public void testIsValid() {
+        assertTrue(config.isValid());
+        assertFalse(invalidConfig.isValid());
+    }
+
+    /**
+     * Tests getXconnects.
+     */
+    @Test
+    public void testGetXconnects() {
+        Set<XConnectStoreKey> xconnects = config.getXconnects();
+        assertThat(xconnects.size(), is(3));
+        assertTrue(xconnects.contains(KEY1));
+        assertTrue(xconnects.contains(KEY2));
+        assertTrue(xconnects.contains(KEY3));
+        assertFalse(xconnects.contains(KEY4));
+    }
+
+    /**
+     * Tests getPorts.
+     */
+    @Test
+    public void testGetPorts() {
+        Set<PortNumber> ports;
+
+        ports = config.getPorts(KEY1);
+        assertThat(ports.size(), is(2));
+        assertTrue(ports.contains(PORT3));
+        assertTrue(ports.contains(PORT4));
+
+        ports = config.getPorts(KEY2);
+        assertThat(ports.size(), is(2));
+        assertTrue(ports.contains(PORT3));
+        assertTrue(ports.contains(PORT4));
+
+        ports = config.getPorts(KEY3);
+        assertThat(ports.size(), is(2));
+        assertTrue(ports.contains(PORT4));
+        assertTrue(ports.contains(PORT5));
+    }
+
+    private class MockDelegate implements ConfigApplyDelegate {
+        @Override
+        public void onApply(Config config) {
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/grouphandler/DestinationSetTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/grouphandler/DestinationSetTest.java
new file mode 100644
index 0000000..f890852
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/grouphandler/DestinationSetTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2017-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.grouphandler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.net.DeviceId;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class DestinationSetTest {
+    DestinationSet ds1, ds2, ds3, ds4;
+    DeviceId d201, d202;
+    int el201, el202;
+
+    @Before
+    public void setUp() {
+        d201 = DeviceId.deviceId("of:0000000000000201");
+        d202 = DeviceId.deviceId("of:0000000000000202");
+        el201 = 201;
+        el202 = 202;
+        ds1 = new DestinationSet(false, d201);
+        ds2 = new DestinationSet(false, el201, d201);
+        ds3 = new DestinationSet(false, el201, d201, el202, d202);
+        ds4 = new DestinationSet(false,
+                                 DestinationSet.NO_EDGE_LABEL, d201,
+                                 DestinationSet.NO_EDGE_LABEL, d202);
+    }
+
+    @Test
+    public void testIsValid() {
+        assertTrue(!ds1.mplsSet());
+        assertTrue(ds1.getEdgeLabel(d201) == DestinationSet.NO_EDGE_LABEL);
+        assertTrue(ds1.getDestinationSwitches().size() == 1);
+
+        assertTrue(!ds2.mplsSet());
+        assertTrue(ds2.getEdgeLabel(d201) == el201);
+        assertTrue(ds2.getDestinationSwitches().size() == 1);
+
+        assertTrue(!ds3.mplsSet());
+        assertTrue(ds3.getEdgeLabel(d201) == el201);
+        assertTrue(ds3.getEdgeLabel(d202) == el202);
+        assertTrue(ds3.getDestinationSwitches().size() == 2);
+
+        assertTrue(!ds4.mplsSet());
+        assertTrue(ds4.getEdgeLabel(d201) == DestinationSet.NO_EDGE_LABEL);
+        assertTrue(ds4.getEdgeLabel(d202) == DestinationSet.NO_EDGE_LABEL);
+        assertTrue(ds4.getDestinationSwitches().size() == 2);
+
+        assertFalse(ds1.equals(ds2));
+        assertFalse(ds1.equals(ds4));
+        assertFalse(ds3.equals(ds4));
+        assertFalse(ds2.equals(ds3));
+    }
+
+
+    @Test
+    public void testOneDestinationWithoutLabel() {
+        DestinationSet testds = new DestinationSet(false, d201);
+        assertTrue(testds.equals(ds1)); // match
+
+        testds = new DestinationSet(true, d201);
+        assertFalse(testds.equals(ds1)); //wrong mplsSet
+
+        testds = new DestinationSet(false, d202);
+        assertFalse(testds.equals(ds1)); //wrong device
+
+        testds = new DestinationSet(false, el201, d201);
+        assertFalse(testds.equals(ds1)); // wrong label
+
+        testds = new DestinationSet(false, -1, d201, -1, d202);
+        assertFalse(testds.equals(ds1)); // 2-devs should not match
+    }
+
+
+
+    @Test
+    public void testOneDestinationWithLabel() {
+        DestinationSet testds = new DestinationSet(false, 203, d202);
+        assertFalse(testds.equals(ds2)); //wrong label
+
+        testds = new DestinationSet(true, 201, d201);
+        assertFalse(testds.equals(ds2)); //wrong mplsSet
+
+        testds = new DestinationSet(false, 201, d202);
+        assertFalse(testds.equals(ds2)); //wrong device
+
+        testds = new DestinationSet(false, 201, DeviceId.deviceId("of:0000000000000201"));
+        assertTrue(testds.equals(ds2)); // match
+
+        testds = new DestinationSet(false, d201);
+        assertFalse(testds.equals(ds2)); // wrong label
+
+        testds = new DestinationSet(false, el201, d201, el202, d202);
+        assertFalse(testds.equals(ds1)); // 2-devs should not match
+    }
+
+    @Test
+    public void testDestPairWithLabel() {
+        DestinationSet testds = new DestinationSet(false, el201, d201, el202, d202);
+        assertTrue(testds.equals(ds3)); // match same switches, same order
+        assertTrue(testds.hashCode() == ds3.hashCode());
+
+        testds = new DestinationSet(false, el202, d202, el201, d201);
+        assertTrue(testds.equals(ds3)); // match same switches, order reversed
+        assertTrue(testds.hashCode() == ds3.hashCode());
+
+        testds = new DestinationSet(false, el202, d202);
+        assertFalse(testds.equals(ds3)); // one less switch should not match
+        assertFalse(testds.hashCode() == ds3.hashCode());
+
+        testds = new DestinationSet(false, el201, d201);
+        assertFalse(testds.equals(ds3)); // one less switch should not match
+        assertFalse(testds.hashCode() == ds3.hashCode());
+
+        testds = new DestinationSet(false, el201, d201, 0, DeviceId.NONE);
+        assertFalse(testds.equals(ds3)); // one less switch should not match
+        assertFalse(testds.hashCode() == ds3.hashCode());
+
+        testds = new DestinationSet(false, el201, d202, el201, d201);
+        assertFalse(testds.equals(ds3)); // wrong labels
+        assertFalse(testds.hashCode() == ds3.hashCode());
+
+        testds = new DestinationSet(true, el202, d202, el201, d201);
+        assertFalse(testds.equals(ds3)); // wrong mpls set
+        assertFalse(testds.hashCode() == ds3.hashCode());
+
+        testds = new DestinationSet(false, el202, d202, el201, d202);
+        assertFalse(testds.equals(ds3)); // wrong device
+        assertFalse(testds.hashCode() == ds3.hashCode());
+
+        testds = new DestinationSet(false,
+                                    el202, DeviceId.deviceId("of:0000000000000205"),
+                                    el201, d201);
+        assertFalse(testds.equals(ds3)); // wrong device
+        assertFalse(testds.hashCode() == ds3.hashCode());
+    }
+
+    @Test
+    public void testDestPairWithoutLabel() {
+        DestinationSet testds = new DestinationSet(false, -1, d201, -1, d202);
+        assertTrue(testds.equals(ds4)); // match same switches, same order
+        assertTrue(testds.hashCode() == ds4.hashCode());
+
+        testds = new DestinationSet(false, -1, d202, -1, d201);
+        assertTrue(testds.equals(ds4)); // match same switches, order reversed
+        assertTrue(testds.hashCode() == ds4.hashCode());
+
+        testds = new DestinationSet(false, -1, d202);
+        assertFalse(testds.equals(ds4)); // one less switch should not match
+        assertFalse(testds.hashCode() == ds4.hashCode());
+
+        testds = new DestinationSet(false, -1, d201);
+        assertFalse(testds.equals(ds4)); // one less switch should not match
+        assertFalse(testds.hashCode() == ds4.hashCode());
+
+        testds = new DestinationSet(false, -1, d201, 0, DeviceId.NONE);
+        assertFalse(testds.equals(ds4)); // one less switch should not match
+        assertFalse(testds.hashCode() == ds4.hashCode());
+
+        testds = new DestinationSet(false, el201, d201, -1, d202);
+        assertFalse(testds.equals(ds4)); // wrong labels
+        assertFalse(testds.hashCode() == ds4.hashCode());
+
+        testds = new DestinationSet(true, -1, d202, -1, d201);
+        assertFalse(testds.equals(ds4)); // wrong mpls set
+        assertFalse(testds.hashCode() == ds4.hashCode());
+
+        testds = new DestinationSet(false, -1, d202, -1, d202);
+        assertFalse(testds.equals(ds4)); // wrong device
+        assertFalse(testds.hashCode() == ds4.hashCode());
+
+        testds = new DestinationSet(false,
+                                    -1, DeviceId.deviceId("of:0000000000000205"),
+                                    -1, d201);
+        assertFalse(testds.equals(ds4)); // wrong device
+        assertFalse(testds.hashCode() == ds4.hashCode());
+    }
+
+}
diff --git a/apps/segmentrouting/app/src/test/resources/app-ecmp.json b/apps/segmentrouting/app/src/test/resources/app-ecmp.json
new file mode 100644
index 0000000..e94b1c5
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/app-ecmp.json
@@ -0,0 +1,19 @@
+{
+  "vRouterMacs" : [
+      "00:00:00:00:00:01",
+      "00:00:00:00:00:02"
+  ],
+  "suppressSubnet" : [
+      "of:1/1",
+      "of:1/2"
+  ],
+  "suppressHostByPort" : [
+      "of:1/1",
+      "of:1/2"
+  ],
+  "suppressHostByProvider" : [
+      "org.onosproject.provider.host",
+      "org.onosproject.netcfghost"
+  ],
+  "MPLS-ECMP" : true
+}
diff --git a/apps/segmentrouting/app/src/test/resources/app-invalid.json b/apps/segmentrouting/app/src/test/resources/app-invalid.json
new file mode 100644
index 0000000..01508f8
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/app-invalid.json
@@ -0,0 +1,15 @@
+{
+  "vRouterMacs" : [
+      "00:00:00:00:00:01",
+      "00:00:00:00:00:02"
+  ],
+  "suppressSubnet" : [
+      "of:1/1",
+      "of:1/2"
+  ],
+  "suppressHostByPort" : [
+      "of:1/1",
+      "wrongPort"
+  ],
+  "suppressHostByProvider" : []
+}
diff --git a/apps/segmentrouting/app/src/test/resources/app.json b/apps/segmentrouting/app/src/test/resources/app.json
new file mode 100644
index 0000000..dab6384
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/app.json
@@ -0,0 +1,18 @@
+{
+  "vRouterMacs" : [
+      "00:00:00:00:00:01",
+      "00:00:00:00:00:02"
+  ],
+  "suppressSubnet" : [
+      "of:1/1",
+      "of:1/2"
+  ],
+  "suppressHostByPort" : [
+      "of:1/1",
+      "of:1/2"
+  ],
+  "suppressHostByProvider" : [
+      "org.onosproject.provider.host",
+      "org.onosproject.netcfghost"
+  ]
+}
diff --git a/apps/segmentrouting/app/src/test/resources/blocked-ports-alt.json b/apps/segmentrouting/app/src/test/resources/blocked-ports-alt.json
new file mode 100644
index 0000000..3d8749e
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/blocked-ports-alt.json
@@ -0,0 +1,5 @@
+{
+  "of:0000000000000001": ["1-9"],
+  "of:0000000000000003": ["7"],
+  "of:0000000000000004": ["1"]
+}
diff --git a/apps/segmentrouting/app/src/test/resources/blocked-ports.json b/apps/segmentrouting/app/src/test/resources/blocked-ports.json
new file mode 100644
index 0000000..2543f3d
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/blocked-ports.json
@@ -0,0 +1,5 @@
+{
+  "of:0000000000000001": ["1-4", "7-9"],
+  "of:0000000000000003": ["7-9"],
+  "of:0000000000000004": ["1", "5", "9"]
+}
diff --git a/apps/segmentrouting/app/src/test/resources/device-invalid.json b/apps/segmentrouting/app/src/test/resources/device-invalid.json
new file mode 100644
index 0000000..dfcbdb8
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/device-invalid.json
@@ -0,0 +1,12 @@
+{
+  "name" : "Leaf-R1",
+  "ipv4NodeSid" : 101,
+  "ipv4Loopback" : "10.0.1.254",
+  "routerMac" : "00:00:00:00:01:80",
+  "isEdgeRouter" : true,
+  "adjacencySids" : [
+    { "adjSid" : 100, "ports" : [2, 3] },
+    { "adjSid" : 200, "ports" : [4, 5] }
+  ],
+  "pairDeviceId" : "of:123456789ABCDEF0"
+}
diff --git a/apps/segmentrouting/app/src/test/resources/device-ipv6.json b/apps/segmentrouting/app/src/test/resources/device-ipv6.json
new file mode 100644
index 0000000..9832f8c
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/device-ipv6.json
@@ -0,0 +1,13 @@
+{
+  "name" : "Leaf-R1",
+  "ipv4NodeSid" : 101,
+  "ipv4Loopback" : "10.0.1.254",
+  "ipv6NodeSid" : 111,
+  "ipv6Loopback" : "2000::c0a8:0101",
+  "routerMac" : "00:00:00:00:01:80",
+  "isEdgeRouter" : true,
+  "adjacencySids" : [
+    { "adjSid" : 100, "ports" : [2, 3] },
+    { "adjSid" : 200, "ports" : [4, 5] }
+  ]
+}
diff --git a/apps/segmentrouting/app/src/test/resources/device-pair.json b/apps/segmentrouting/app/src/test/resources/device-pair.json
new file mode 100644
index 0000000..c699ff5
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/device-pair.json
@@ -0,0 +1,13 @@
+{
+  "name" : "Leaf-R1",
+  "ipv4NodeSid" : 101,
+  "ipv4Loopback" : "10.0.1.254",
+  "routerMac" : "00:00:00:00:01:80",
+  "isEdgeRouter" : true,
+  "adjacencySids" : [
+    { "adjSid" : 100, "ports" : [2, 3] },
+    { "adjSid" : 200, "ports" : [4, 5] }
+  ],
+  "pairDeviceId" : "of:123456789ABCDEF0",
+  "pairLocalPort" : "10"
+}
diff --git a/apps/segmentrouting/app/src/test/resources/device.json b/apps/segmentrouting/app/src/test/resources/device.json
new file mode 100644
index 0000000..83aec6e
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/device.json
@@ -0,0 +1,11 @@
+{
+  "name" : "Leaf-R1",
+  "ipv4NodeSid" : 101,
+  "ipv4Loopback" : "10.0.1.254",
+  "routerMac" : "00:00:00:00:01:80",
+  "isEdgeRouter" : true,
+  "adjacencySids" : [
+    { "adjSid" : 100, "ports" : [2, 3] },
+    { "adjSid" : 200, "ports" : [4, 5] }
+  ]
+}
diff --git a/apps/segmentrouting/app/src/test/resources/pwaas-conflicting-vlan.json b/apps/segmentrouting/app/src/test/resources/pwaas-conflicting-vlan.json
new file mode 100644
index 0000000..fac162d
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/pwaas-conflicting-vlan.json
@@ -0,0 +1,24 @@
+{
+  "1": {
+    "cP1": "of:0000000000000001/1",
+    "cP2": "of:0000000000000002/2",
+    "cP1InnerTag": "10",
+    "cP1OuterTag": "20",
+    "cP2InnerTag": "11",
+    "cP2OuterTag": "21",
+    "mode": "RAW",
+    "sdTag": "",
+    "pwLabel": "255"
+  },
+  "20": {
+    "cP1": "of:0000000000000001/1",
+    "cP2": "of:0000000000000002/2",
+    "cP1InnerTag": "100",
+    "cP1OuterTag": "",
+    "cP2InnerTag": "21",
+    "cP2OuterTag": "",
+    "mode": "RAW",
+    "sdTag": "",
+    "pwLabel": "1255"
+  }
+}
diff --git a/apps/segmentrouting/app/src/test/resources/pwaas-invalid-mode.json b/apps/segmentrouting/app/src/test/resources/pwaas-invalid-mode.json
new file mode 100644
index 0000000..af0a9d1
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/pwaas-invalid-mode.json
@@ -0,0 +1,13 @@
+{
+  "1": {
+    "cP1": "of:0000000000000001/1",
+    "cP2": "of:0000000000000011/1",
+    "cP1InnerTag": "10",
+    "cP1OuterTag": "20",
+    "cP2InnerTag": "11",
+    "cP2OuterTag": "",
+    "mode": "UNDEFINED_MODED",
+    "sdTag": "40",
+    "pwLabel": "255"
+  }
+}
diff --git a/apps/segmentrouting/app/src/test/resources/pwaas-invalid-pwlabel.json b/apps/segmentrouting/app/src/test/resources/pwaas-invalid-pwlabel.json
new file mode 100644
index 0000000..66697f5
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/pwaas-invalid-pwlabel.json
@@ -0,0 +1,13 @@
+{
+  "1": {
+    "cP1": "of:0000000000000001/1",
+    "cP2": "of:0000000000000011/1",
+    "cP1InnerTag": "10",
+    "cP1OuterTag": "20",
+    "cP2InnerTag": "11",
+    "cP2OuterTag": "",
+    "mode": "1",
+    "sdTag": "40",
+    "pwLabel": "255.555551"
+  }
+}
diff --git a/apps/segmentrouting/app/src/test/resources/pwaas-invalid-vlan.json b/apps/segmentrouting/app/src/test/resources/pwaas-invalid-vlan.json
new file mode 100644
index 0000000..b556e06
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/pwaas-invalid-vlan.json
@@ -0,0 +1,24 @@
+{
+  "1": {
+    "cP1": "of:0000000000000001/1",
+    "cP2": "of:0000000000000002/2",
+    "cP1InnerTag": "10",
+    "cP1OuterTag": "20",
+    "cP2InnerTag": "11",
+    "cP2OuterTag": "21",
+    "mode": "RAW",
+    "sdTag": "",
+    "pwLabel": "255"
+  },
+  "20": {
+    "cP1": "of:0000000000000001/1",
+    "cP2": "of:0000000000000002/2",
+    "cP1InnerTag": "100",
+    "cP1OuterTag": "200.55",
+    "cP2InnerTag": "1100",
+    "cP2OuterTag": "210",
+    "mode": "RAW",
+    "sdTag": "",
+    "pwLabel": "1255"
+  }
+}
diff --git a/apps/segmentrouting/app/src/test/resources/pwaas.json b/apps/segmentrouting/app/src/test/resources/pwaas.json
new file mode 100644
index 0000000..2a58b4e
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/pwaas.json
@@ -0,0 +1,24 @@
+{
+  "1": {
+    "cP1": "of:0000000000000001/1",
+    "cP2": "of:0000000000000002/1",
+    "cP1InnerTag": "10",
+    "cP1OuterTag": "20",
+    "cP2InnerTag": "10",
+    "cP2OuterTag": "21",
+    "mode": "RAW",
+    "sdTag": "",
+    "pwLabel": "255"
+  },
+  "20": {
+    "cP1": "of:0000000000000001/1",
+    "cP2": "of:0000000000000002/1",
+    "cP1InnerTag": "100",
+    "cP1OuterTag": "200",
+    "cP2InnerTag": "100",
+    "cP2OuterTag": "210",
+    "mode": "RAW",
+    "sdTag": "",
+    "pwLabel": "1255"
+  }
+}
diff --git a/apps/segmentrouting/app/src/test/resources/xconnect-invalid.json b/apps/segmentrouting/app/src/test/resources/xconnect-invalid.json
new file mode 100644
index 0000000..e468271
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/xconnect-invalid.json
@@ -0,0 +1,18 @@
+{
+  "of:0000000000000001": [
+    {
+      "vlan": 10,
+      "ports": [3, 4]
+    }
+  ],
+  "of:0000000000000002": [
+    {
+      "vlan": 10,
+      "ports": [3, 4]
+    },
+    {
+      "vlan": 20,
+      "ports": [4, 5, 6]
+    }
+  ]
+}
diff --git a/apps/segmentrouting/app/src/test/resources/xconnect.json b/apps/segmentrouting/app/src/test/resources/xconnect.json
new file mode 100644
index 0000000..ebd61b3
--- /dev/null
+++ b/apps/segmentrouting/app/src/test/resources/xconnect.json
@@ -0,0 +1,19 @@
+{
+  "of:0000000000000001": [
+    {
+      "vlan": 10,
+      "ports": [3, 4],
+      "name": "OLT1"
+    }
+  ],
+  "of:0000000000000002": [
+    {
+      "vlan": 10,
+      "ports": [3, 4]
+    },
+    {
+      "vlan": 20,
+      "ports": [4, 5]
+    }
+  ]
+}
