diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicy.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicy.java
new file mode 100644
index 0000000..d795d61
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicy.java
@@ -0,0 +1,64 @@
+package net.onrc.onos.apps.segmentrouting;
+
+import net.onrc.onos.core.matchaction.match.PacketMatch;
+
+public class SegmentRoutingPolicy {
+
+    /**
+     * Enums for policy type
+     *
+     */
+    public enum PolicyType{
+        TUNNEL_FLOW,
+        LOADBALANCE,
+        AVOID,
+        DENY
+    }
+
+    protected SegmentRoutingManager srManager;
+    protected String policyId;
+    protected PacketMatch match;
+    protected int priority;
+    protected PolicyType type;
+
+    public SegmentRoutingPolicy(SegmentRoutingManager srm, String pid,
+            PolicyType type, PacketMatch match, int priority) {
+        this.srManager = srm;
+        this.policyId = pid;
+        this.match = match;
+        this.priority = priority;
+        this.type = type;
+    }
+
+    public SegmentRoutingPolicy(String pid, PacketMatch match, int priority) {
+        this.policyId = pid;
+        this.match = match;
+        this.priority = priority;
+        this.type = PolicyType.TUNNEL_FLOW;
+    }
+
+    public String getPolicyId(){
+        return this.policyId;
+    }
+
+    public PacketMatch getMatch(){
+        return this.match;
+    }
+
+    public int getPriority(){
+        return this.priority;
+    }
+
+    public PolicyType getType(){
+        return this.type;
+    }
+
+    public boolean createPolicy() {
+        return false;
+    }
+
+    public boolean removePolicy() {
+        return false;
+    }
+
+}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicyTunnel.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicyTunnel.java
new file mode 100644
index 0000000..91f3d29
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicyTunnel.java
@@ -0,0 +1,136 @@
+package net.onrc.onos.apps.segmentrouting;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.floodlightcontroller.core.IOF13Switch;
+import net.onrc.onos.apps.segmentrouting.SegmentRoutingTunnel.TunnelRouteInfo;
+import net.onrc.onos.core.matchaction.MatchAction;
+import net.onrc.onos.core.matchaction.MatchActionId;
+import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
+import net.onrc.onos.core.matchaction.MatchActionOperations.Operator;
+import net.onrc.onos.core.matchaction.action.Action;
+import net.onrc.onos.core.matchaction.action.DecNwTtlAction;
+import net.onrc.onos.core.matchaction.action.GroupAction;
+import net.onrc.onos.core.matchaction.match.PacketMatch;
+import net.onrc.onos.core.util.SwitchPort;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.esotericsoftware.minlog.Log;
+
+public class SegmentRoutingPolicyTunnel extends SegmentRoutingPolicy {
+
+    private static final Logger log = LoggerFactory
+            .getLogger(SegmentRoutingPolicyTunnel.class);
+
+    private String tunnelId;
+
+    public SegmentRoutingPolicyTunnel(SegmentRoutingManager srm, String pid,
+            PolicyType type, PacketMatch match, int priority, String tid) {
+        super(srm, pid, type, match, priority);
+        this.tunnelId = tid;
+        // TODO Auto-generated constructor stub
+    }
+
+    @Override
+    public boolean createPolicy() {
+
+        SegmentRoutingTunnel tunnelInfo = srManager.getTunnelInfo(tunnelId);
+
+        List<TunnelRouteInfo> routes = tunnelInfo.getRoutes();
+
+        for (TunnelRouteInfo route : routes) {
+            List<Action> actions = new ArrayList<>();
+
+            // Check PHP was done by stitching
+            // If no MPLS label is added, then NW TTL needs to be decremented
+            if (route.getRoute().isEmpty()) {
+                DecNwTtlAction decNwTtlAction = new DecNwTtlAction(1);
+                actions.add(decNwTtlAction);
+            }
+
+            GroupAction groupAction = new GroupAction();
+            groupAction.setGroupId(route.getGroupId());
+            actions.add(groupAction);
+
+            MatchAction matchAction = new MatchAction(new MatchActionId(
+                    srManager.getNextMatchActionID()),
+                    new SwitchPort((long) 0, (short) 0), match, priority,
+                    actions);
+            MatchActionOperationEntry maEntry =
+                    new MatchActionOperationEntry(Operator.ADD, matchAction);
+
+            IOF13Switch sw13 = srManager.getIOF13Switch(route.getSrcSwDpid());
+
+            if (sw13 != null) {
+                srManager.printMatchActionOperationEntry(sw13, maEntry);
+                try {
+                    sw13.pushFlow(maEntry);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    return false;
+                }
+            }
+            else {
+                Log.warn("Cannot find the target switch {}", route.getSrcSwDpid());
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean removePolicy() {
+
+        List<Action> actions = new ArrayList<>();
+        int gropuId = 0; // dummy group ID
+        GroupAction groupAction = new GroupAction();
+        groupAction.setGroupId(gropuId);
+        actions.add(groupAction);
+
+        MatchAction matchAction = new MatchAction(new MatchActionId(
+                srManager.getNextMatchActionID()),
+                new SwitchPort((long) 0, (short) 0), match, priority,
+                actions);
+        MatchActionOperationEntry maEntry =
+                new MatchActionOperationEntry(Operator.REMOVE, matchAction);
+
+        SegmentRoutingTunnel tunnel = srManager.getTunnelInfo(tunnelId);
+        if (tunnel == null) {
+            log.warn("Cannot find the tunnel {} for the policy {}", tunnelId,
+                    policyId);
+            return false;
+        }
+        List<TunnelRouteInfo> routes = tunnel.getRoutes();
+
+        for (TunnelRouteInfo route : routes) {
+            IOF13Switch sw13 = srManager.getIOF13Switch(route.getSrcSwDpid());
+            if (sw13 == null) {
+                log.warn("Cannt find the switch {}", route.getSrcSwDpid());
+                return false;
+            }
+            else {
+                srManager.printMatchActionOperationEntry(sw13, maEntry);
+                try {
+                    sw13.pushFlow(maEntry);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    log.debug("policy remove failed due to pushFlow() exception");
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+
+    public String getTunnelId(){
+        return this.tunnelId;
+    }
+
+}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingTunnel.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingTunnel.java
new file mode 100644
index 0000000..9eea762
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingTunnel.java
@@ -0,0 +1,510 @@
+package net.onrc.onos.apps.segmentrouting;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.floodlightcontroller.core.IOF13Switch;
+import net.floodlightcontroller.core.IOF13Switch.NeighborSet;
+import net.onrc.onos.core.drivermanager.OFSwitchImplDellOSR;
+import net.onrc.onos.core.topology.Link;
+import net.onrc.onos.core.topology.Switch;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SegmentRoutingTunnel {
+
+    private static final Logger log = LoggerFactory
+            .getLogger(SegmentRoutingTunnel.class);
+
+    private String tunnelId;
+    private List<Integer> labelIds;
+    private List<TunnelRouteInfo> routes;
+    private SegmentRoutingManager srManager;
+
+    private final int MAX_NUM_LABELS = 3;
+
+    public SegmentRoutingTunnel(SegmentRoutingManager srm, String tid,
+            List<Integer> labelIds) {
+        this.srManager = srm;
+        this.tunnelId = tid;
+        this.labelIds = labelIds;
+        this.routes = new ArrayList<TunnelRouteInfo>();
+    }
+
+    public String getTunnelId(){
+        return this.tunnelId;
+    }
+
+    public List<Integer> getLabelids() {
+        return this.labelIds;
+    }
+
+    public List<TunnelRouteInfo> getRoutes(){
+        return this.routes;
+    }
+
+    public boolean createTunnel() {
+
+        if (labelIds.isEmpty() || labelIds.size() < 2) {
+            log.debug("Wrong tunnel information");
+            return false;
+        }
+
+        List<String> Ids = new ArrayList<String>();
+        for (Integer label : labelIds) {
+            Ids.add(label.toString());
+        }
+
+        List<TunnelRouteInfo> stitchingRule = getStitchingRule(Ids);
+        if (stitchingRule == null) {
+            log.debug("Failed to get a tunnel rule.");
+            return false;
+        }
+
+        for (TunnelRouteInfo route: stitchingRule) {
+            NeighborSet ns = new NeighborSet();
+            for (Dpid dpid: route.getFwdSwDpid())
+                ns.addDpid(dpid);
+
+            printTunnelInfo(route.srcSwDpid, tunnelId, route.getRoute(), ns);
+            int groupId = -1;
+            if ((groupId =createGroupsForTunnel(tunnelId, route, ns)) < 0) {
+                log.debug("Failed to create a tunnel at driver.");
+                return false;
+            }
+            route.setGroupId(groupId);
+        }
+
+        this.routes = stitchingRule;
+
+        return true;
+    }
+
+    public boolean removeTunnel() {
+
+        for (TunnelRouteInfo route: routes) {
+            IOF13Switch sw13 = srManager.getIOF13Switch(route.srcSwDpid);
+            if (sw13 == null) {
+                log.warn("Cannot find the switch", route.srcSwDpid);
+                return false;
+            }
+            else {
+                if (!sw13.removeGroup(route.getGroupId())) {
+                    log.warn("Faied to remove the tunnel {} at driver",
+                            tunnelId);
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Create groups for the tunnel
+     *
+     * @param tunnelId tunnel ID
+     * @param routeInfo label stacks for the tunnel
+     * @param ns NeighborSet to forward packets
+     * @return group ID, return -1 if it fails
+     */
+    private int createGroupsForTunnel(String tunnelId, TunnelRouteInfo routeInfo,
+            NeighborSet ns) {
+
+        IOF13Switch targetSw = srManager.getIOF13Switch(routeInfo.srcSwDpid);
+
+        if (targetSw == null) {
+            log.debug("Switch {} is gone.", routeInfo.srcSwDpid);
+            return -1;
+        }
+
+        List<Integer> Ids = new ArrayList<Integer>();
+        for (String IdStr: routeInfo.route)
+            Ids.add(Integer.parseInt(IdStr));
+
+        List<PortNumber> ports = getPortsFromNeighborSet(routeInfo.srcSwDpid, ns);
+        int groupId = targetSw.createGroup(Ids, ports);
+
+        return groupId;
+    }
+
+
+    /**
+     * Split the nodes IDs into multiple tunnel if Segment Stitching is required.
+     * We assume that the first node ID is the one of source router, and the last
+     * node ID is that of the destination router.
+     *
+     * @param route list of node IDs
+     * @return List of the TunnelRoutInfo
+     */
+    private List<TunnelRouteInfo> getStitchingRule(List<String> route) {
+
+        if (route.isEmpty() || route.size() < 3)
+            return null;
+
+        List<TunnelRouteInfo> rules = new ArrayList<TunnelRouteInfo>();
+
+        Switch srcSw = srManager.getSwitchFromNodeId(route.get(0));
+        if (srcSw == null) {
+            log.warn("Switch is not found for Node SID {}", route.get(0));
+            return null;
+        }
+        String srcDpid = srcSw.getDpid().toString();
+
+        int i = 0;
+        TunnelRouteInfo routeInfo = new TunnelRouteInfo();
+        boolean checkNeighbor = false;
+        String prevAdjacencySid = null;
+        String prevNodeId = null;
+
+        for (String nodeId: route) {
+            // The first node ID is always the source router.
+            // We assume that the first ID cannot be an Adjacency SID.
+            if (i == 0) {
+                srcSw = srManager.getSwitchFromNodeId(nodeId);
+                if (srcDpid == null)
+                    srcDpid = srcSw.getDpid().toString();
+                routeInfo.setSrcDpid(srcDpid);
+                checkNeighbor = true;
+                i++;
+            }
+            // if this is the first node ID to put the label stack..
+            else if (i == 1) {
+                if (checkNeighbor) {
+                    List<Dpid> fwdSws = getDpidIfNeighborOf(nodeId, srcSw);
+                    // if nodeId is NOT the neighbor of srcSw..
+                    if (fwdSws.isEmpty()) {
+                        fwdSws = srManager.getForwardingSwitchForNodeId(srcSw,nodeId);
+                        if (fwdSws == null || fwdSws.isEmpty()) {
+                            log.warn("There is no route from node {} to node {}",
+                                    srcSw.getDpid(), nodeId);
+                            return null;
+                        }
+                        routeInfo.addRoute(nodeId);
+                        i++;
+                    }
+                    routeInfo.setFwdSwDpid(fwdSws);
+                    // we check only the next node ID of the source router
+                    checkNeighbor = false;
+                }
+                // if neighbor check is already done, then just add it
+                else  {
+                    routeInfo.addRoute(nodeId);
+                    i++;
+                }
+            }
+            // if i > 1
+            else {
+                // If the adjacency SID is pushed and the next SID is the destination
+                // of the adjacency SID, then do not add the SID.
+                if (prevAdjacencySid != null) {
+                    if (isAdjacencySidNeighborOf(prevNodeId, prevAdjacencySid, nodeId)) {
+                        prevAdjacencySid = null;
+                        prevNodeId = nodeId;
+                        continue;
+                    }
+                    prevAdjacencySid = null;
+                }
+                routeInfo.addRoute(nodeId);
+                i++;
+            }
+
+            // If the adjacency ID is added the label stack,
+            // then we need to check if the next node is the destination of the adjacency SID
+            if (srManager.isAdjacencySid(nodeId))
+                prevAdjacencySid = nodeId;
+
+            // If the number of labels reaches the limit, start over the procedure
+            if (i == MAX_NUM_LABELS +1) {
+
+                rules.add(routeInfo);
+                routeInfo = new TunnelRouteInfo();
+
+                if (srManager.isAdjacencySid(nodeId)) {
+                    // If the previous sub tunnel finishes with adjacency SID,
+                    // then we need to start the procedure from the adjacency
+                    // destination ID.
+                    List<Switch> destNodeList =
+                            getAdjacencyDestinationNode(prevNodeId, nodeId);
+                    if (destNodeList == null || destNodeList.isEmpty()) {
+                        log.warn("Cannot find destination node for adjacencySID {}",
+                                nodeId);
+                        return null;
+                    }
+                    // If the previous sub tunnel finishes with adjacency SID with
+                    // multiple ports, then we need to remove the adjacency Sid
+                    // from the previous sub tunnel and start the new sub tunnel
+                    // with the adjacency Sid. Technically, the new subtunnel
+                    // forward packets to the port assigned to the adjacency Sid
+                    // and the label stack starts with the next ID.
+                    // This is to avoid to install new policy rule to multiple nodes for stitching when the
+                    // adjacency Sid that has more than one port.
+                    if (destNodeList.size() > 1) {
+                        rules.get(rules.size()-1).route.remove(nodeId);
+                        srcSw = srManager.getSwitchFromNodeId(prevNodeId);
+                        List<Dpid> fwdSws = getDpidIfNeighborOf(nodeId, srcSw);
+                        routeInfo.setFwdSwDpid(fwdSws);
+                        routeInfo.setSrcDpid(srcSw.getDpid().toString());
+                        i = 1;
+                        checkNeighbor = false;
+                        continue;
+                    }
+                    else {
+                        srcSw = destNodeList.get(0);
+                    }
+                }
+                else {
+                    srcSw = srManager.getSwitchFromNodeId(nodeId);
+                }
+                srcDpid = srcSw.getDpid().toString();
+                routeInfo.setSrcDpid(srcDpid);
+                i = 1;
+                checkNeighbor = true;
+            }
+
+            if (prevAdjacencySid == null)
+                prevNodeId = nodeId;
+        }
+
+
+        if (i < MAX_NUM_LABELS+1 && (routeInfo.getFwdSwDpid() != null &&
+                !routeInfo.getFwdSwDpid().isEmpty())) {
+            rules.add(routeInfo);
+            // NOTE: empty label stack can happen, but forwarding destination should be set
+        }
+
+        return rules;
+    }
+
+
+    /**
+     * Get port numbers of the neighbor set.
+     * If ECMP in transit router is not supported, then only one port should be returned
+     * regardless of number of nodes in neighbor set.
+     *
+     * @param srcSwDpid source switch
+     * @param ns Neighbor set of the switch
+     * @return List of PortNumber, null if not found
+     */
+    private List<PortNumber> getPortsFromNeighborSet(String srcSwDpid, NeighborSet ns) {
+
+        List<PortNumber> portList = new ArrayList<PortNumber>();
+        Switch srcSwitch = srManager.getSwitch(srcSwDpid);
+        if (srcSwitch == null)
+            return null;
+        IOF13Switch srcSwitch13 =
+                srManager.getIOF13Switch(srcSwitch.getDpid().toString());
+
+        for (Dpid neighborDpid: ns.getDpids()) {
+            if (srcSwitch13 instanceof OFSwitchImplDellOSR &&
+                    ns.getDpids().size() == 1) {
+                Switch dstSwitch = srManager.getSwitch(neighborDpid.toString());
+                if (srManager.isTransitRouter(srcSwitch) &&
+                        srManager.isTransitRouter(dstSwitch)) {
+                    Link link = srcSwitch.getLinkToNeighbor(neighborDpid);
+                    portList.add(link.getSrcPort().getNumber());
+                    break;
+                }
+            }
+            else {
+                for (Link link: srcSwitch.getOutgoingLinks()) {
+                    if (link.getDstSwitch().getDpid().equals(neighborDpid)) {
+                        portList.add(link.getSrcPort().getNumber());
+                    }
+                }
+            }
+        }
+
+        return portList;
+    }
+
+
+    /**
+     * Get the DPID of the router with node ID IF the node ID is the neighbor of the
+     * Switch srcSW.
+     * If the nodeId is the adjacency Sid, then it returns the destination router DPIDs.
+     *
+     * @param nodeId Node ID to check
+     * @param srcSw target Switch
+     * @return List of DPID of nodeId, empty list if the nodeId is not the neighbor of srcSW
+     */
+    private List<Dpid> getDpidIfNeighborOf(String nodeId, Switch srcSw) {
+        List<Dpid> fwdSws = new ArrayList<Dpid>();
+        // if the nodeID is the adjacency ID, then we need to regard it as the
+        // neighbor node ID and need to return the destination router DPID(s)
+        if (srManager.isAdjacencySid(nodeId)) {
+            String srcNodeId = srManager.getMplsLabel(srcSw.getDpid().toString());
+            List<Integer> ports =
+                    srManager.getAdacencyPorts(Integer.parseInt(srcNodeId),
+                            Integer.parseInt(nodeId));
+
+            for (Integer port: ports) {
+                for (Link link: srcSw.getOutgoingLinks()) {
+                    if (link.getSrcPort().getPortNumber().value() == port) {
+                        fwdSws.add(link.getDstSwitch().getDpid());
+                    }
+                }
+            }
+        }
+        else {
+            List<Dpid> fwdSwDpids =
+                    srManager.getForwardingSwitchForNodeId(srcSw,nodeId);
+            if (fwdSwDpids == null || fwdSwDpids.isEmpty()) {
+                log.warn("There is no route from node {} to node {}",
+                        srcSw.getDpid(), nodeId);
+                return fwdSws;
+            }
+
+            for (Dpid dpid: fwdSwDpids) {
+                String id = srManager.getMplsLabel(dpid.toString()).toString();
+                if (id.equals(nodeId)) {
+                    fwdSws.add(dpid);
+                    break;
+                }
+            }
+        }
+
+        return fwdSws;
+    }
+
+
+
+    /**
+     * Check whether the router with preNodeid is connected to the router
+     * with nodeId via adjacencySid or not
+     *
+     * @param prevNodeId the router node ID of the adjacencySid
+     * @param adjacencySid adjacency SID
+     * @param nodeId the router node ID to check
+     * @return
+     */
+    private boolean isAdjacencySidNeighborOf(String prevNodeId, String adjacencySid, String nodeId) {
+
+        List<Integer> ports =
+                srManager.getAdacencyPorts(Integer.valueOf(prevNodeId),
+                        Integer.valueOf(adjacencySid));
+
+        if (ports == null) {
+            log.warn("Cannot find ports for node ID {} and adjacencySID ",
+                    prevNodeId, adjacencySid);
+            return false;
+        }
+
+        for (Integer port: ports) {
+            Switch sw = srManager.getSwitchFromNodeId(prevNodeId);
+            for (Link link: sw.getOutgoingLinks()) {
+                if (link.getSrcPort().getPortNumber().value() == port) {
+                    String linkDstDpid = link.getDstPort().getDpid().toString();
+                    String linkDstId = srManager.getMplsLabel(linkDstDpid);
+                    if (linkDstId.equals(nodeId)) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+
+    /**
+     * Get the destination Nodes of the adjacency Sid
+     *
+     * @param nodeId  node ID of the adjacency Sid
+     * @param adjacencySid  adjacency Sid
+     * @return List of Switch, empty list if not found
+     */
+    private List<Switch> getAdjacencyDestinationNode(String nodeId, String adjacencySid) {
+        List<Switch> dstSwList = new ArrayList<Switch>();
+
+        List<Integer> ports = srManager.getAdacencyPorts(Integer.valueOf(nodeId),
+                Integer.valueOf(adjacencySid));
+
+        Switch srcSw = srManager.getSwitchFromNodeId(nodeId);
+        for (Integer port: ports) {
+            for (Link link: srcSw.getOutgoingLinks()) {
+                if (link.getSrcPort().getPortNumber().value() == port) {
+                    dstSwList.add(link.getDstSwitch());
+                }
+            }
+        }
+
+        return dstSwList;
+
+    }
+
+
+
+
+    /**
+     * print tunnel info - used only for debugging.
+     * @param targetSw
+     *
+     * @param fwdSwDpids
+     * @param ids
+     * @param tunnelId
+     */
+    private void printTunnelInfo(String targetSw, String tunnelId,
+            List<String> ids, NeighborSet ns) {
+        StringBuilder logStr = new StringBuilder("In switch " +
+                targetSw + ", create a tunnel " + tunnelId + " " + " of push ");
+        for (String id: ids)
+            logStr.append(id + "-");
+        logStr.append(" output to ");
+        for (Dpid dpid: ns.getDpids())
+            logStr.append(dpid + " - ");
+
+        log.debug(logStr.toString());
+
+    }
+
+    public class TunnelRouteInfo {
+
+        private String srcSwDpid;
+        private List<Dpid> fwdSwDpids;
+        private List<String> route;
+        private int gropuId;
+
+        public TunnelRouteInfo() {
+            fwdSwDpids = new ArrayList<Dpid>();
+            route = new ArrayList<String>();
+        }
+
+        private void setSrcDpid(String dpid) {
+            this.srcSwDpid = dpid;
+        }
+
+        private void setFwdSwDpid(List<Dpid> dpid) {
+            this.fwdSwDpids = dpid;
+        }
+
+        private void addRoute(String id) {
+            route.add(id);
+        }
+
+        private void setGroupId(int groupId) {
+            this.gropuId = groupId;
+        }
+
+        public String getSrcSwDpid() {
+            return this.srcSwDpid;
+        }
+
+        public List<Dpid> getFwdSwDpid() {
+            return this.fwdSwDpids;
+        }
+
+        public List<String> getRoute() {
+            return this.route;
+        }
+
+        public int getGroupId() {
+            return this.gropuId;
+        }
+    }
+
+}
