diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..3e541f0
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2014 Open Networking Laboratory
+  ~
+  ~ 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.
+  --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+    <artifactId>onos-apps</artifactId>
+    <groupId>org.onosproject</groupId>
+    <version>1.2.0-SNAPSHOT</version>
+  </parent>
+
+    <artifactId>onos-app-segmentrouting</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>ONOS OSGi bundle archetype</description>
+    <url>http://onosproject.org</url>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-grouphandler</artifactId>
+            <version>1.2.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/src/main/java/org/onosproject/segmentrouting/ArpHandler.java b/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
new file mode 100644
index 0000000..5b94518
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.HostId;
+import org.onosproject.net.packet.OutboundPacket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class ArpHandler {
+
+    private static Logger log = LoggerFactory.getLogger(ArpHandler.class);
+
+    private SegmentRoutingManager srManager;
+    private NetworkConfigHandler config;
+
+    /**
+     * Creates an ArpHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public ArpHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.networkConfigHandler);
+    }
+
+    /**
+     * 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.
+     *
+     * @param pkt incoming packet
+     */
+    public void processPacketIn(InboundPacket pkt) {
+
+        Ethernet ethernet = pkt.parsed();
+        ARP arp = (ARP) ethernet.getPayload();
+
+        ConnectPoint connectPoint = pkt.receivedFrom();
+        PortNumber inPort = connectPoint.port();
+        DeviceId deviceId = connectPoint.deviceId();
+        byte[] senderMacAddressByte = arp.getSenderHardwareAddress();
+        Ip4Address hostIpAddress = Ip4Address.valueOf(arp.getSenderProtocolAddress());
+
+        srManager.routingRulePopulator.populateIpRuleForHost(deviceId, hostIpAddress, MacAddress.
+                valueOf(senderMacAddressByte), inPort);
+
+        if (arp.getOpCode() == ARP.OP_REQUEST) {
+            handleArpRequest(deviceId, connectPoint, ethernet);
+        } else {
+            srManager.ipHandler.forwardPackets(deviceId, hostIpAddress);
+        }
+    }
+
+    private void handleArpRequest(DeviceId deviceId, ConnectPoint inPort, Ethernet payload) {
+
+        ARP arpRequest = (ARP) payload.getPayload();
+        HostId targetHostId = HostId.hostId(MacAddress.valueOf(
+                arpRequest.getTargetHardwareAddress()));
+
+        // ARP request for router
+        if (isArpReqForRouter(deviceId, arpRequest)) {
+            Ip4Address targetAddress = Ip4Address.valueOf(arpRequest.getTargetProtocolAddress());
+            sendArpResponse(arpRequest, config.getRouterMac(targetAddress));
+
+        // ARP request for known hosts
+        } else if (srManager.hostService.getHost(targetHostId) != null) {
+            MacAddress targetMac = srManager.hostService.getHost(targetHostId).mac();
+            sendArpResponse(arpRequest, targetMac);
+
+        // ARP request for unknown host in the subnet
+        } else if (isArpReqForSubnet(deviceId, arpRequest)) {
+            flood(payload, inPort);
+        }
+    }
+
+
+    private boolean isArpReqForRouter(DeviceId deviceId, ARP arpRequest) {
+        Ip4Address gatewayIpAddress = config.getGatewayIpAddress(deviceId);
+        if (gatewayIpAddress != null) {
+            Ip4Address targetProtocolAddress = Ip4Address.valueOf(arpRequest
+                    .getTargetProtocolAddress());
+            if (gatewayIpAddress.equals(targetProtocolAddress)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isArpReqForSubnet(DeviceId deviceId, ARP arpRequest) {
+        String subnetInfo = config.getSubnetInfo(deviceId);
+        if (subnetInfo != null) {
+            IpPrefix prefix = IpPrefix.valueOf(subnetInfo);
+            if (prefix.contains(Ip4Address.valueOf(arpRequest.getTargetProtocolAddress()))) {
+                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 = config.getRouterMacAddress(deviceId).toBytes();
+        byte[] senderIpAddress = config.getRouterIpAddress(deviceId)
+                .getIp4Prefix().address().toOctets();
+
+        ARP arpRequest = new ARP();
+        arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
+                  .setProtocolType(ARP.PROTO_TYPE_IP)
+                  .setHardwareAddressLength(
+                        (byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
+                  .setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH)
+                  .setOpCode(ARP.OP_REQUEST)
+                  .setSenderHardwareAddress(senderMacAddress)
+                  .setTargetHardwareAddress(MacAddress.ZERO.toBytes())
+                  .setSenderProtocolAddress(senderIpAddress)
+                  .setTargetProtocolAddress(targetAddress.toOctets());
+
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(MacAddress.BROADCAST.toBytes())
+                .setSourceMACAddress(senderMacAddress)
+                .setEtherType(Ethernet.TYPE_ARP).setPayload(arpRequest);
+
+        flood(eth, inPort);
+    }
+
+    private void sendArpResponse(ARP arpRequest, MacAddress targetMac) {
+
+        ARP arpReply = new ARP();
+        arpReply.setHardwareType(ARP.HW_TYPE_ETHERNET)
+                .setProtocolType(ARP.PROTO_TYPE_IP)
+                .setHardwareAddressLength(
+                        (byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
+                .setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH)
+                .setOpCode(ARP.OP_REPLY)
+                .setSenderHardwareAddress(targetMac.toBytes())
+                .setSenderProtocolAddress(arpRequest.getTargetProtocolAddress())
+                .setTargetHardwareAddress(arpRequest.getSenderHardwareAddress())
+                .setTargetProtocolAddress(arpRequest.getSenderProtocolAddress());
+
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
+                .setSourceMACAddress(targetMac.toBytes())
+                .setEtherType(Ethernet.TYPE_ARP).setPayload(arpReply);
+
+
+        HostId dstId = HostId.hostId(MacAddress.valueOf(
+                arpReply.getTargetHardwareAddress()));
+        Host dst = srManager.hostService.getHost(dstId);
+        if (dst == null) {
+            log.warn("Cannot send ARP response to unknown device");
+            return;
+        }
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().
+                setOutput(dst.location().port()).build();
+        OutboundPacket packet = new DefaultOutboundPacket(dst.location().deviceId(),
+                treatment, ByteBuffer.wrap(eth.serialize()));
+
+        srManager.packetService.emit(packet);
+    }
+
+    private void flood(Ethernet request, ConnectPoint inPort) {
+        TrafficTreatment.Builder builder;
+        ByteBuffer buf = ByteBuffer.wrap(request.serialize());
+
+        for (Port port: srManager.deviceService.getPorts(inPort.deviceId())) {
+            if (!port.number().equals(inPort.port()) &&
+                    port.number().toLong() > 0) {
+                builder = DefaultTrafficTreatment.builder();
+                builder.setOutput(port.number());
+                srManager.packetService.emit(new DefaultOutboundPacket(inPort.deviceId(),
+                        builder.build(), buf));
+            }
+        }
+    }
+
+}
diff --git a/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
new file mode 100644
index 0000000..3684ec9
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.flow.FlowRule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class DefaultRoutingHandler {
+
+    private static Logger log = LoggerFactory.getLogger(DefaultRoutingHandler.class);
+
+    private SegmentRoutingManager srManager;
+    private RoutingRulePopulator rulePopulator;
+    private NetworkConfigHandler config;
+    private Status populationStatus;
+
+    /**
+     * 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.networkConfigHandler);
+        this.populationStatus = Status.IDLE;
+    }
+
+    /**
+     * Populates all routing rules to all connected routers, including default
+     * routing rules, adjacency rules, and policy rules if any.
+     *
+     * @return true if it succeeds in populating all rules, otherwise false
+     */
+    public boolean populateAllRoutingRules() {
+
+        populationStatus = Status.STARTED;
+        log.info("Starts to populate routing rules");
+
+        for (Device sw : srManager.deviceService.getDevices()) {
+            if (srManager.mastershipService.
+                    getLocalRole(sw.id()) != MastershipRole.MASTER) {
+                continue;
+            }
+
+            ECMPShortestPathGraph ecmpSPG = new ECMPShortestPathGraph(sw.id(), srManager);
+            if (!populateEcmpRoutingRules(sw, ecmpSPG)) {
+                populationStatus = Status.ABORTED;
+                log.debug("Abort routing rule population");
+                return false;
+            }
+
+            // TODO: Set adjacency routing rule for all switches
+        }
+
+        populationStatus = Status.SUCCEEDED;
+        log.info("Completes routing rule population");
+        return true;
+    }
+
+    private boolean populateEcmpRoutingRules(Device sw,
+                                             ECMPShortestPathGraph ecmpSPG) {
+
+        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 targetSw : swViaMap.keySet()) {
+                DeviceId destSw = sw.id();
+                Set<DeviceId> nextHops = new HashSet<>();
+
+                for (ArrayList<DeviceId> via : swViaMap.get(targetSw)) {
+                    if (via.isEmpty()) {
+                        nextHops.add(destSw);
+                    } else {
+                        nextHops.add(via.get(0));
+                    }
+                }
+                if (!populateEcmpRoutingRulePartial(targetSw, destSw, nextHops)) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private boolean populateEcmpRoutingRulePartial(DeviceId targetSw, DeviceId destSw,
+                                Set<DeviceId> nextHops) {
+        boolean result;
+
+        if (nextHops.isEmpty()) {
+            nextHops.add(destSw);
+        }
+
+        // If both target switch and dest switch are edge routers, then set IP rule
+        // for both subnet and router IP.
+        if (config.isEdgeRouter(targetSw) && config.isEdgeRouter(destSw)) {
+            String subnets = config.getSubnetInfo(destSw);
+            result = rulePopulator.populateIpRuleForSubnet(targetSw, subnets, destSw, nextHops);
+            if (!result) {
+                return false;
+            }
+
+            IpPrefix routerIp = config.getRouterIpAddress(destSw);
+            result = rulePopulator.populateIpRuleForRouter(targetSw, routerIp, destSw, nextHops);
+            if (!result) {
+                return false;
+            }
+
+        // If the target switch is an edge router, then set IP rules for the router IP.
+        } else if (config.isEdgeRouter(targetSw)) {
+            IpPrefix routerIp = config.getRouterIpAddress(destSw);
+            result = rulePopulator.populateIpRuleForRouter(targetSw, routerIp, destSw, nextHops);
+            if (!result) {
+                return false;
+            }
+
+        // If the target switch is an transit router, then set MPLS rules only.
+        } else if (config.isTransitRouter(targetSw)) {
+            result = rulePopulator.populateMplsRule(targetSw, destSw, nextHops);
+            if (!result) {
+                return false;
+            }
+        } else {
+            log.warn("The switch {} is neither an edge router nor a transit router.", targetSw);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Populates table miss entries for all tables, and pipeline rules for
+     * VLAN and TACM tables.
+     *
+     * @param deviceId Switch ID to set the rules
+     */
+    public void populateTtpRules(DeviceId deviceId) {
+
+        rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.VLAN,
+                true, false, false, FlowRule.Type.DEFAULT);
+        rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.ETHER,
+                true, false, false, FlowRule.Type.DEFAULT);
+        rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.IP,
+                false, true, true, FlowRule.Type.ACL);
+        rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.MPLS,
+                false, true, true, FlowRule.Type.ACL);
+        rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.ACL,
+                false, false, false, FlowRule.Type.DEFAULT);
+
+        rulePopulator.populateTableVlan(deviceId);
+        rulePopulator.populateTableTMac(deviceId);
+    }
+
+    /**
+     * 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() {
+        synchronized (populationStatus) {
+            if (populationStatus == Status.IDLE ||
+                    populationStatus == Status.SUCCEEDED) {
+                populationStatus = Status.STARTED;
+                populateAllRoutingRules();
+            }
+        }
+    }
+
+    /**
+     * Resume the flow rule population process if it was aborted for any reason.
+     * Mostly the process is aborted when the groups required are not set yet.
+     */
+    public void resumePopulationProcess() {
+        synchronized (populationStatus) {
+            if (populationStatus == Status.ABORTED) {
+                populationStatus = Status.STARTED;
+                // TODO: we need to restart from the point aborted instead of restarting.
+                populateAllRoutingRules();
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java b/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
new file mode 100644
index 0000000..17cfd96
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
@@ -0,0 +1,190 @@
+package org.onosproject.segmentrouting;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.grouphandler.DeviceProperties;
+import org.onosproject.net.DeviceId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class DeviceConfiguration implements DeviceProperties {
+
+    private static final Logger log = LoggerFactory
+            .getLogger(DeviceConfiguration.class);
+    private final List<Integer> allSegmentIds =
+            Arrays.asList(101, 102, 103, 104, 105, 106);
+    private HashMap<DeviceId, Integer> deviceSegmentIdMap =
+            new HashMap<DeviceId, Integer>() {
+                {
+                    put(DeviceId.deviceId("of:0000000000000001"), 101);
+                    put(DeviceId.deviceId("of:0000000000000002"), 102);
+                    put(DeviceId.deviceId("of:0000000000000003"), 103);
+                    put(DeviceId.deviceId("of:0000000000000004"), 104);
+                    put(DeviceId.deviceId("of:0000000000000005"), 105);
+                    put(DeviceId.deviceId("of:0000000000000006"), 106);
+                }
+            };
+    private final HashMap<DeviceId, MacAddress> deviceMacMap =
+            new HashMap<DeviceId, MacAddress>() {
+                {
+                    put(DeviceId.deviceId("of:0000000000000001"),
+                            MacAddress.valueOf("00:00:00:00:00:01"));
+                    put(DeviceId.deviceId("of:0000000000000002"),
+                            MacAddress.valueOf("00:00:00:00:00:02"));
+                    put(DeviceId.deviceId("of:0000000000000003"),
+                            MacAddress.valueOf("00:00:00:00:00:03"));
+                    put(DeviceId.deviceId("of:0000000000000004"),
+                            MacAddress.valueOf("00:00:00:00:00:04"));
+                    put(DeviceId.deviceId("of:0000000000000005"),
+                            MacAddress.valueOf("00:00:00:00:00:05"));
+                    put(DeviceId.deviceId("of:0000000000000006"),
+                            MacAddress.valueOf("00:00:00:00:00:06"));
+                }
+            };
+
+    private final HashMap<DeviceId, Ip4Address> deviceIpMap =
+            new HashMap<DeviceId, Ip4Address>() {
+                {
+                    put(DeviceId.deviceId("of:0000000000000001"),
+                            Ip4Address.valueOf("192.168.0.1"));
+                    put(DeviceId.deviceId("of:0000000000000002"),
+                            Ip4Address.valueOf("192.168.0.2"));
+                    put(DeviceId.deviceId("of:0000000000000003"),
+                            Ip4Address.valueOf("192.168.0.3"));
+                    put(DeviceId.deviceId("of:0000000000000004"),
+                            Ip4Address.valueOf("192.168.0.4"));
+                    put(DeviceId.deviceId("of:0000000000000005"),
+                            Ip4Address.valueOf("192.168.0.5"));
+                    put(DeviceId.deviceId("of:0000000000000006"),
+                            Ip4Address.valueOf("192.168.0.6"));
+                }
+            };
+
+    @Override
+    public int getSegmentId(DeviceId deviceId) {
+        if (deviceSegmentIdMap.get(deviceId) != null) {
+            log.debug("getSegmentId for device{} is {}",
+                    deviceId,
+                    deviceSegmentIdMap.get(deviceId));
+            return deviceSegmentIdMap.get(deviceId);
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+
+    @Override
+    public MacAddress getDeviceMac(DeviceId deviceId) {
+        if (deviceMacMap.get(deviceId) != null) {
+            log.debug("getDeviceMac for device{} is {}",
+                    deviceId,
+                    deviceMacMap.get(deviceId));
+            return deviceMacMap.get(deviceId);
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+
+    @Override
+    public boolean isEdgeDevice(DeviceId deviceId) {
+        if (deviceId.equals(DeviceId.deviceId("of:0000000000000001"))
+                || deviceId.equals(DeviceId.deviceId("of:0000000000000006"))) {
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public List<Integer> getAllDeviceSegmentIds() {
+        return allSegmentIds;
+    }
+
+
+    /**
+     * Returns Segment ID for the router with the MAC address given.
+     *
+     * @param targetMac Mac address for the router
+     * @return Segment ID for the router with the MAC address
+     */
+    public int getSegmentId(MacAddress targetMac) {
+        for (Map.Entry<DeviceId, MacAddress> entry: deviceMacMap.entrySet()) {
+            if (entry.getValue().equals(targetMac)) {
+                return deviceSegmentIdMap.get(entry.getKey());
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns Segment ID for the router withe IP address given.
+     *
+     * @param targetAddress IP address of the router
+     * @return Segment ID for the router with the IP address
+     */
+    public int getSegmentId(Ip4Address targetAddress) {
+        for (Map.Entry<DeviceId, Ip4Address> entry: deviceIpMap.entrySet()) {
+            if (entry.getValue().equals(targetAddress)) {
+                return deviceSegmentIdMap.get(entry.getKey());
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns Router IP address for the router with the device ID given.
+     *
+     * @param deviceId device ID of the router
+     * @return IP address of the router
+     */
+    public Ip4Address getRouterIp(DeviceId deviceId) {
+        if (deviceIpMap.get(deviceId) != null) {
+            log.debug("getDeviceIp for device{} is {}",
+                    deviceId,
+                    deviceIpMap.get(deviceId));
+            return deviceIpMap.get(deviceId);
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+    /**
+     * Returns the Device ID of the router with the Segment ID given.
+     *
+     * @param sid Segment ID of the router
+     * @return Device ID of the router
+     */
+    public DeviceId getDeviceId(int sid) {
+        for (Map.Entry<DeviceId, Integer> entry: deviceSegmentIdMap.entrySet()) {
+            if (entry.getValue() == sid) {
+                return entry.getKey();
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the Device ID of the router with the IP address given.
+     *
+     * @param ipAddress IP address of the router
+     * @return Device ID of the router
+     */
+    public DeviceId getDeviceId(Ip4Address ipAddress) {
+        for (Map.Entry<DeviceId, Ip4Address> entry: deviceIpMap.entrySet()) {
+            if (entry.getValue().equals(ipAddress)) {
+                return entry.getKey();
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/src/main/java/org/onosproject/segmentrouting/ECMPShortestPathGraph.java b/src/main/java/org/onosproject/segmentrouting/ECMPShortestPathGraph.java
new file mode 100644
index 0000000..cd28fcf
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/ECMPShortestPathGraph.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This class creates bandwidth constrained breadth first tree and returns paths
+ * from root Device to leaf Devicees which satisfies the bandwidth condition. If
+ * bandwidth parameter is not specified, the normal breadth first tree will be
+ * calculated. 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 linkListToAvoid link list to avoid
+     * @param deviceIdListToAvoid device list to avoid
+     */
+    public ECMPShortestPathGraph(DeviceId rootDevice, List<String> deviceIdListToAvoid,
+                                 List<Link> linkListToAvoid) {
+        this.rootDevice = rootDevice;
+        calcECMPShortestPathGraph(deviceIdListToAvoid, linkListToAvoid);
+    }
+
+    /**
+     * 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 using any provided constraints and Intents.
+     */
+    private void calcECMPShortestPathGraph() {
+        deviceQueue.add(rootDevice);
+        int currDistance = 0;
+        distanceQueue.add(currDistance);
+        deviceSearched.put(rootDevice, currDistance);
+        while (!deviceQueue.isEmpty()) {
+            DeviceId sw = deviceQueue.poll();
+            DeviceId prevSw = null;
+            currDistance = distanceQueue.poll();
+
+            for (Link link : srManager.linkService.getDeviceEgressLinks(sw)) {
+                DeviceId reachedDevice = link.dst().deviceId();
+                if ((prevSw != null)
+                        && (prevSw.equals(reachedDevice))) {
+                    /* Ignore LAG links between the same set of Devicees */
+                    continue;
+                } else  {
+                    prevSw = reachedDevice;
+                }
+
+                Integer distance = deviceSearched.get(reachedDevice);
+                if ((distance != null) && (distance.intValue() < (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<DeviceId>();
+                        distanceSwArray.add(reachedDevice);
+                        distanceDeviceMap.put(currDistance + 1, distanceSwArray);
+                    } else {
+                        distanceSwArray.add(reachedDevice);
+                    }
+                }
+
+                ArrayList<Link> upstreamLinkArray =
+                        upstreamLinks.get(reachedDevice);
+                if (upstreamLinkArray == null) {
+                    upstreamLinkArray = new ArrayList<Link>();
+                    upstreamLinkArray.add(copyDefaultLink(link));
+                    //upstreamLinkArray.add(link);
+                    upstreamLinks.put(reachedDevice, upstreamLinkArray);
+                } else {
+                    /* ECMP links */
+                    upstreamLinkArray.add(copyDefaultLink(link));
+                }
+            }
+        }
+    }
+
+    /**
+     * Calculates the BFS tree using any provided constraints and Intents.
+     */
+    private void calcECMPShortestPathGraph(List<String> deviceIdListToAvoid, List<Link> linksToAvoid) {
+        deviceQueue.add(rootDevice);
+        int currDistance = 0;
+        distanceQueue.add(currDistance);
+        deviceSearched.put(rootDevice, currDistance);
+        boolean foundLinkToAvoid = false;
+        while (!deviceQueue.isEmpty()) {
+            DeviceId sw = deviceQueue.poll();
+            DeviceId prevSw = null;
+            currDistance = distanceQueue.poll();
+            for (Link link : srManager.linkService.getDeviceEgressLinks(sw)) {
+                for (Link linkToAvoid: linksToAvoid) {
+                    // TODO: equls should work
+                    //if (link.equals(linkToAvoid)) {
+                    if (linkContains(link, linksToAvoid)) {
+                        foundLinkToAvoid = true;
+                        break;
+                    }
+                }
+                if (foundLinkToAvoid) {
+                    foundLinkToAvoid = false;
+                    continue;
+                }
+                DeviceId reachedDevice = link.dst().deviceId();
+                if (deviceIdListToAvoid.contains(reachedDevice.toString())) {
+                    continue;
+                }
+                if ((prevSw != null)
+                        && (prevSw.equals(reachedDevice))) {
+                    /* Ignore LAG links between the same set of Devicees */
+                    continue;
+                } else {
+                    prevSw = reachedDevice;
+                }
+
+                Integer distance = deviceSearched.get(reachedDevice);
+                if ((distance != null) && (distance.intValue() < (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<DeviceId>();
+                        distanceSwArray.add(reachedDevice);
+                        distanceDeviceMap.put(currDistance + 1, distanceSwArray);
+                    } else {
+                        distanceSwArray.add(reachedDevice);
+                    }
+                }
+
+                ArrayList<Link> upstreamLinkArray =
+                        upstreamLinks.get(reachedDevice);
+                if (upstreamLinkArray == null) {
+                    upstreamLinkArray = new ArrayList<Link>();
+                    upstreamLinkArray.add(copyDefaultLink(link));
+                    upstreamLinks.put(reachedDevice, upstreamLinkArray);
+                } else {
+                    /* ECMP links */
+                    upstreamLinkArray.add(copyDefaultLink(link));
+                }
+            }
+        }
+    }
+
+
+    private boolean linkContains(Link link, List<Link> links) {
+
+        DeviceId srcDevice1 = link.src().deviceId();
+        DeviceId dstDevice1 = link.dst().deviceId();
+        long srcPort1 = link.src().port().toLong();
+        long dstPort1 = link.dst().port().toLong();
+
+        for (Link link2: links) {
+            DeviceId srcDevice2 = link2.src().deviceId();
+            DeviceId dstDevice2 = link2.dst().deviceId();
+            long srcPort2 = link2.src().port().toLong();
+            long dstPort2 = link2.dst().port().toLong();
+
+            if (srcDevice1.toString().equals(srcDevice2.toString())
+                    && dstDevice1.toString().equals(dstDevice2.toString())
+                    && srcPort1 == srcPort2 && dstPort1 == dstPort2) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    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<Link>();
+            if (path != null && !path.links().isEmpty()) {
+                sofarLinks.addAll(path.links());
+            }
+            sofarLinks.add(upstreamLink);
+            sofarPath = new DefaultPath(ProviderId.NONE, sofarLinks, 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 Devicees 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<Integer, HashMap<DeviceId, ArrayList<Path>>>();
+
+        for (Integer itrIndx : distanceDeviceMap.keySet()) {
+            HashMap<DeviceId, ArrayList<Path>> swMap = new
+                    HashMap<DeviceId, ArrayList<Path>>();
+            for (DeviceId sw : distanceDeviceMap.get(itrIndx)) {
+                swMap.put(sw, getECMPPaths(sw));
+            }
+            pathGraph.put(itrIndx, swMap);
+        }
+
+        return pathGraph;
+    }
+
+    /**
+     * 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 Devicees learned in multiple Dijkstra
+     *         iterations and corresponding ECMP paths in terms of Devicees to
+     *         be traversed to it from the root Device
+     */
+    public HashMap<Integer, HashMap<DeviceId,
+            ArrayList<ArrayList<DeviceId>>>> getAllLearnedSwitchesAndVia() {
+
+        HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> deviceViaMap =
+                new HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>>();
+
+        for (Integer itrIndx : distanceDeviceMap.keySet()) {
+            HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swMap =
+                    new HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>();
+
+            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 = new DefaultLink(src.providerId(), src.src(),
+                src.dst(), src.type(), src.annotations());
+
+        return defaultLink;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sBuilder = new StringBuilder();
+        for (Device device: srManager.deviceService.getDevices()) {
+            if (device.id() != rootDevice) {
+                sBuilder.append("Paths from" + rootDevice + " to " + device.id() + "\r\n");
+                ArrayList<Path> paths = getECMPPaths(device.id());
+                if (paths != null) {
+                    for (Path path : paths) {
+                        for (Link link : path.links()) {
+                            sBuilder.append(" : " + link.src() + " -> " + link.dst());
+                        }
+                    }
+                }
+            }
+        }
+        return sBuilder.toString();
+    }
+}
+
diff --git a/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
new file mode 100644
index 0000000..3bfb888
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.nio.ByteBuffer;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MPLS;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class IcmpHandler {
+
+    private static Logger log = LoggerFactory.getLogger(IcmpHandler.class);
+    private SegmentRoutingManager srManager;
+    private NetworkConfigHandler config;
+
+    /**
+     * Creates an IcmpHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public IcmpHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.networkConfigHandler);
+    }
+
+    /**
+     * Process incoming ICMP packet.
+     * If it is an ICMP request to router or known host, then sends an ICMP response.
+     * If it is an ICMP packet to known host and forward the packet to the host.
+     * If it is an ICMP packet to unknown host in a subnet, then sends an ARP request
+     * to the subnet.
+     *
+     * @param pkt
+     */
+    public void processPacketIn(InboundPacket pkt) {
+
+        Ethernet ethernet = pkt.parsed();
+        IPv4 ipv4 = (IPv4) ethernet.getPayload();
+
+        ConnectPoint connectPoint = pkt.receivedFrom();
+        DeviceId deviceId = connectPoint.deviceId();
+        Ip4Address destinationAddress =
+                Ip4Address.valueOf(ipv4.getDestinationAddress());
+        Ip4Address gatewayIpAddress = config.getGatewayIpAddress(deviceId);
+        IpPrefix routerIpPrefix = config.getRouterIpAddress(deviceId);
+        Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address();
+
+        // ICMP to the router IP or gateway IP
+        if (((ICMP) ipv4.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST &&
+                (destinationAddress.equals(routerIpAddress) ||
+                        gatewayIpAddress.equals(destinationAddress))) {
+            sendICMPResponse(ethernet, connectPoint);
+            // TODO: do we need to set the flow rule again ??
+
+        // ICMP for any known host
+        } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
+            srManager.ipHandler.forwardPackets(deviceId, destinationAddress);
+
+        // ICMP for an unknown host in the subnet of the router
+        } else if (config.inSameSubnet(deviceId, destinationAddress)) {
+            srManager.arpHandler.sendArpRequest(deviceId, destinationAddress, connectPoint);
+
+        // ICMP for an unknown host
+        } else {
+            log.debug("ICMP request for unknown host {} ", destinationAddress);
+            // Do nothing
+        }
+    }
+
+    private void sendICMPResponse(Ethernet icmpRequest, ConnectPoint outport) {
+
+        Ethernet icmpReplyEth = new Ethernet();
+
+        IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload();
+        IPv4 icmpReplyIpv4 = new IPv4();
+
+        int destAddress = icmpRequestIpv4.getDestinationAddress();
+        icmpReplyIpv4.setDestinationAddress(icmpRequestIpv4.getSourceAddress());
+        icmpReplyIpv4.setSourceAddress(destAddress);
+        icmpReplyIpv4.setTtl((byte) 64);
+        icmpReplyIpv4.setChecksum((short) 0);
+
+        ICMP icmpReply = (ICMP) icmpRequestIpv4.getPayload().clone();
+        icmpReply.setIcmpType(ICMP.TYPE_ECHO_REPLY);
+        icmpReply.setIcmpCode(ICMP.SUBTYPE_ECHO_REPLY);
+        icmpReply.setChecksum((short) 0);
+
+        icmpReplyIpv4.setPayload(icmpReply);
+
+        icmpReplyEth.setPayload(icmpReplyIpv4);
+        icmpReplyEth.setEtherType(Ethernet.TYPE_IPV4);
+        icmpReplyEth.setDestinationMACAddress(icmpRequest.getSourceMACAddress());
+        icmpReplyEth.setSourceMACAddress(icmpRequest.getDestinationMACAddress());
+        icmpReplyEth.setVlanID(icmpRequest.getVlanID());
+
+        Ip4Address destIpAddress = Ip4Address.valueOf(icmpReplyIpv4.getDestinationAddress());
+        Ip4Address destRouterAddress = config.getDestinationRouterAddress(destIpAddress);
+        int sid = config.getMplsId(destRouterAddress);
+        if (sid < 0) {
+            log.warn("Cannot find the Segment ID for {}", destAddress);
+            return;
+        }
+
+        sendPacketOut(outport, icmpReplyEth, sid);
+
+    }
+
+    private void sendPacketOut(ConnectPoint outport, Ethernet payload, int sid) {
+
+        IPv4 ipPacket = (IPv4) payload.getPayload();
+        Ip4Address destIpAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress());
+
+        if (sid == -1 || config.getMplsId(payload.getDestinationMAC()) == 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.warn("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(((IPv4) payload.getPayload()).getTtl());
+            mplsPkt.setPayload(payload.getPayload());
+            payload.setPayload(mplsPkt);
+
+            OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
+                    treatment, ByteBuffer.wrap(payload.serialize()));
+
+            srManager.packetService.emit(packet);
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/segmentrouting/IpHandler.java b/src/main/java/org/onosproject/segmentrouting/IpHandler.java
new file mode 100644
index 0000000..cca8692
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/IpHandler.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.IPv4;
+import org.onlab.packet.Ip4Address;
+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.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+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;
+
+public class IpHandler {
+
+    private static Logger log = LoggerFactory.getLogger(IpHandler.class);
+    private SegmentRoutingManager srManager;
+    private NetworkConfigHandler config;
+    private ConcurrentHashMap<Ip4Address, ConcurrentLinkedQueue<IPv4>> ipPacketQueue;
+
+    /**
+     * Creates an IpHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public IpHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.networkConfigHandler);
+        ipPacketQueue = new ConcurrentHashMap<Ip4Address, ConcurrentLinkedQueue<IPv4>>();
+    }
+
+    /**
+     * 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
+     */
+    public void processPacketIn(InboundPacket pkt) {
+        Ethernet ethernet = pkt.parsed();
+        IPv4 ipv4 = (IPv4) ethernet.getPayload();
+
+        ConnectPoint connectPoint = pkt.receivedFrom();
+        DeviceId deviceId = connectPoint.deviceId();
+        Ip4Address destinationAddress =
+                Ip4Address.valueOf(ipv4.getDestinationAddress());
+
+        // IP packet for know hosts
+        if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
+            forwardPackets(deviceId, destinationAddress);
+
+        // IP packet for unknown host in the subnet of the router
+        } else if (config.inSameSubnet(deviceId, destinationAddress)) {
+            srManager.arpHandler.sendArpRequest(deviceId, destinationAddress, connectPoint);
+
+        // IP packets for unknown host
+        } else {
+            log.debug("ICMP request 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 TPC packets due to out-of-order packet transfer
+        if (ipPacket.getProtocol() == IPv4.PROTOCOL_TCP) {
+            return;
+        }
+
+        Ip4Address destIpAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress());
+
+        if (ipPacketQueue.get(destIpAddress) == null) {
+            ConcurrentLinkedQueue<IPv4> queue = new ConcurrentLinkedQueue<IPv4>();
+            queue.add(ipPacket);
+            ipPacketQueue.put(destIpAddress, queue);
+        } else {
+            ipPacketQueue.get(destIpAddress).add(ipPacket);
+        }
+    }
+
+    /**
+     * Forwards IP packets in the buffer to the destination IP address.
+     * It is called when the controller finds the destination MAC address
+     * via ARP responsees.
+     *
+     * @param deviceId switch device ID
+     * @param destIpAddress destination IP address
+     */
+    public void forwardPackets(DeviceId deviceId, Ip4Address destIpAddress) {
+        for (IPv4 ipPacket : ipPacketQueue.get(destIpAddress)) {
+            Ip4Address destAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress());
+            if (ipPacket != null && config.inSameSubnet(deviceId, destAddress)) {
+                ipPacket.setTtl((byte) (ipPacket.getTtl() - 1));
+                ipPacket.setChecksum((short) 0);
+                for (Host dest: srManager.hostService.getHostsByIp(destIpAddress)) {
+                    Ethernet eth = new Ethernet();
+                    eth.setDestinationMACAddress(dest.mac());
+                    eth.setSourceMACAddress(config.getRouterMacAddress(
+                            deviceId));
+                    eth.setEtherType(Ethernet.TYPE_IPV4);
+                    eth.setPayload(ipPacket);
+
+                    TrafficTreatment treatment = DefaultTrafficTreatment.builder().
+                            setOutput(dest.location().port()).build();
+                    OutboundPacket packet = new DefaultOutboundPacket(deviceId,
+                            treatment, ByteBuffer.wrap(eth.serialize()));
+                    srManager.packetService.emit(packet);
+                }
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/segmentrouting/NetworkConfigHandler.java b/src/main/java/org/onosproject/segmentrouting/NetworkConfigHandler.java
new file mode 100644
index 0000000..2cb5867
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/NetworkConfigHandler.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is temporary class and used only for test.
+ * It will be replaced with "real" Network Config Manager.
+ */
+
+public class NetworkConfigHandler {
+
+    private static Logger log = LoggerFactory.getLogger(NetworkConfigHandler.class);
+    private SegmentRoutingManager srManager;
+    private DeviceConfiguration deviceConfig = new DeviceConfiguration();
+
+    public NetworkConfigHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+    }
+
+    public Ip4Address getGatewayIpAddress(DeviceId deviceId) {
+
+        if (deviceId.uri().equals(URI.create("of:0000000000000001"))) {
+            return Ip4Address.valueOf("10.0.1.128");
+        } else if (deviceId.uri().equals(URI.create("of:0000000000000006"))) {
+            return Ip4Address.valueOf("7.7.7.128");
+        }
+
+        log.warn("No gateway Ip address was found for {}", deviceId);
+        return Ip4Address.valueOf("0.0.0.0");
+    }
+
+    public IpPrefix getRouterIpAddress(DeviceId deviceId) {
+
+        return IpPrefix.valueOf(deviceConfig.getRouterIp(deviceId), 32);
+    }
+
+    public MacAddress getRouterMacAddress(DeviceId deviceId) {
+        return deviceConfig.getDeviceMac(deviceId);
+    }
+
+    public boolean inSameSubnet(DeviceId deviceId, Ip4Address destIp) {
+
+        String subnetInfo = getSubnetInfo(deviceId);
+        if (subnetInfo == null) {
+            return false;
+        }
+
+        IpPrefix prefix = IpPrefix.valueOf(subnetInfo);
+        if (prefix.contains(destIp)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean inSameSubnet(Ip4Address address, int sid) {
+        DeviceId deviceId = deviceConfig.getDeviceId(sid);
+        if (deviceId == null) {
+            log.warn("Cannot find a device for SID {}", sid);
+            return false;
+        }
+
+        String subnetInfo = getSubnetInfo(deviceId);
+        if (subnetInfo == null) {
+            log.warn("Cannot find the subnet info for {}", deviceId);
+            return false;
+        }
+
+        Ip4Prefix subnet = Ip4Prefix.valueOf(subnetInfo);
+        if (subnet.contains(address)) {
+            return true;
+        }
+
+        return false;
+
+    }
+
+    public String getSubnetInfo(DeviceId deviceId) {
+        // TODO : supports multiple subnet
+        if (deviceId.uri().equals(URI.create("of:0000000000000001"))) {
+            return "10.0.1.1/24";
+        } else if (deviceId.uri().equals(URI.create("of:0000000000000006"))) {
+            return "7.7.7.7/24";
+        } else {
+            log.error("Switch {} is not an edge router", deviceId);
+            return null;
+        }
+    }
+
+    public int getMplsId(DeviceId deviceId) {
+        return deviceConfig.getSegmentId(deviceId);
+    }
+
+    public int getMplsId(MacAddress mac) {
+        return deviceConfig.getSegmentId(mac);
+    }
+
+    public int getMplsId(Ip4Address address) {
+        return deviceConfig.getSegmentId(address);
+    }
+
+    public boolean isEcmpNotSupportedInTransit(DeviceId deviceId) {
+        return false;
+    }
+
+    public boolean isTransitRouter(DeviceId deviceId) {
+        return true;
+    }
+
+
+    public boolean isEdgeRouter(DeviceId deviceId) {
+        if (deviceId.uri().equals(URI.create("of:0000000000000001"))
+                || deviceId.uri().equals(URI.create("of:0000000000000006"))) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private List<PortNumber> getPortsToNeighbors(DeviceId deviceId, List<DeviceId> fwdSws) {
+
+        List<PortNumber> portNumbers = Lists.newArrayList();
+
+        Set<Link> links = srManager.linkService.getDeviceEgressLinks(deviceId);
+        for (Link link: links) {
+            for (DeviceId swId: fwdSws) {
+                if (link.dst().deviceId().equals(swId)) {
+                    portNumbers.add(link.src().port());
+                    break;
+                }
+            }
+        }
+
+        return portNumbers;
+    }
+
+    public List<PortNumber> getPortsToDevice(DeviceId deviceId) {
+        List<PortNumber> portNumbers = Lists.newArrayList();
+
+        Set<Link> links = srManager.linkService.getDeviceEgressLinks(deviceId);
+        for (Link link: links) {
+            if (link.dst().deviceId().equals(deviceId)) {
+                portNumbers.add(link.src().port());
+            }
+        }
+
+        return portNumbers;
+    }
+
+
+    public Ip4Address getDestinationRouterAddress(Ip4Address destIpAddress) {
+        // TODO: need to check the subnet info
+        if (destIpAddress.toString().equals("10.0.1.1")) {
+            return Ip4Address.valueOf("192.168.0.1");
+        } else if (destIpAddress.toString().equals("7.7.7.7")) {
+            return Ip4Address.valueOf("192.168.0.6");
+        } else {
+            log.warn("No router was found for {}", destIpAddress);
+            return null;
+        }
+
+    }
+
+    public DeviceId getDeviceId(Ip4Address ip4Address) {
+        return deviceConfig.getDeviceId(ip4Address);
+    }
+
+    public MacAddress getRouterMac(Ip4Address targetAddress) {
+        if (targetAddress.toString().equals("10.0.1.128")) {
+            return MacAddress.valueOf("00:00:00:00:00:01");
+        } else if (targetAddress.toString().equals("7.7.7.128")) {
+            return MacAddress.valueOf("00:00:00:00:00:06");
+        } else {
+            log.warn("Cannot find a router for {}", targetAddress);
+            return null;
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
new file mode 100644
index 0000000..063517e
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.Ip4Address;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+
+import org.onlab.packet.MplsLabel;
+import org.onosproject.grouphandler.NeighborSet;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class RoutingRulePopulator {
+
+    private static final Logger log = LoggerFactory.getLogger(RoutingRulePopulator.class);
+
+    private SegmentRoutingManager srManager;
+    private NetworkConfigHandler config;
+
+    /**
+     * Creates a RoutingRulePopulator object.
+     *
+     * @param srManager
+     */
+    public RoutingRulePopulator(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.networkConfigHandler);
+    }
+
+    /**
+     * Populates IP flow rules for specific hosts directly connected to the switch.
+     *
+     * @param deviceId switch ID to set the rules
+     * @param hostIp host IP address
+     * @param hostMac host MAC address
+     * @param outPort port where the host is connected
+     */
+    public void populateIpRuleForHost(DeviceId deviceId, Ip4Address hostIp,
+                                      MacAddress hostMac, PortNumber outPort) {
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, 32));
+        sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+
+        tbuilder.setEthDst(hostMac)
+                .setEthSrc(config.getRouterMacAddress(deviceId))
+                .setOutput(outPort);
+
+        TrafficTreatment treatment = tbuilder.build();
+        TrafficSelector selector = sbuilder.build();
+
+        FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                srManager.appId, 600, false, FlowRule.Type.IP);
+
+        srManager.flowRuleService.applyFlowRules(f);
+        log.debug("Flow rule {} is set to switch {}", f, deviceId);
+    }
+
+    /**
+     * Populates IP flow rules for the subnets of the destination router.
+     *
+     * @param deviceId switch ID to set the rules
+     * @param subnetInfo subnet information
+     * @param destSw destination switch ID
+     * @param nextHops next hop switch ID list
+     * @return true if all rules are set successfully, false otherwise
+     */
+    public boolean populateIpRuleForSubnet(DeviceId deviceId, String subnetInfo,
+                                           DeviceId destSw, Set<DeviceId> nextHops) {
+
+        List<IpPrefix> subnets = extractSubnet(subnetInfo);
+        for (IpPrefix subnet: subnets) {
+            if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Populates IP flow rules for the router IP address.
+     *
+     * @param deviceId device ID to set the rules
+     * @param ipPrefix the IP address of the destination router
+     * @param destSw device ID of the destination router
+     * @param nextHops next hop switch ID list
+     * @return true if all rules are set successfully, false otherwise
+     */
+    public boolean populateIpRuleForRouter(DeviceId deviceId, IpPrefix ipPrefix,
+                                           DeviceId destSw, Set<DeviceId> nextHops) {
+
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        sbuilder.matchIPDst(ipPrefix);
+        sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+
+        NeighborSet ns = null;
+
+        //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.decNwTtl();
+            ns = new NeighborSet(nextHops);
+        } else {
+            tbuilder.copyTtlOut();
+            ns = new NeighborSet(nextHops, config.getMplsId(destSw));
+        }
+
+        DefaultGroupKey groupKey = (DefaultGroupKey) srManager.getGroupKey(ns);
+        if (groupKey == null) {
+            log.warn("Group key is not found for ns {}", ns);
+            return false;
+        }
+        Group group = srManager.groupService.getGroup(deviceId, groupKey);
+        if (group != null) {
+            tbuilder.group(group.id());
+        } else {
+            log.warn("No group found for NeighborSet {} from {} to {}",
+                    ns, deviceId, destSw);
+            return false;
+        }
+
+        TrafficTreatment treatment = tbuilder.build();
+        TrafficSelector selector = sbuilder.build();
+
+        FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                srManager.appId, 600, false, FlowRule.Type.IP);
+
+        srManager.flowRuleService.applyFlowRules(f);
+        log.debug("IP flow rule {} is set to switch {}", f, deviceId);
+
+        return true;
+    }
+
+
+    /**
+     * Populates MPLS flow rules to all transit routers.
+     *
+     * @param deviceId device ID of the switch to set the rules
+     * @param destSwId destination switch device ID
+     * @param nextHops next hops switch ID list
+     * @return true if all rules are set successfully, false otherwise
+     */
+    public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId, Set<DeviceId> nextHops) {
+
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        Collection<TrafficTreatment> treatments = new ArrayList<>();
+
+        // TODO Handle the case of Bos == false
+        sbuilder.matchMplsLabel(MplsLabel.mplsLabel(config.getMplsId(destSwId)));
+        sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
+
+        //If the next hop is the destination router, do PHP
+        if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
+            TrafficTreatment treatmentBos =
+                    getMplsTreatment(deviceId, destSwId, nextHops, true, true);
+            TrafficTreatment treatment =
+                    getMplsTreatment(deviceId, destSwId, nextHops, true, false);
+            if (treatmentBos != null) {
+                treatments.add(treatmentBos);
+            } else {
+                log.warn("Failed to set MPLS rules.");
+                return false;
+            }
+        } else {
+            TrafficTreatment treatmentBos =
+                    getMplsTreatment(deviceId, destSwId, nextHops, false, true);
+            TrafficTreatment treatment =
+                    getMplsTreatment(deviceId, destSwId, nextHops, false, false);
+
+            if (treatmentBos != null) {
+                treatments.add(treatmentBos);
+            } else {
+                log.warn("Failed to set MPLS rules.");
+                return false;
+            }
+        }
+
+        TrafficSelector selector = sbuilder.build();
+        for (TrafficTreatment treatment: treatments) {
+            FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                    srManager.appId, 600, false, FlowRule.Type.MPLS);
+            srManager.flowRuleService.applyFlowRules(f);
+            log.debug("MPLS rule {} is set to {}", f, deviceId);
+        }
+
+        return true;
+    }
+
+
+    private TrafficTreatment getMplsTreatment(DeviceId deviceId, DeviceId destSw,
+                                             Set<DeviceId> nextHops,
+                                             boolean phpRequired, boolean isBos) {
+
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        if (phpRequired) {
+            tbuilder.copyTtlIn();
+            if (isBos) {
+                tbuilder.popMpls(Ethernet.TYPE_IPV4)
+                        .decNwTtl();
+            } else {
+                tbuilder.popMpls(Ethernet.MPLS_UNICAST)
+                .decMplsTtl();
+            }
+        } else {
+            tbuilder.decMplsTtl();
+        }
+
+        if (config.isEcmpNotSupportedInTransit(deviceId)
+                && config.isTransitRouter(deviceId)) {
+            Link link = selectOneLink(deviceId, nextHops);
+            if (link == null) {
+                log.warn("No link from {} to {}", deviceId, nextHops);
+                return null;
+            }
+            tbuilder.setEthSrc(config.getRouterMacAddress(deviceId))
+                    .setEthDst(config.getRouterMacAddress(link.dst().deviceId()))
+                    .setOutput(link.src().port());
+        } else {
+            NeighborSet ns = new NeighborSet(nextHops);
+            DefaultGroupKey groupKey = (DefaultGroupKey) srManager.getGroupKey(ns);
+            if (groupKey == null) {
+                log.warn("Group key is not found for ns {}", ns);
+                return null;
+            }
+            Group group = srManager.groupService.getGroup(deviceId, groupKey);
+            if (group != null) {
+                tbuilder.group(group.id());
+            } else {
+                log.warn("No group found for ns {} key {} in {}", ns,
+                        srManager.getGroupKey(ns), deviceId);
+                return null;
+            }
+        }
+
+        return tbuilder.build();
+    }
+
+    /**
+     * Populates VLAN flows rules.
+     * All packets are forwarded to TMAC table.
+     *
+     * @param deviceId switch ID to set the rules
+     */
+    public void populateTableVlan(DeviceId deviceId) {
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        tbuilder.transition(FlowRule.Type.ETHER);
+
+        TrafficTreatment treatment = tbuilder.build();
+        TrafficSelector selector = sbuilder.build();
+
+        FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                srManager.appId, 600, false, FlowRule.Type.VLAN);
+
+        srManager.flowRuleService.applyFlowRules(f);
+
+        log.debug("Vlan flow rule {} is set to switch {}", f, deviceId);
+    }
+
+    /**
+     * Populates TMAC table rules.
+     * IP packets are forwarded to IP table.
+     * MPLS packets are forwarded to MPLS table.
+     *
+     * @param deviceId switch ID to set the rules
+     */
+    public void populateTableTMac(DeviceId deviceId) {
+
+        // flow rule for IP packets
+        TrafficSelector selectorIp = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchEthDst(config.getRouterMacAddress(deviceId))
+                .build();
+        TrafficTreatment treatmentIp = DefaultTrafficTreatment.builder()
+                .transition(FlowRule.Type.IP)
+                .build();
+
+        FlowRule flowIp = new DefaultFlowRule(deviceId, selectorIp, treatmentIp, 100,
+                srManager.appId, 600, false, FlowRule.Type.ETHER);
+
+        srManager.flowRuleService.applyFlowRules(flowIp);
+
+        // flow rule for MPLS packets
+        TrafficSelector selectorMpls = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.MPLS_UNICAST)
+                .matchEthDst(config.getRouterMacAddress(deviceId))
+                .build();
+        TrafficTreatment treatmentMpls = DefaultTrafficTreatment.builder()
+                .transition(FlowRule.Type.MPLS)
+                .build();
+
+        FlowRule flowMpls = new DefaultFlowRule(deviceId, selectorMpls, treatmentMpls, 100,
+                srManager.appId, 600, false, FlowRule.Type.ETHER);
+
+        srManager.flowRuleService.applyFlowRules(flowMpls);
+
+    }
+
+    /**
+     * Populates a table miss entry.
+     *
+     * @param deviceId switch ID to set rules
+     * @param tableToAdd table to set the rules
+     * @param toControllerNow flag to send packets to controller immediately
+     * @param toControllerWrite flag to send packets to controller at the end of pipeline
+     * @param toTable flag to send packets to a specific table
+     * @param tableToSend table type to send packets when the toTable flag is set
+     */
+    public void populateTableMissEntry(DeviceId deviceId, FlowRule.Type tableToAdd, boolean toControllerNow,
+                                       boolean toControllerWrite,
+                                       boolean toTable, FlowRule.Type tableToSend) {
+        // TODO: Change arguments to EnumSet
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .build();
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+        if (toControllerNow) {
+            tBuilder.setOutput(PortNumber.CONTROLLER);
+        }
+
+        if (toControllerWrite) {
+            tBuilder.deferred().setOutput(PortNumber.CONTROLLER);
+        }
+
+        if (toTable) {
+            tBuilder.transition(tableToSend);
+        }
+
+        FlowRule flow = new DefaultFlowRule(deviceId, selector, tBuilder.build(), 0,
+                srManager.appId, 600, false, tableToAdd);
+
+        srManager.flowRuleService.applyFlowRules(flow);
+
+    }
+
+
+    private List<IpPrefix> extractSubnet(String subnetInfo) {
+        List<IpPrefix> subnetIpPrefixes = new ArrayList<>();
+
+        // TODO: refactoring required depending on the format of the subnet info
+        IpPrefix prefix = IpPrefix.valueOf(subnetInfo);
+        if (prefix == null) {
+            log.error("Wrong ip prefix type {}", subnetInfo);
+        } else {
+            subnetIpPrefixes.add(prefix);
+        }
+
+        return subnetIpPrefixes;
+    }
+
+    private Link selectOneLink(DeviceId srcId, Set<DeviceId> destIds) {
+
+        Set<Link> links = srManager.linkService.getDeviceEgressLinks(srcId);
+        DeviceId destId = (DeviceId) destIds.toArray()[0];
+        for (Link link: links) {
+            if (link.dst().deviceId().equals(destId)) {
+                return link;
+            }
+        }
+
+        return null;
+    }
+
+}
diff --git a/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
new file mode 100644
index 0000000..a7a3b11
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.Event;
+import org.onosproject.grouphandler.DefaultGroupHandler;
+import org.onosproject.grouphandler.NeighborSet;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupListener;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.net.link.LinkService;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+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;
+
+@SuppressWarnings("ALL")
+@Component(immediate = true)
+public class SegmentRoutingManager {
+
+    private static Logger log = LoggerFactory.getLogger(SegmentRoutingManager.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TopologyService topologyService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentService intentService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected GroupService groupService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    protected NetworkConfigHandler networkConfigHandler = new NetworkConfigHandler(this);
+    protected ArpHandler arpHandler = new ArpHandler(this);
+    protected IcmpHandler icmpHandler = new IcmpHandler(this);
+    protected IpHandler ipHandler = new IpHandler(this);
+    protected RoutingRulePopulator routingRulePopulator = new RoutingRulePopulator(this);
+    protected ApplicationId appId;
+
+    private DefaultRoutingHandler defaultRoutingHandler = new DefaultRoutingHandler(this);
+    private DeviceConfiguration deviceConfiguration = new DeviceConfiguration();
+    private InternalPacketProcessor processor = new InternalPacketProcessor();
+    private InternalEventHandler eventHandler = new InternalEventHandler();
+
+    private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
+
+    private static ScheduledFuture<?> eventHandlerFuture = null;
+    private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>();
+    private Map<DeviceId, DefaultGroupHandler> groupHandlerMap
+            = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>();
+
+    private static int numOfEvents = 0;
+    private static int numOfHandlerExecution = 0;
+    private static int numOfHandlerScheduled = 0;
+
+    @Activate
+    protected void activate() {
+        appId = coreService.registerApplication("org.onosproject.segmentrouting");
+        packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
+        linkService.addListener(new InternalLinkListener());
+        groupService.addListener(new InternalGroupListener());
+        deviceService.addListener(new InternalDeviceListener());
+
+        for (Device device: deviceService.getDevices()) {
+            if (mastershipService.
+                    getLocalRole(device.id()) == MastershipRole.MASTER) {
+                DefaultGroupHandler groupHandler =
+                    DefaultGroupHandler.createGroupHandler(device.id(),
+                            appId, deviceConfiguration, linkService, groupService);
+                groupHandler.createGroups();
+                groupHandlerMap.put(device.id(), groupHandler);
+                log.debug("Initiating default group handling for {}", device.id());
+
+                defaultRoutingHandler.startPopulationProcess();
+            } else {
+                log.debug("Activate: Local role {} "
+                                + "is not MASTER for device {}",
+                        mastershipService.
+                                getLocalRole(device.id()),
+                        device.id());
+            }
+        }
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        packetService.removeProcessor(processor);
+        processor = null;
+        log.info("Stopped");
+    }
+
+    /**
+     * Returns the GrouopKey object for the device and the NighborSet given.
+     *
+     * @param ns NeightborSet object for the GroupKey
+     * @return GroupKey object for the NeighborSet
+     */
+    public GroupKey getGroupKey(NeighborSet ns) {
+
+        for (DefaultGroupHandler groupHandler: groupHandlerMap.values()) {
+            return groupHandler.getGroupKey(ns);
+        }
+
+        return null;
+    }
+
+    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.getEtherType() == Ethernet.TYPE_ARP) {
+                arpHandler.processPacketIn(pkt);
+            } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
+                IPv4 ipPacket = (IPv4) ethernet.getPayload();
+                ipHandler.addToPacketBuffer(ipPacket);
+                if (ipPacket.getProtocol() == IPv4.PROTOCOL_ICMP) {
+                    icmpHandler.processPacketIn(pkt);
+                } else {
+                    ipHandler.processPacketIn(pkt);
+                }
+            }
+        }
+    }
+
+    private class InternalLinkListener implements LinkListener {
+        @Override
+        public void event(LinkEvent event) {
+            if (event.type() == LinkEvent.Type.LINK_ADDED ||
+                    event.type() == LinkEvent.Type.LINK_REMOVED) {
+                scheduleEventHandlerIfNotScheduled(event);
+            }
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+
+        @Override
+        public void event(DeviceEvent event) {
+            if (mastershipService.
+                    getLocalRole(event.subject().id()) != MastershipRole.MASTER) {
+                log.debug("Local role {} is not MASTER for device {}",
+                        mastershipService.
+                                getLocalRole(event.subject().id()),
+                        event.subject().id());
+                return;
+            }
+
+            switch (event.type()) {
+            case DEVICE_ADDED:
+            case PORT_REMOVED:
+                scheduleEventHandlerIfNotScheduled(event);
+                break;
+            default:
+            }
+        }
+    }
+
+    private class InternalGroupListener implements GroupListener {
+
+        @Override
+        public void event(GroupEvent event) {
+            switch (event.type()) {
+                case GROUP_ADDED:
+                    scheduleEventHandlerIfNotScheduled(event);
+                    break;
+                case GROUP_ADD_REQUESTED:
+                    log.info("Group add requested");
+                    break;
+                case GROUP_UPDATED:
+                    break;
+                default:
+                    log.warn("Unhandled group event type: {}", event.type());
+            }
+        }
+    }
+
+    private void scheduleEventHandlerIfNotScheduled(Event event) {
+
+        eventQueue.add(event);
+        numOfEvents++;
+        if (eventHandlerFuture == null ||
+                eventHandlerFuture.isDone()) {
+            eventHandlerFuture = executorService.schedule(eventHandler,
+                    100, TimeUnit.MILLISECONDS);
+            numOfHandlerScheduled++;
+        }
+
+        log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents,
+                numOfHandlerScheduled);
+
+    }
+
+    private class InternalEventHandler implements Runnable {
+
+        public void run() {
+            numOfHandlerExecution++;
+            while (!eventQueue.isEmpty()) {
+                Event event = eventQueue.poll();
+                if (event.type() == LinkEvent.Type.LINK_ADDED) {
+                    processLinkAdded((Link) event.subject());
+                } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
+                    processLinkRemoved((Link) event.subject());
+                } else if (event.type() == GroupEvent.Type.GROUP_ADDED) {
+                    processGroupAdded((Group) event.subject());
+                } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED) {
+                    processDeviceAdded((Device) event.subject());
+                } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
+                    processPortRemoved((Device) event.subject(),
+                            ((DeviceEvent) event).port());
+                } else {
+                    log.warn("Unhandled event type: {}", event.type());
+                }
+            }
+            log.debug("numOfHandlerExecution {} numOfEventHanlderScheduled {} numOfEvents {}",
+                    numOfHandlerExecution, numOfHandlerScheduled, numOfEvents);
+        }
+    }
+
+
+
+    private void processLinkAdded(Link link) {
+        log.debug("A new link {} was added", link.toString());
+
+        if (mastershipService.
+                getLocalRole(link.src().deviceId()) == MastershipRole.MASTER) {
+            DefaultGroupHandler groupHandler =
+                    groupHandlerMap.get(link.src().deviceId());
+            if (groupHandler != null) {
+                groupHandler.linkUp(link);
+            }
+        }
+        defaultRoutingHandler.startPopulationProcess();
+    }
+
+    private void processLinkRemoved(Link link) {
+        log.debug("A link {} was removed", link.toString());
+        defaultRoutingHandler.startPopulationProcess();
+    }
+
+
+    private void processGroupAdded(Group group) {
+        log.debug("A new group with ID {} was added", group.id());
+        defaultRoutingHandler.resumePopulationProcess();
+    }
+
+    private void processDeviceAdded(Device device) {
+        log.debug("A new device with ID {} was added", device.id());
+        defaultRoutingHandler.populateTtpRules(device.id());
+        DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(
+                device.id(), appId, new DeviceConfiguration(), linkService, groupService);
+        dgh.createGroups();
+        groupHandlerMap.put(device.id(), dgh);
+    }
+
+    private void processPortRemoved(Device device, Port port) {
+        log.debug("Port {} was removed", port.toString());
+        DefaultGroupHandler groupHandler =
+                groupHandlerMap.get(device.id());
+        if (groupHandler != null) {
+            groupHandler.portDown(port.number());
+        }
+    }
+}
