diff --git a/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
new file mode 100644
index 0000000..0ac3728
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
@@ -0,0 +1,412 @@
+/*
+ * 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.grouphandler;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+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.link.LinkService;
+import org.slf4j.Logger;
+
+/**
+ * Default ECMP group handler creation module. This
+ * component creates a set of ECMP groups for every neighbor
+ * that this device is connected to based on whether the
+ * current device is an edge device or a transit device.
+ */
+public class DefaultGroupHandler {
+    protected final Logger log = getLogger(getClass());
+
+    protected final DeviceId deviceId;
+    protected final ApplicationId appId;
+    protected final DeviceProperties deviceConfig;
+    protected final List<Integer> allSegmentIds;
+    protected final int nodeSegmentId;
+    protected final boolean isEdgeRouter;
+    protected final MacAddress nodeMacAddr;
+    protected LinkService linkService;
+    protected GroupService groupService;
+
+    protected HashMap<DeviceId, Set<PortNumber>> devicePortMap =
+            new HashMap<DeviceId, Set<PortNumber>>();
+    protected HashMap<PortNumber, DeviceId> portDeviceMap =
+            new HashMap<PortNumber, DeviceId>();
+
+    private GroupListener listener = new InternalGroupListener();
+    protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
+    .register(URI.class)
+    .register(HashSet.class)
+    .register(DeviceId.class)
+    .register(PortNumber.class)
+    .register(NeighborSet.class)
+    .register(PolicyGroupIdentifier.class)
+    .register(PolicyGroupParams.class)
+    .register(GroupBucketIdentifier.class)
+    .register(GroupBucketIdentifier.BucketOutputType.class);
+
+    protected DefaultGroupHandler(DeviceId deviceId,
+                               ApplicationId appId,
+                               DeviceProperties config,
+                               LinkService linkService,
+                               GroupService groupService) {
+        this.deviceId = checkNotNull(deviceId);
+        this.appId = checkNotNull(appId);
+        this.deviceConfig = checkNotNull(config);
+        this.linkService = checkNotNull(linkService);
+        this.groupService = checkNotNull(groupService);
+        allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds());
+        nodeSegmentId = config.getSegmentId(deviceId);
+        isEdgeRouter = config.isEdgeDevice(deviceId);
+        nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
+
+        this.groupService.addListener(listener);
+
+        populateNeighborMaps();
+    }
+
+    /**
+     * Creates a group handler object based on the type of device. If
+     * device is of edge type it returns edge group handler, else it
+     * returns transit group handler.
+     *
+     * @param deviceId device identifier
+     * @param appId application identifier
+     * @param config interface to retrieve the device properties
+     * @param linkService link service object
+     * @param groupService group service object
+     * @return default group handler type
+     */
+    public static DefaultGroupHandler createGroupHandler(DeviceId deviceId,
+                                                  ApplicationId appId,
+                                                  DeviceProperties config,
+                                                  LinkService linkService,
+                                                  GroupService groupService) {
+        if (config.isEdgeDevice(deviceId)) {
+            return new DefaultEdgeGroupHandler(deviceId,
+                                               appId,
+                                               config,
+                                               linkService,
+                                               groupService);
+        } else {
+            return new DefaultTransitGroupHandler(deviceId,
+                                                  appId,
+                                                  config,
+                                                  linkService,
+                                                  groupService);
+        }
+    }
+
+    /**
+     * Creates the auto created groups for this device based on the
+     * current snapshot of the topology.
+     */
+    //Empty implementations to be overridden by derived classes
+    public void createGroups() {
+    }
+
+    /**
+     * Performs group creation or update procedures when a new link
+     * is discovered on this device.
+     *
+     * @param newLink new neighbor link
+     */
+    public void linkUp(Link newLink) {
+
+        if (newLink.type() != Link.Type.DIRECT) {
+            log.warn("linkUp: unknown link type");
+            return;
+        }
+
+
+        if (!newLink.src().deviceId().equals(deviceId)) {
+            log.warn("linkUp: deviceId{} doesn't match with link src{}",
+                     deviceId,
+                     newLink.src().deviceId());
+            return;
+        }
+
+        log.debug("Device {} linkUp at local port {} to neighbor {}",
+                  deviceId, newLink.src().port(), newLink.dst().deviceId());
+        if (devicePortMap.get(newLink.dst().deviceId()) == null) {
+            // New Neighbor
+            newNeighbor(newLink);
+        } else {
+            // Old Neighbor
+            newPortToExistingNeighbor(newLink);
+        }
+    }
+
+    /**
+     * Performs group recovery procedures when a port goes down
+     * on this device.
+     *
+     * @param port port number that has gone down
+     */
+    public void portDown(PortNumber port) {
+        if (portDeviceMap.get(port) == null) {
+            log.warn("portDown: unknown port");
+            return;
+        }
+        log.debug("Device {} portDown {} to neighbor {}",
+                  deviceId, port, portDeviceMap.get(port));
+        Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
+                                                     portDeviceMap.get(port),
+                                                     devicePortMap.keySet());
+        for (NeighborSet ns : nsSet) {
+            // Create the bucket to be removed
+            TrafficTreatment.Builder tBuilder =
+                    DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(port)
+                    .setEthDst(deviceConfig.getDeviceMac(
+                         portDeviceMap.get(port)))
+                    .setEthSrc(nodeMacAddr);
+            if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
+                tBuilder.pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel()));
+            }
+            GroupBucket removeBucket = DefaultGroupBucket.
+                    createSelectGroupBucket(tBuilder.build());
+            GroupBuckets removeBuckets = new GroupBuckets(
+                                               Arrays.asList(removeBucket));
+            log.debug("portDown in device{}: "
+                    + "groupService.removeBucketsFromGroup "
+                    + "for neighborset{}", deviceId, ns);
+            groupService.removeBucketsFromGroup(deviceId,
+                                                getGroupKey(ns),
+                                                removeBuckets,
+                                                getGroupKey(ns),
+                                                appId);
+        }
+
+        devicePortMap.get(portDeviceMap.get(port)).remove(port);
+        portDeviceMap.remove(port);
+    }
+
+    /**
+     * Returns a group associated with the key.
+     *
+     * @param key cookie associated with the group
+     * @return group if found or null
+     */
+    public Group getGroup(GroupKey key) {
+        return groupService.getGroup(deviceId, key);
+    }
+
+    //Empty implementation
+    protected void newNeighbor(Link newLink) {
+    }
+
+    //Empty implementation
+    protected void newPortToExistingNeighbor(Link newLink) {
+    }
+
+    //Empty implementation
+    protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent(
+                                    DeviceId impactedNeighbor,
+                                    Set<DeviceId> updatedNeighbors) {
+        return null;
+    }
+
+    private void populateNeighborMaps() {
+        Set<Link> outgoingLinks = linkService.getDeviceEgressLinks(deviceId);
+        for (Link link:outgoingLinks) {
+            if (link.type() != Link.Type.DIRECT) {
+                continue;
+            }
+            addNeighborAtPort(link.dst().deviceId(), link.src().port());
+        }
+    }
+
+    protected void addNeighborAtPort(DeviceId neighborId, PortNumber portToNeighbor) {
+        // Update DeviceToPort database
+        log.debug("Device {} addNeighborAtPort: neighbor {} at port {}",
+                  deviceId, neighborId, portToNeighbor);
+        if (devicePortMap.get(neighborId) != null) {
+            devicePortMap.get(neighborId).add(portToNeighbor);
+        } else {
+            Set<PortNumber> ports = new HashSet<PortNumber>();
+            ports.add(portToNeighbor);
+            devicePortMap.put(neighborId, ports);
+        }
+
+        // Update portToDevice database
+        if (portDeviceMap.get(portToNeighbor) == null) {
+            portDeviceMap.put(portToNeighbor, neighborId);
+        }
+    }
+
+    protected Set<Set<DeviceId>>
+            getPowerSetOfNeighbors(Set<DeviceId> neighbors) {
+        List<DeviceId> list = new ArrayList<DeviceId>(neighbors);
+        Set<Set<DeviceId>> sets = new HashSet<Set<DeviceId>>();
+        // get the number of elements in the neighbors
+        int elements = list.size();
+        // the number of members of a power set is 2^n
+        // including the empty set
+        int powerElements = (1 << elements);
+
+        // run a binary counter for the number of power elements
+        // NOTE: Exclude empty set
+        for (long i = 1; i < powerElements; i++) {
+            Set<DeviceId> neighborSubSet = new HashSet<DeviceId>();
+            for (int j = 0; j < elements; j++) {
+                if ((i >> j) % 2 == 1) {
+                    neighborSubSet.add(list.get(j));
+                }
+            }
+            sets.add(neighborSubSet);
+        }
+        return sets;
+    }
+
+    private boolean isSegmentIdSameAsNodeSegmentId(DeviceId deviceId, int sId) {
+        return (deviceConfig.getSegmentId(deviceId) == sId);
+    }
+
+    protected List<Integer> getSegmentIdsTobePairedWithNeighborSet(
+                                   Set<DeviceId> neighbors) {
+
+        List<Integer> nsSegmentIds = new ArrayList<Integer>();
+
+        // Always pair up with no edge label
+        //If (neighbors.size() == 1) {
+        nsSegmentIds.add(-1);
+        //}
+
+        // Filter out SegmentIds matching with the
+        // nodes in the combo
+        for (Integer sId : allSegmentIds) {
+            if (sId.equals(nodeSegmentId)) {
+                continue;
+            }
+            boolean filterOut = false;
+            // Check if the edge label being set is of
+            // any node in the Neighbor set
+            for (DeviceId deviceId : neighbors) {
+                if (isSegmentIdSameAsNodeSegmentId(deviceId, sId)) {
+                    filterOut = true;
+                    break;
+                }
+            }
+            if (!filterOut) {
+                nsSegmentIds.add(sId);
+            }
+        }
+        return nsSegmentIds;
+    }
+
+    protected void createGroupsFromNeighborsets(Set<NeighborSet> nsSet) {
+        for (NeighborSet ns : nsSet) {
+            // Create the bucket array from the neighbor set
+            List<GroupBucket> buckets = new ArrayList<GroupBucket>();
+            for (DeviceId d : ns.getDeviceIds()) {
+                for (PortNumber sp : devicePortMap.get(d)) {
+                    TrafficTreatment.Builder tBuilder =
+                            DefaultTrafficTreatment.builder();
+                    tBuilder.setOutput(sp)
+                            .setEthDst(deviceConfig.getDeviceMac(d))
+                            .setEthSrc(nodeMacAddr);
+                    if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
+                        tBuilder.pushMpls()
+                                .setMpls(MplsLabel.
+                                         mplsLabel(ns.getEdgeLabel()));
+                    }
+                    buckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                                                                tBuilder.build()));
+                }
+            }
+            GroupBuckets groupBuckets = new GroupBuckets(buckets);
+            GroupDescription newGroupDesc = new DefaultGroupDescription(
+                                      deviceId,
+                                      Group.Type.SELECT,
+                                      groupBuckets,
+                                      getGroupKey(ns),
+                                      appId);
+            log.debug("createGroupsFromNeighborsets: "
+                    + "groupService.addGroup for neighborset{}", ns);
+            groupService.addGroup(newGroupDesc);
+        }
+    }
+
+    protected void handleGroupEvent(GroupEvent event) {
+        switch (event.type()) {
+        case GROUP_ADDED:
+            log.debug("Received GROUP_ADDED from group service "
+                    + "for device {} with group key{} with id{}",
+                      event.subject().deviceId(),
+                      event.subject().appCookie(),
+                      event.subject().id());
+            break;
+        case GROUP_UPDATED:
+            log.trace("Received GROUP_UPDATED from group service "
+                    + "for device {} with group key{} with id{}",
+                      event.subject().deviceId(),
+                      event.subject().appCookie(),
+                      event.subject().id());
+            break;
+        case GROUP_REMOVED:
+            log.debug("Received GROUP_REMOVED from group service "
+                    + "for device {} with group key{} with id{}",
+                      event.subject().deviceId(),
+                      event.subject().appCookie(),
+                      event.subject().id());
+            break;
+        default:
+            break;
+        }
+    }
+
+    private class InternalGroupListener implements GroupListener {
+
+        @Override
+        public void event(GroupEvent event) {
+            handleGroupEvent(event);
+        }
+    }
+
+    public GroupKey getGroupKey(Object obj) {
+        return new DefaultGroupKey(kryo.build().serialize(obj));
+    }
+
+}
