[ONOS-700][ONOS-1801]refactor tunnel subsystem api.
1.use more abstract and more flexible entity[TunnelPoint] to represent
for source or destination point of tunnel,instead of Label
2.suport for muti-producer
3.use Order entity to record tunnel-order relationship
4.modify Tunnel entity to add more properties.
5.rename Label and LabelId to OpticalTunnelPoint and OpticalLogicId in
order to keep code style consistently,at the same time
OpticalTunnelPoint implements TunnelPoint
6.add junit test

Change-Id: I371afcef5501e468a43758c5982e7a93b443b114
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/DefaultLabel.java b/core/api/src/main/java/org/onosproject/net/tunnel/DefaultOpticalTunnelEndPoint.java
similarity index 61%
rename from core/api/src/main/java/org/onosproject/net/tunnel/DefaultLabel.java
rename to core/api/src/main/java/org/onosproject/net/tunnel/DefaultOpticalTunnelEndPoint.java
index c164515..3fb2e7d 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/DefaultLabel.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/DefaultOpticalTunnelEndPoint.java
@@ -1,5 +1,6 @@
 package org.onosproject.net.tunnel;
 
+import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.MoreObjects.toStringHelper;
 
 import java.util.Objects;
@@ -12,43 +13,46 @@
 import org.onosproject.net.provider.ProviderId;
 
 /**
- * Default label model implementation.
+ * Default optical tunnel point model implementation.
  */
-public class DefaultLabel extends AbstractModel implements Label {
+public class DefaultOpticalTunnelEndPoint extends AbstractModel implements OpticalTunnelEndPoint {
     private final Optional<ElementId> elementId;
     private final Optional<PortNumber> portNumber;
-    private final Optional<Label> parentLabel;
+    private final Optional<OpticalTunnelEndPoint> parentPoint;
     private final Type type;
-    private final LabelId id;
+    private final OpticalLogicId id;
     private final boolean isGlobal;
 
     /**
-     * Creates a label attributed to the specified provider (may be null).
-     * if provider is null, which means the label is not managed by the SB.
+     * Creates a optical tunnel point attributed to the specified provider (may be null).
+     * if provider is null, which means the optical tunnel point is not managed by the SB.
      *
      * @param providerId  tunnelProvider Id
      * @param elementId   parent network element
      * @param number      port number
-     * @param parentLabel parent port or parent label
+     * @param parentPoint parent port or parent label
      * @param type        port type
      * @param id          LabelId
      * @param isGlobal    indicator whether the label is global significant or not
      * @param annotations optional key/value annotations
      */
-    public DefaultLabel(ProviderId providerId, Optional<ElementId> elementId,
-                        Optional<PortNumber> number, Optional<Label> parentLabel,
-                        Type type, LabelId id, boolean isGlobal, Annotations... annotations) {
+    public DefaultOpticalTunnelEndPoint(ProviderId providerId, Optional<ElementId> elementId,
+                        Optional<PortNumber> number, Optional<OpticalTunnelEndPoint> parentPoint,
+                        Type type, OpticalLogicId id, boolean isGlobal, Annotations... annotations) {
         super(providerId, annotations);
+        checkNotNull(type, "type cannot be null");
+        checkNotNull(id, "id cannot be null");
+        checkNotNull(isGlobal, "isGlobal cannot be null");
         this.elementId = elementId;
         this.portNumber = number;
-        this.parentLabel = parentLabel;
+        this.parentPoint = parentPoint;
         this.id = id;
         this.type = type;
         this.isGlobal = isGlobal;
     }
 
     @Override
-    public LabelId id() {
+    public OpticalLogicId id() {
         return id;
     }
 
@@ -63,8 +67,8 @@
     }
 
     @Override
-    public Optional<Label> parentLabel() {
-        return parentLabel;
+    public Optional<OpticalTunnelEndPoint> parentPoint() {
+        return parentPoint;
     }
 
     @Override
@@ -79,7 +83,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(elementId, portNumber, parentLabel, id);
+        return Objects.hash(elementId, portNumber, parentPoint, id);
     }
 
     @Override
@@ -87,14 +91,14 @@
         if (this == obj) {
             return true;
         }
-        if (obj instanceof DefaultLabel) {
-            final DefaultLabel other = (DefaultLabel) obj;
+        if (obj instanceof DefaultOpticalTunnelEndPoint) {
+            final DefaultOpticalTunnelEndPoint other = (DefaultOpticalTunnelEndPoint) obj;
             return Objects.equals(this.id, other.id) &&
                    Objects.equals(this.type, other.type) &&
                    Objects.equals(this.isGlobal, other.isGlobal) &&
                    Objects.equals(this.elementId, other.elementId) &&
                    Objects.equals(this.portNumber, other.portNumber) &&
-                   Objects.equals(this.parentLabel, other.parentLabel);
+                   Objects.equals(this.parentPoint, other.parentPoint);
         }
         return false;
     }
@@ -104,7 +108,7 @@
         return toStringHelper(this)
                 .add("elementId", elementId)
                 .add("portNumber", portNumber)
-                .add("parentLabel", parentLabel)
+                .add("parentPoint", parentPoint)
                 .add("type", type)
                 .add("id", id)
                 .add("isGlobal", isGlobal)
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/DefaultTunnel.java b/core/api/src/main/java/org/onosproject/net/tunnel/DefaultTunnel.java
index c045d21..fa911fc 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/DefaultTunnel.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/DefaultTunnel.java
@@ -1,61 +1,92 @@
 package org.onosproject.net.tunnel;
 
+import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkState;
 
 import java.util.Objects;
 
-import org.onosproject.core.IdGenerator;
+import org.onosproject.core.DefaultGroupId;
 import org.onosproject.net.AbstractModel;
 import org.onosproject.net.Annotations;
+import org.onosproject.net.NetworkResource;
 import org.onosproject.net.provider.ProviderId;
-import org.onosproject.net.resource.BandwidthResource;
 
 /**
- * Default tunnel model implementation.
+ * The default implementation of an network tunnel. supports for creating a
+ * tunnel by connect point ,IP address, MAC address, device and so on.
  */
 public final class DefaultTunnel extends AbstractModel implements Tunnel {
-    private final TunnelId  id;
-    private final Label src;
-    private final Label dst;
-    private final Type type;
+
+    private final TunnelEndPoint src; // a source point of tunnel.
+    private final TunnelEndPoint dst; // a destination point of tunnel.
     private final State state;
-    private final boolean isDurable;
-    private final boolean isBidirectional;
-    private final BandwidthResource bandwidth;
+    private final Type type; // tunnel type
+    private final DefaultGroupId groupId; // represent for a group flow table
+    // which a tunnel match up
+    // tunnel producer
+    private final TunnelId tunnelId; // tunnel identify generated by
+                                     // ONOS as primary key
+    private final TunnelName tunnelName; // name of a tunnel
 
     /**
-     * Constructs an tunnel using the builder pattern.
+     * Creates an active infrastructure tunnel using the supplied information.
      *
-     * @param providerId  provider identity, can be null if comes from the NB
-     * @param builder     tunnelBuilder
+     * @param producerName provider identity
+     * @param src tunnel source
+     * @param dst tunnel destination
+     * @param type tunnel type
+     * @param groupId groupId
+     * @param tunnelId tunnelId
+     * @param tunnelName tunnel name
      * @param annotations optional key/value annotations
-     * @return
      */
-    private DefaultTunnel(ProviderId providerId, TunnelBuilder builder, Annotations... annotations) {
-        super(providerId, annotations);
-        this.id = builder.id;
-        this.src = builder.src;
-        this.dst = builder.dst;
-        this.type = builder.type;
-        this.state = builder.state;
-        this.isDurable = builder.isDurable;
-        this.isBidirectional = builder.isBidirectional;
-        this.bandwidth = builder.bandwidth;
+    public DefaultTunnel(ProviderId producerName, TunnelEndPoint src,
+                         TunnelEndPoint dst, Type type, DefaultGroupId groupId,
+                         TunnelId tunnelId, TunnelName tunnelName,
+                         Annotations... annotations) {
+        this(producerName, src, dst, type, Tunnel.State.ACTIVE, groupId,
+             tunnelId, tunnelName, annotations);
+    }
+
+    /**
+     * Creates an tunnel using the supplied information.
+     *
+     * @param producerName provider identity
+     * @param src tunnel source
+     * @param dst tunnel destination
+     * @param type tunnel type
+     * @param state tunnel state
+     * @param groupId groupId
+     * @param tunnelId tunnelId
+     * @param tunnelName tunnel name
+     * @param annotations optional key/value annotations
+     */
+    public DefaultTunnel(ProviderId producerName, TunnelEndPoint src,
+                         TunnelEndPoint dst, Type type, State state,
+                         DefaultGroupId groupId, TunnelId tunnelId,
+                         TunnelName tunnelName, Annotations... annotations) {
+        super(producerName, annotations);
+        checkNotNull(producerName, "producerName cannot be null");
+        checkNotNull(src, "src cannot be null");
+        checkNotNull(dst, "dst cannot be null");
+        checkNotNull(type, "type cannot be null");
+        checkNotNull(state, "state cannot be null");
+        this.src = src;
+        this.dst = dst;
+        this.type = type;
+        this.state = state;
+        this.groupId = groupId;
+        this.tunnelId = tunnelId;
+        this.tunnelName = tunnelName;
     }
 
     @Override
-    public TunnelId id() {
-        return id;
-    }
-
-    @Override
-    public Label src() {
+    public TunnelEndPoint src() {
         return src;
     }
 
     @Override
-    public Label dst() {
+    public TunnelEndPoint dst() {
         return dst;
     }
 
@@ -70,29 +101,31 @@
     }
 
     @Override
-    public boolean isDurable() {
-        return isDurable;
+    public NetworkResource resource() {
+        return null;
     }
 
     @Override
-    public boolean isBidirectional() {
-        return isBidirectional;
+    public TunnelId tunnelId() {
+        return tunnelId;
     }
 
     @Override
-    public BandwidthResource bandwidth() {
-        return bandwidth;
+    public DefaultGroupId groupId() {
+        return groupId;
+    }
+
+    @Override
+    public TunnelName tunnelName() {
+        return tunnelName;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(id);
+        return Objects.hash(src, dst, type, groupId, tunnelId, tunnelName,
+                            state);
     }
 
-    /**
-     * {@inheritDoc}
-     * Note that only TunnelId is considered on equality check.
-     */
     @Override
     public boolean equals(Object obj) {
         if (this == obj) {
@@ -100,69 +133,23 @@
         }
         if (obj instanceof DefaultTunnel) {
             final DefaultTunnel other = (DefaultTunnel) obj;
-            return Objects.equals(this.id, other.id);
+            return Objects.equals(this.src, other.src)
+                    && Objects.equals(this.dst, other.dst)
+                    && Objects.equals(this.type, other.type)
+                    && Objects.equals(this.groupId, other.groupId)
+                    && Objects.equals(this.tunnelId, other.tunnelId)
+                    && Objects.equals(this.tunnelName, other.tunnelName)
+                    && Objects.equals(this.state, other.state);
         }
         return false;
     }
 
     @Override
     public String toString() {
-        return toStringHelper(this)
-                .add("tunnelId", id)
-                .add("src", src)
-                .add("dst", dst)
-                .add("type", type)
-                .add("state", state)
-                .add("durable", isDurable)
-                .add("isBidirectional", isBidirectional)
-                .add("bandwidth", bandwidth)
-                .toString();
-    }
-
-    public static class TunnelBuilder {
-        private TunnelId id = null;
-        private Label src = null;
-        private Label dst = null;
-        private Type type = null;
-        private State state = null;
-        private boolean isDurable = false;
-        private boolean isBidirectional = false;
-        private BandwidthResource bandwidth = null;
-
-        private static IdGenerator idGenerator;
-
-        public TunnelBuilder labelSrcDst(Label src, Label dst) {
-            this.src = src;
-            this.dst = dst;
-            return this;
-        }
-
-        public TunnelBuilder state(State state) {
-            this.state = state;
-            return this;
-        }
-
-        public TunnelBuilder isDurable(boolean isDurable) {
-            this.isDurable = isDurable;
-            return this;
-        }
-
-        public TunnelBuilder isBidirectional(boolean isBidirectional) {
-            this.isBidirectional = isBidirectional;
-            return this;
-        }
-
-        public TunnelBuilder bandwidth(BandwidthResource bandwidth) {
-            this.bandwidth = bandwidth;
-            return this;
-        }
-
-        public DefaultTunnel build(ProviderId providerId, Annotations... annotations) {
-            checkState(idGenerator != null, "Id generator is not bound.");
-            this.id = TunnelId.valueOf(idGenerator.getNewId());
-            return new DefaultTunnel(providerId, this, annotations);
-        }
-
+        return toStringHelper(this).add("src", src).add("dst", dst)
+                .add("type", type).add("state", state).add("groupId", groupId)
+                .add("producerTunnelId", tunnelId)
+                .add("tunnelName", tunnelName).toString();
     }
 
 }
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/DefaultTunnelDescription.java b/core/api/src/main/java/org/onosproject/net/tunnel/DefaultTunnelDescription.java
index 432f4c6..16585de 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/DefaultTunnelDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/DefaultTunnelDescription.java
@@ -15,11 +15,13 @@
  */
 package org.onosproject.net.tunnel;
 
-import com.google.common.base.MoreObjects;
-
+import static com.google.common.base.Preconditions.checkNotNull;
+import org.onosproject.core.DefaultGroupId;
 import org.onosproject.net.AbstractDescription;
-import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.provider.ProviderId;
+
+import com.google.common.base.MoreObjects;
 
 /**
  * Default implementation of immutable tunnel description entity.
@@ -27,31 +29,46 @@
 public class DefaultTunnelDescription extends AbstractDescription
         implements TunnelDescription {
 
-    private final TunnelId  tunnelId;
-    private final ConnectPoint src;
-    private final ConnectPoint dst;
+    private final TunnelId tunnelId;
+    private final TunnelEndPoint src;
+    private final TunnelEndPoint dst;
     private final Tunnel.Type type;
-    private final boolean isBidirectional;
+    private final DefaultGroupId groupId; // represent for a group flow table
+    // which a tunnel match up
+    // tunnel producer
+    private final ProviderId producerName; // tunnel producer name
+    private final TunnelName tunnelName; // name of a tunnel
 
     /**
      * Creates a tunnel description using the supplied information.
      *
-     * @param id          TunnelId
-     * @param src         ConnectPoint source
-     * @param dst         ConnectPoint destination
-     * @param type        tunnel type
-     * @param isBidirectional        boolean
+     * @param id TunnelId
+     * @param src TunnelPoint source
+     * @param dst TunnelPoint destination
+     * @param type tunnel type
+     * @param groupId groupId
+     * @param producerName tunnel producer
+     * @param tunnelName tunnel name
      * @param annotations optional key/value annotations
      */
-    public DefaultTunnelDescription(TunnelId id, ConnectPoint src, ConnectPoint dst,
-                                  Tunnel.Type type, boolean isBidirectional,
-                                  SparseAnnotations... annotations) {
+    public DefaultTunnelDescription(TunnelId id, TunnelEndPoint src,
+                                    TunnelEndPoint dst, Tunnel.Type type,
+                                    DefaultGroupId groupId,
+                                    ProviderId producerName,
+                                    TunnelName tunnelName,
+                                    SparseAnnotations... annotations) {
         super(annotations);
+        checkNotNull(producerName, "producerName cannot be null");
+        checkNotNull(src, "src cannot be null");
+        checkNotNull(dst, "dst cannot be null");
+        checkNotNull(type, "type cannot be null");
         this.tunnelId = id;
         this.src = src;
         this.dst = dst;
         this.type = type;
-        this.isBidirectional = isBidirectional;
+        this.groupId = groupId;
+        this.producerName = producerName;
+        this.tunnelName = tunnelName;
     }
 
     @Override
@@ -60,12 +77,12 @@
     }
 
     @Override
-    public ConnectPoint src() {
+    public TunnelEndPoint src() {
         return src;
     }
 
     @Override
-    public ConnectPoint dst() {
+    public TunnelEndPoint dst() {
         return dst;
     }
 
@@ -75,8 +92,18 @@
     }
 
     @Override
-    public boolean isBidirectional() {
-        return isBidirectional;
+    public DefaultGroupId groupId() {
+        return groupId;
+    }
+
+    @Override
+    public ProviderId producerName() {
+        return producerName;
+    }
+
+    @Override
+    public TunnelName tunnelName() {
+        return tunnelName;
     }
 
     @Override
@@ -86,7 +113,9 @@
                 .add("src", src())
                 .add("dst", dst())
                 .add("type", type())
-                .add("isBidirectional", isBidirectional())
+                .add("tunnelName", tunnelName())
+                .add("producerName", producerName())
+                .add("groupId", groupId())
                 .toString();
     }
 
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/IpTunnelEndPoint.java b/core/api/src/main/java/org/onosproject/net/tunnel/IpTunnelEndPoint.java
new file mode 100644
index 0000000..d440c3a
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/IpTunnelEndPoint.java
@@ -0,0 +1,53 @@
+package org.onosproject.net.tunnel;
+
+import java.util.Objects;
+
+import org.onlab.packet.IpAddress;
+
+import com.google.common.base.MoreObjects;
+/**
+ * Represent for a tunnel point using ip address.
+ */
+public final class IpTunnelEndPoint implements TunnelEndPoint {
+
+    private final IpAddress ip;
+
+    /**
+     * Public construction is prohibited.
+     * @param ip ip address
+     */
+    private IpTunnelEndPoint(IpAddress ip) {
+        this.ip = ip;
+    }
+
+    /**
+     * Create a IP tunnel end point.
+     * @param ip IP address
+     * @return IpTunnelEndPoint
+     */
+    public static IpTunnelEndPoint ipTunnelPoint(IpAddress ip) {
+        return new IpTunnelEndPoint(ip);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ip);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IpTunnelEndPoint) {
+            final IpTunnelEndPoint other = (IpTunnelEndPoint) obj;
+            return Objects.equals(this.ip, other.ip);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("ip", ip).toString();
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/Label.java b/core/api/src/main/java/org/onosproject/net/tunnel/Label.java
deleted file mode 100644
index 2f9d9ed..0000000
--- a/core/api/src/main/java/org/onosproject/net/tunnel/Label.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.net.tunnel;
-
-import java.util.Optional;
-
-import org.onosproject.net.Annotated;
-import org.onosproject.net.ElementId;
-import org.onosproject.net.NetworkResource;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.Provided;
-
-/**
- * Generic representation of a logical port entity in a consistent way,
- * it is used to identify e.g., VLAN#, MPLS label#, ODUk timeSlot, WDM lambda, etc.
- * It supports nested case.
- */
-public interface Label extends Annotated, Provided, NetworkResource {
-
-    /** Represents coarse Label type classification. */
-    enum Type {
-        /**
-         * Signifies VLAN-based tag.
-         */
-        VLAN,
-
-        /**
-         * Signifies LAG-based label.
-         */
-        LAG,
-
-        /**
-         * Signifies MPLS-based label.
-         */
-        MPLS,
-
-        /**
-         * Signifies IP-based label.
-         */
-        IP,
-
-        /**
-         * Signifies optical data unit-based label.
-         */
-        TIMESLOT,
-
-        /**
-         * Signifies optical wavelength-based label.
-         */
-        LAMBDA,
-
-        /**
-         * Signifies device-based identifier for the label.
-         */
-        DEVICE
-    }
-
-    /**
-     * Returns the identifier to this Label.
-     *
-     * @return identifier
-     */
-    LabelId id();
-
-    /**
-     * Returns the parent network element to which this label belongs.
-     *
-     * @return parent network element
-     */
-    Optional<ElementId> elementId();
-
-    /**
-     * Returns the parent network port to which this label belongs, can not be be null.
-     *
-     * @return port number
-     */
-    Optional<PortNumber> portNumber();
-
-    /**
-     * Returns the parent label to which this label belongs, optional.
-     *
-     * @return parent label, if it is null, the parent is a physical port
-     */
-    Optional<Label> parentLabel();
-
-    /**
-     * Indicates whether or not the port is global significant.
-     *
-     * @return true if the port is global significant
-     */
-    boolean isGlobal();
-
-    /**
-     * Returns the label type.
-     *
-     * @return label type
-     */
-    Type type();
-}
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/LabelId.java b/core/api/src/main/java/org/onosproject/net/tunnel/OpticalLogicId.java
similarity index 69%
rename from core/api/src/main/java/org/onosproject/net/tunnel/LabelId.java
rename to core/api/src/main/java/org/onosproject/net/tunnel/OpticalLogicId.java
index 0d59211..d12849b 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/LabelId.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/OpticalLogicId.java
@@ -21,17 +21,17 @@
 /**
  * Representation of a label Id, a logical port identifier.
  */
-public final class LabelId {
+public final class OpticalLogicId {
         /**
          * Represents a logical Id.
         */
-        private final long labelId;
+        private final long logicId;
 
         /**
          * Constructor, public creation is prohibited.
          */
-        private LabelId(long id) {
-            this.labelId = id;
+        private OpticalLogicId(long id) {
+            this.logicId = id;
         }
 
         /**
@@ -40,26 +40,26 @@
          * @param id identifier as long value
          * @return LabelId
          */
-        public static LabelId labelId(long id) {
-            return new LabelId(id);
+        public static OpticalLogicId logicId(long id) {
+            return new OpticalLogicId(id);
         }
 
-        public static LabelId labelId(String string) {
-            return new LabelId(UnsignedLongs.decode(string));
+        public static OpticalLogicId logicId(String string) {
+            return new OpticalLogicId(UnsignedLongs.decode(string));
         }
 
         public long toLong() {
-            return labelId;
+            return logicId;
         }
 
         @Override
         public String toString() {
-            return UnsignedLongs.toString(labelId);
+            return UnsignedLongs.toString(logicId);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(labelId);
+            return Objects.hash(logicId);
         }
 
         @Override
@@ -67,9 +67,9 @@
             if (this == obj) {
                 return true;
             }
-            if (obj instanceof LabelId) {
-                final LabelId other = (LabelId) obj;
-                return this.labelId == other.labelId;
+            if (obj instanceof OpticalLogicId) {
+                final OpticalLogicId other = (OpticalLogicId) obj;
+                return this.logicId == other.logicId;
             }
             return false;
         }
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/OpticalTunnelEndPoint.java b/core/api/src/main/java/org/onosproject/net/tunnel/OpticalTunnelEndPoint.java
new file mode 100644
index 0000000..9ce84be
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/OpticalTunnelEndPoint.java
@@ -0,0 +1,87 @@
+/*
+ * 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.net.tunnel;
+
+import java.util.Optional;
+
+import org.onosproject.net.Annotated;
+import org.onosproject.net.ElementId;
+import org.onosproject.net.NetworkResource;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.Provided;
+
+/**
+ * Generic representation of a logical port entity in a consistent way,
+ * it is used to identify e.g., ODUk timeSlot, WDM lambda, etc.
+ * It supports nested case.
+ */
+public interface OpticalTunnelEndPoint extends TunnelEndPoint, Annotated, Provided, NetworkResource {
+
+    /** Represents coarse tunnel point type classification. */
+    public enum Type {
+        /**
+         * Signifies optical data unit-based tunnel point.
+         */
+        TIMESLOT,
+
+        /**
+         * Signifies optical wavelength-based tunnel point.
+         */
+        LAMBDA
+    }
+
+    /**
+     * Returns the identifier.
+     *
+     * @return identifier
+     */
+    OpticalLogicId id();
+
+    /**
+     * Returns the parent network element to which this tunnel point belongs.
+     *
+     * @return parent network element
+     */
+    Optional<ElementId> elementId();
+
+    /**
+     * Returns the parent network port to which this tunnel point belongs, can not be be null.
+     *
+     * @return port number
+     */
+    Optional<PortNumber> portNumber();
+
+    /**
+     * Returns the parent tunnel point to which this tunnel point belongs, optional.
+     *
+     * @return parent tunnel point, if it is null, the parent is a physical port
+     */
+    Optional<OpticalTunnelEndPoint> parentPoint();
+
+    /**
+     * Indicates whether or not the port is global significant.
+     *
+     * @return true if the port is global significant
+     */
+    boolean isGlobal();
+
+    /**
+     * Returns the tunnel point type.
+     *
+     * @return tunnel point type
+     */
+    Type type();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/Tunnel.java b/core/api/src/main/java/org/onosproject/net/tunnel/Tunnel.java
index 605d70f..bc3d18b 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/Tunnel.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/Tunnel.java
@@ -15,50 +15,44 @@
  */
 package org.onosproject.net.tunnel;
 
+import org.onosproject.core.DefaultGroupId;
 import org.onosproject.net.Annotated;
 import org.onosproject.net.NetworkResource;
 import org.onosproject.net.Provided;
-import org.onosproject.net.resource.BandwidthResource;
-
 
 /**
- * Abstraction of a generalized Tunnel entity (bandwidth pipe) for either L3/L2 networks or L1/L0 networks,
- * representation of e.g., VLAN, GRE tunnel, MPLS LSP, L1 ODUk connection, WDM OCH, etc.. Each Tunnel is
- * associated with at least two Label objects that model the logical ports essentially.
+ * Abstraction of a generalized Tunnel entity (bandwidth pipe) for either L3/L2
+ * networks or L1/L0 networks, representation of e.g., VLAN, GRE tunnel, MPLS
+ * LSP, L1 ODUk connection, WDM OCH, etc.. Each Tunnel is associated with at
+ * least two tunnel end point objects that model the logical ports essentially.
  * Note that it supports nested case.
  */
-
 public interface Tunnel extends Annotated, Provided, NetworkResource {
 
     /**
-     * Coarse representation of the Tunnel types.
+     * Tunnel technology type.
      */
     enum Type {
         /**
+         * Signifies that this is a MPLS tunnel.
+         */
+        MPLS,
+        /**
          * Signifies that this is a L2 tunnel.
          */
         VLAN,
-
         /**
          * Signifies that this is a DC L2 extension tunnel.
          */
         VXLAN,
-
         /**
          * Signifies that this is a L3 tunnel.
          */
         GRE,
-
-        /**
-         * Signifies that this is a MPLS tunnel.
-         */
-        LSP,
-
         /**
          * Signifies that this is a L1 OTN tunnel.
          */
-        ODUk,
-
+        ODUK,
         /**
          * Signifies that this is a L0 OCH tunnel.
          */
@@ -67,61 +61,32 @@
 
     /**
      * Representation of the tunnel state.
-     *
      */
-    enum State {
-
+    public enum State {
         /**
          * Signifies that a tunnel is currently in a initialized state.
          */
         INIT,
-
         /**
          * Signifies that a tunnel is currently established but no traffic.
          */
         ESTABLISHED,
-
         /**
-         * Signifies that a tunnel is currently serving the traffic.
+         * Signifies that a tunnel is currently active. This state means that
+         * this tunnel is available. It can be borrowed by consumer.
          */
         ACTIVE,
-
         /**
          * Signifies that a tunnel is currently out of service.
          */
         FAILED,
-
         /**
-         * Signifies that a tunnel is currently in maintenance state.
+         * Signifies that a tunnel is currently inactive. This state means that
+         * this tunnel can not be borrowed by consumer.
          */
         INACTIVE
-
     }
 
-    TunnelId id();
-
-
-    /**
-     * Returns the tunnel source point (source Label object).
-     *
-     * @return source Label object
-     */
-    Label src();
-
-    /**
-     * Returns the tunnel destination point (destination Label object).
-     *
-     * @return destination Label object
-     */
-    Label dst();
-
-    /**
-     * Returns the tunnel type.
-     *
-     * @return tunnel type
-     */
-    Type type();
-
     /**
      * Returns the tunnel state.
      *
@@ -130,29 +95,52 @@
     State state();
 
     /**
-     * Indicates if the tunnel is to be considered durable.
+     * the origin of a tunnel.
      *
-     * @return true if the tunnel is durable
+     * @return the origin of a tunnel
      */
-    boolean isDurable();
-
+    TunnelEndPoint src();
 
     /**
-     * Indicates if the tunnel is to be considered Bidirectional.
+     * the terminal of a tunnel.
      *
-     * @return true if the tunnel is Bidirectional
+     * @return the terminal of a tunnel
      */
-    boolean isBidirectional();
+    TunnelEndPoint dst();
 
     /**
-     * Return the tunnel bandwidth.
+     * Returns the tunnel type.
      *
-     * @return tunnel bandwidth
+     * @return tunnel type
      */
-    BandwidthResource bandwidth();
+    Type type();
+
+    /**
+     * Returns group flow table id which a tunnel match up.
+     *
+     * @return OpenFlowGroupId
+     */
+    DefaultGroupId groupId();
+
+    /**
+     * Returns tunnel identify generated by ONOS as primary key.
+     *
+     * @return TunnelId
+     */
+    TunnelId tunnelId();
+
+    /**
+     * Return the name of a tunnel.
+     *
+     * @return Tunnel Name
+     */
+    TunnelName tunnelName();
+
+    /**
+     * Network resource backing the tunnel, e.g. lambda, VLAN id, MPLS tag.
+     *
+     * @return backing resource
+     */
+    NetworkResource resource();
+
 }
-
-
-
-
-
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelAdminService.java b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelAdminService.java
index 3731e5a..d140600 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelAdminService.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelAdminService.java
@@ -15,9 +15,8 @@
  */
 package org.onosproject.net.tunnel;
 
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
 import org.onosproject.net.Path;
+import org.onosproject.net.provider.ProviderId;
 
 /**
  * Service for administering the inventory of provisioned tunnels.
@@ -37,17 +36,9 @@
      *
      * @param src source label
      * @param dst destination label
+     * @param producerName producer name
      */
-    void removeTunnels(Label src, Label dst);
-
-    /**
-     * Removes all provisioned tunnels leading to and from the
-     * specified connection point.
-     *
-     * @param src source connection point
-     * @param dst destination connection point
-     */
-    void removeTunnels(ConnectPoint src, ConnectPoint dst);
+    void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, ProviderId producerName);
 
     /**
      * Removes all provisioned tunnels leading to and from the
@@ -56,24 +47,9 @@
      * @param src source connection point
      * @param dst destination connection point
      * @param type tunnel type
+     * @param producerName producer name
      */
-    void removeTunnels(ConnectPoint src, ConnectPoint dst, Tunnel.Type type);
-
-    /**
-     * Removes all provisioned tunnels leading to and from the
-     * specified connection point.
-     *
-     * @param connectPoint connection point
-     */
-    void removeTunnels(ConnectPoint connectPoint);
-
-    /**
-     * Removes all provisioned tunnels leading to and from the
-     * specified device.
-     *
-     * @param deviceId device identifier
-     */
-    void removeTunnels(DeviceId deviceId);
+    void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, Tunnel.Type type, ProviderId producerName);
 
     /**
      * Invokes the core to update a tunnel based on specified tunnel parameters.
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelDescription.java b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelDescription.java
index f77928e..efa9c58 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelDescription.java
@@ -15,13 +15,16 @@
  */
 package org.onosproject.net.tunnel;
 
-import org.onosproject.net.ConnectPoint;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.net.Annotated;
 import org.onosproject.net.Description;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.tunnel.Tunnel.Type;
 
 /**
- * Describes the tunnel.
+ * Describes a tunnel.
  */
-public interface TunnelDescription extends Description {
+public interface TunnelDescription extends Description, Annotated {
 
     /**
      * Returns the tunnel id.
@@ -35,27 +38,40 @@
      *
      * @return tunnel source ConnectionPoint
      */
-    ConnectPoint src();
+    TunnelEndPoint src();
 
     /**
      * Returns the connection point destination.
      *
      * @return tunnel destination
      */
-    ConnectPoint dst();
+    TunnelEndPoint dst();
 
     /**
      * Returns the tunnel type.
      *
      * @return tunnel type
      */
-    Tunnel.Type type();
+    Type type();
 
     /**
-     * Returns if the tunnel is bidirectional.
+     * Returns group flow table id which a tunnel match up.
      *
-     * @return true if bidirectional, otherwise false
+     * @return OpenFlowGroupId
      */
-    boolean isBidirectional();
+    DefaultGroupId groupId();
 
+    /**
+     * Returns tunnel producer name.
+     *
+     * @return producer name
+     */
+    ProviderId producerName();
+
+    /**
+     * Return the name of a tunnel.
+     *
+     * @return Tunnel Name
+     */
+    TunnelName tunnelName();
 }
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelEndPoint.java b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelEndPoint.java
new file mode 100644
index 0000000..53db69c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelEndPoint.java
@@ -0,0 +1,9 @@
+package org.onosproject.net.tunnel;
+
+/**
+ * Represents for source end point or destination end point of a tunnel. Maybe a tunnel
+ * based on ConnectPoint, IpAddress, MacAddress and so on is built.
+ */
+public interface TunnelEndPoint {
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelEvent.java b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelEvent.java
index 41b36a4..9824623 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelEvent.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelEvent.java
@@ -20,7 +20,7 @@
 /**
  * Describes tunnel events.
  */
-public class TunnelEvent extends AbstractEvent<TunnelEvent.Type, Tunnel> {
+public final class TunnelEvent extends AbstractEvent<TunnelEvent.Type, Tunnel> {
 
     /**
      * Type of tunnel events.
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelName.java b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelName.java
new file mode 100644
index 0000000..db6bd7c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelName.java
@@ -0,0 +1,60 @@
+package org.onosproject.net.tunnel;
+
+import java.util.Objects;
+
+/**
+ * Represents for a unique tunnel name. TunnelId is generated by ONOS while
+ * TunnelName is given by producer. The consumer can borrow tunnels with
+ * TunnelId or TunnelName.
+ */
+public final class TunnelName {
+    private final String str;
+
+    // Default constructor for serialization
+    private TunnelName(String tunnelName) {
+        this.str = tunnelName;
+    }
+
+
+    /**
+     * Creates a tunnel name using the supplied URI string.
+     *
+     * @param tunnelName tunnel name string
+     * @return tunnel name object
+     */
+    public static TunnelName tunnelName(String tunnelName) {
+        return new TunnelName(tunnelName);
+    }
+
+    /**
+     * The string of tunnel name.
+     *
+     * @return the string of tunnel name
+     */
+    public String value() {
+        return str;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(str);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof TunnelName) {
+            final TunnelName that = (TunnelName) obj;
+            return this.getClass() == that.getClass()
+                    && Objects.equals(this.str, that.str);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return str;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelProvider.java b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelProvider.java
index ea90342..e388c70 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelProvider.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelProvider.java
@@ -25,7 +25,7 @@
 public interface TunnelProvider extends Provider {
 
     /**
-     * Instructs the provider to setup a tunnel.
+     * Instructs the provider to setup a tunnel. It's used by consumers.
      *
      * @param tunnel Tunnel
      * @param path explicit route or null for the tunnel
@@ -34,6 +34,7 @@
 
     /**
      * Instructs the provider to setup a tunnel given the respective device.
+     * It's used by consumers.
      *
      * @param srcElement device
      * @param tunnel Tunnel
@@ -42,7 +43,7 @@
     void setupTunnel(ElementId srcElement, Tunnel tunnel, Path path);
 
     /**
-     * Instructs the provider to release a tunnel.
+     * Instructs the provider to release a tunnel. It's used by consumers.
      *
      * @param tunnel Tunnel
      */
@@ -50,6 +51,7 @@
 
     /**
      * Instructs the provider to release a tunnel given the respective device.
+     * It's used by consumers.
      *
      * @param srcElement device
      * @param tunnel Tunnel
@@ -57,20 +59,46 @@
     void releaseTunnel(ElementId srcElement, Tunnel tunnel);
 
     /**
-     * Instructs the provider to update a tunnel.
+     * Instructs the provider to update a tunnel. It's used by consumers. Maybe
+     * some consumers enable to update a tunnel.
      *
      * @param tunnel Tunnel
-     * @param path explicit route (path changed) or null (path not changed) for the tunnel
+     * @param path explicit route (path changed) or null (path not changed) for
+     *            the tunnel
      */
     void updateTunnel(Tunnel tunnel, Path path);
 
     /**
      * Instructs the provider to update a tunnel given the respective device.
+     * It's used by consumers. Maybe some consumers enable to update a tunnel.
      *
      * @param srcElement device
      * @param tunnel Tunnel
-     * @param path explicit route (path changed) or null (path not changed) for the tunnel
+     * @param path explicit route (path changed) or null (path not changed) for
+     *            the tunnel
      */
     void updateTunnel(ElementId srcElement, Tunnel tunnel, Path path);
 
+    /**
+     * Signals that the provider has added a tunnel. It's used by producers.
+     *
+     * @param tunnel tunnel information
+     * @return tunnel identity
+     */
+    TunnelId tunnelAdded(TunnelDescription tunnel);
+
+    /**
+     * Signals that the provider has removed a tunnel. It's used by producers.
+     *
+     * @param tunnel tunnel information
+     */
+    void tunnelRemoved(TunnelDescription tunnel);
+
+    /**
+     * Signals that the a tunnel was changed (e.g., sensing changes of
+     * tunnel).It's used by producers.
+     *
+     * @param tunnel tunnel information
+     */
+    void tunnelUpdated(TunnelDescription tunnel);
 }
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelProviderService.java b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelProviderService.java
index 4842098..7b02676 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelProviderService.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelProviderService.java
@@ -26,8 +26,9 @@
      * Signals that the provider has added a tunnel.
      *
      * @param tunnel tunnel information
+     * @return tunnel identity
      */
-    void tunnelAdded(TunnelDescription tunnel);
+    TunnelId tunnelAdded(TunnelDescription tunnel);
 
     /**
      * Signals that the provider has removed a tunnel.
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelService.java b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelService.java
index 3b060fc..109d981 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelService.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelService.java
@@ -17,88 +17,166 @@
 
 import java.util.Collection;
 
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Path;
-import org.onosproject.net.resource.BandwidthResource;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.tunnel.Tunnel.Type;
 
 /**
- * Service for interacting with the tunnel inventory.
+ * Service for interacting with the inventory of tunnels.
  */
 public interface TunnelService {
 
     /**
-     * Invokes the core to create a tunnel based on specified parameters.
+     * Borrows a specific tunnel. Annotations parameter is reserved.If there
+     * is no tunnel in the store, returns a "null" object, and record the tunnel subscription.
+     * Where tunnel is created, ONOS notifies this consumer actively.
      *
-     * @param src sourcePoint
-     * @param dst destinationPoint
-     * @param bw  bandwidth
-     * @param path explicit path or null
+     * @param consumerId a tunnel consumer
+     * @param tunnelId tunnel identify generated by onos
+     * @param annotations Annotations
+     * @return Tunnel subscribed tunnel
      */
-    void requestTunnel(ConnectPoint src, ConnectPoint dst, BandwidthResource bw, Path path);
+    Tunnel borrowTunnel(ApplicationId consumerId, TunnelId tunnelId,
+                           Annotations... annotations);
 
     /**
-     * Invokes the core to create a tunnel based on specified parameters with a tunnel type.
+     * Borrows a specific tunnel by tunnelName. Annotations parameter is reserved.If there
+     * is no tunnel in the store, return a "null" object, and record the tunnel subscription.
+     * Where tunnel is created, ONOS notifies this consumer actively.
      *
-     * @param src sourcePoint
-     * @param dst destinationPoint
-     * @param type  tunnelType
-     * @param bw  bandwidth
-     * @param path explicit path or null
+     * @param consumerId a tunnel consumer
+     * @param tunnelName tunnel name
+     * @param annotations Annotations
+     * @return collection of subscribed Tunnels
      */
-    void requestTunnel(ConnectPoint src, ConnectPoint dst, Tunnel.Type type, BandwidthResource bw, Path path);
+    Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelName tunnelName,
+                           Annotations... annotations);
 
     /**
-     * Returns the count of all known tunnels in the dataStore.
+     * Borrows all tunnels between source and destination. Annotations
+     * parameter is reserved.If there is no any tunnel in the store, return a
+     * empty collection,and record the tunnel subscription. Where tunnel is created, ONOS
+     * notifies this consumer actively. Otherwise ONOS core returns all the
+     * tunnels, consumer determined which one to use.
      *
-     * @return number of tunnels
+     * @param consumerId a tunnel consumer
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel
+     * @param annotations Annotations
+     * @return collection of subscribed Tunnels
      */
-    int getTunnelCount();
+    Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src,
+                                       TunnelEndPoint dst, Annotations... annotations);
 
     /**
-     * Returns a collection of all known tunnel based on the type.
+     * Borrows all specified type tunnels between source and destination.
+     * Annotations parameter is reserved.If there is no any tunnel in the store,
+     * return a empty collection, and record the tunnel subscription. Where tunnel is
+     * created, ONOS notifies this consumer actively. Otherwise,ONOS core returns
+     * all available tunnels, consumer determined which one to use.
      *
-     *@param type  tunnelType
-     * @return all tunnels for a specific type
-     */
-    Collection<Tunnel> getTunnels(Tunnel.Type type);
-
-    /**
-     * Returns set of all tunnels from the specified connectpoint.
-     *
-     * @param connectPoint device/portnumber
-     * @param type  tunnelType
-     * @return set of tunnels
-     */
-    Collection<Tunnel> getTunnels(ConnectPoint connectPoint, Tunnel.Type type);
-
-    /**
-     * Returns set of all tunnels from the
-     * specified source connectpoint and destination connectpoint.
-     *
-     * @param src sourcePoint
-     * @param dst destinationPoint
+     * @param consumerId a tunnel consumer
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel
      * @param type tunnel type
-     * @return set of tunnels
+     * @param annotations Annotations
+     * @return collection of available Tunnels
      */
-    Collection<Tunnel> getTunnels(ConnectPoint src, ConnectPoint dst, Tunnel.Type type);
+    Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src,
+                                       TunnelEndPoint dst, Type type,
+                                       Annotations... annotations);
 
     /**
-     * Returns the tunnel between the specified source
-     * and destination connection points.
+     * Returns back a specific tunnel to store.
      *
-     * @param src source label
-     * @param dst destination label
-     * @return tunnel from source to destination; null if none found
+     * @param consumerId a tunnel consumer
+     * @param tunnelId tunnel identify generated by ONOS
+     * @param annotations Annotations
+     * @return success or fail
      */
-    Tunnel getTunnel(Label src, Label dst);
+    boolean returnTunnel(ApplicationId consumerId, TunnelId tunnelId,
+                              Annotations... annotations);
 
     /**
-     * Returns the tunnel based on the Id.
+     * Returns all specific name tunnel back store. Annotations parameter is reserved.if there
+     * is no tunnel in the store, return a "null" object, and record the tunnel subscription.
+     * Where tunnel is created, ONOS notifies this consumer actively.
      *
-     * @param id tunnelId
-     * @return tunnel with specified Id
+     * @param consumerId a tunnel consumer
+     * @param tunnelName tunnel name
+     * @param annotations Annotations
+     * @return boolean
      */
-    Tunnel getTunnel(TunnelId id);
+    boolean returnTunnel(ApplicationId consumerId, TunnelName tunnelName,
+                           Annotations... annotations);
+
+    /**
+     * Returns all specific type tunnels between source and destination back
+     * store. Annotations parameter is reserved.
+     *
+     * @param consumerId a tunnel consumer
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel
+     * @param type tunnel type
+     * @param annotations Annotations
+     * @return success or fail
+     */
+    boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src,
+                              TunnelEndPoint dst, Type type,
+                              Annotations... annotations);
+
+    /**
+     * Returns all tunnels between source and destination back the store.
+     * Annotations parameter is reserved.
+     *
+     * @param consumerId a tunnel consumer
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel.
+     * @param annotations Annotations
+     * @return success or fail
+     */
+    boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src,
+                              TunnelEndPoint dst, Annotations... annotations);
+
+    /**
+     * Returns a tunnel by a specific tunnel identity.
+     *
+     * @param tunnelId tunnel identify generated by tunnel producer
+     * @return Tunnel
+     */
+    Tunnel queryTunnel(TunnelId tunnelId);
+
+    /**
+     * Returns all tunnel subscription record by consumer.
+     *
+     * @param consumerId consumer identity
+     * @return Collection of TunnelSubscription
+     */
+    Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId consumerId);
+
+    /**
+     * Returns all specified type tunnels.
+     *
+     * @param type tunnel type
+     * @return Collection of tunnels
+     */
+    Collection<Tunnel> queryTunnel(Type type);
+
+    /**
+     * Returns all tunnels between source point and destination point.
+     *
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel.
+     * @return Collection of tunnels
+     */
+    Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst);
+
+    /**
+     * Returns all tunnels.
+     *
+     * @return all tunnels
+     */
+    int tunnelCount();
 
     /**
      * Adds the specified tunnel listener.
@@ -113,5 +191,4 @@
      * @param listener tunnel listener
      */
     void removeListener(TunnelListener listener);
-
 }
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelStore.java b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelStore.java
index 09c74c1..107dea3 100644
--- a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelStore.java
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelStore.java
@@ -15,100 +15,206 @@
  */
 package org.onosproject.net.tunnel;
 
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
+import java.util.Collection;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.Annotations;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.tunnel.Tunnel.Type;
 import org.onosproject.store.Store;
 
 /**
- * Manages inventory of tunnels.
+ * Manages inventory of tunnel; not intended for direct use.
  */
 public interface TunnelStore extends Store<TunnelEvent, TunnelStoreDelegate> {
-
     /**
-     * Returns the number of tunnels in the store.
+     * Creates or updates a tunnel.
      *
-     * @return number of tunnels
+     * @param tunnel tunnel
+     * @return tunnel identity
      */
-    int getTunnelCount();
+    TunnelId createOrUpdateTunnel(Tunnel tunnel);
 
     /**
-     * Returns an iterable collection of all tunnel in the inventory.
+     * Deletes a tunnel by a specific tunnel identifier.
      *
-     * @return collection of all tunnels
+     * @param tunnelId tunnel unique identifier generated by ONOS
      */
-    Iterable<Tunnel> getTunnels();
+    void deleteTunnel(TunnelId tunnelId);
 
     /**
-     * Returns all tunnels egressing from the specified device.
+     * Deletes all tunnels between source point and destination point.
      *
-     * @param deviceId device identifier
-     * @return set of device tunnels
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel.
+     * @param producerName producerName
      */
-    Iterable<Tunnel> getDeviceEgressTunnels(DeviceId deviceId);
+    void deleteTunnel(TunnelEndPoint src, TunnelEndPoint dst,
+                                  ProviderId producerName);
 
     /**
-     * Returns all tunnels ingressing from the specified device.
+     * Deletes all specific type tunnels between source point and destination
+     * point.
      *
-     * @param deviceId device identifier
-     * @return set of device tunnels
-     */
-    Iterable<Tunnel> getDeviceIngressTunnels(DeviceId deviceId);
-
-    /**
-     * Returns the tunnel between the two end-points and the tunnel type.
-     *
-     * @param src source connection point
-     * @param dst destination connection point
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel.
      * @param type tunnel type
-     * @return tunnels or null if one not found between the end-points
+     * @param producerName producerName
      */
-    Iterable<Tunnel> getTunnel(ConnectPoint src, ConnectPoint dst, Tunnel.Type type);
+    void deleteTunnel(TunnelEndPoint src, TunnelEndPoint dst,
+                                  Tunnel.Type type, ProviderId producerName);
 
     /**
-     * Returns all tunnels egressing from the specified connection point.
+     * Returns a specific tunnel. Annotations parameter is reserved. If there
+     * is no tunnel in the store, return a "null" object, and record the tunnel subscription.
+     * Where tunnel is created, ONOS notifies this consumer actively.
      *
-     * @param src source connection point
-     * @return set of connection point tunnels
+     * @param consumerId a tunnel consumer
+     * @param tunnelId tunnel identify generated by onos
+     * @param annotations parameter
+     * @return Tunnel subscribed tunnel
      */
-    Iterable<Tunnel> getEgressTunnels(ConnectPoint src);
+    Tunnel borrowTunnel(ApplicationId consumerId, TunnelId tunnelId,
+                           Annotations... annotations);
 
     /**
-     * Returns all tunnels ingressing to the specified connection point.
+     * Returns a specific tunnel by tunnelName. Annotations parameter is
+     * reserved. If there is no tunnel in the store, return a "null" object,and
+     * record the tunnel subscription. Where tunnel is created, ONOS notifies this consumer
+     * actively.
      *
-     * @param dst destination connection point
-     * @return set of connection point tunnels
+     * @param consumerId a tunnel consumer
+     * @param tunnelName tunnel name
+     * @param annotations parameter
+     * @return collection of subscribed Tunnels
      */
-    Iterable<Tunnel> getIngressTunnels(ConnectPoint dst);
+    Collection<Tunnel> borrowTunnel(ApplicationId consumerId,
+                                       TunnelName tunnelName,
+                                       Annotations... annotations);
 
     /**
-     * Creates a new tunnel based on the given information.
+     * Returns all tunnels between source and destination. Annotations
+     * parameter is reserved. If there is no any tunnel in the store, return a
+     * empty collection, and record the tunnel subscription. Where tunnel is created, ONOS
+     * notifies this consumer actively. Otherwise ONOS core returns all the
+     * tunnels, consumer determined which one to use.
      *
-     * @param providerId    provider identity (e.g., PCEP provider)
-     * @param tunnel tunnel information
-     * @return create tunnel event
+     * @param consumerId a tunnel consumer
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel
+     * @param annotations parameter
+     * @return collection of subscribed Tunnels
      */
-    TunnelEvent addTunnel(ProviderId providerId,
-                                        Tunnel tunnel);
+    Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src,
+                                       TunnelEndPoint dst, Annotations... annotations);
 
     /**
-     * Updates a new tunnel based on the given information.
+     * Returns all specified type tunnels between source and destination.
+     * Annotations parameter is reserved. If there is no any tunnel in the store,
+     * return a empty collection, and record the tunnel subscription. Where tunnel is
+     * created, ONOS notifies this consumer actively. Otherwise,ONOS core returns
+     * all available tunnels, consumer determined which one to use.
      *
-     * @param providerId      provider identity (e.g., PCEP provider)
-     * @param tunnel tunnel
-     * @return update tunnel event
+     * @param consumerId a tunnel consumer
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel
+     * @param type tunnel type
+     * @param annotations Annotations
+     * @return collection of available Tunnels
      */
-    TunnelEvent updateTunnel(ProviderId providerId,
-                                        Tunnel tunnel);
+    Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src,
+                                       TunnelEndPoint dst, Type type,
+                                       Annotations... annotations);
 
     /**
-     * Removes a new tunnel based on the given information.
+     * Returns back a specific tunnel to store.
      *
-     * @param providerId      provider identity (e.g., PCEP provider)
-     * @param tunnel tunnel
-     * @return remove tunnel event
+     * @param consumerId a tunnel consumer
+     * @param tunnelId tunnel identify generated by ONOS
+     * @param annotations Annotations
+     * @return success or fail
      */
-    TunnelEvent removeTunnel(ProviderId providerId,
-                             Tunnel tunnel);
+    boolean returnTunnel(ApplicationId consumerId, TunnelId tunnelId,
+                              Annotations... annotations);
 
+    /**
+     * Returns all specific name tunnel back store. Annotations parameter is
+     * reserved.If there is no tunnel in the store, return a "null" object,and
+     * record the tunnel subscription. Where tunnel is created, ONOS notifies this consumer
+     * actively.
+     *
+     * @param consumerId a tunnel consumer
+     * @param tunnelName tunnel name
+     * @param annotations Annotations
+     * @return boolean
+     */
+    boolean returnTunnel(ApplicationId consumerId, TunnelName tunnelName,
+                              Annotations... annotations);
+
+    /**
+     * Returns all specific type tunnels between source and destination back
+     * store. Annotations parameter is reserved.
+     *
+     * @param consumerId a tunnel consumer
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel
+     * @param type tunnel type
+     * @param annotations Annotations
+     * @return success or fail
+     */
+    boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src,
+                              TunnelEndPoint dst, Type type,
+                              Annotations... annotations);
+
+    /**
+     * Returns all tunnels between source and destination back the store.
+     * Annotations parameter is reserved.
+     *
+     * @param consumerId a tunnel consumer
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel.
+     * @param annotations Annotations
+     * @return success or fail
+     */
+    boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src,
+                              TunnelEndPoint dst, Annotations... annotations);
+
+    /**
+     * Returns a tunnel by a specific tunnel identity.
+     *
+     * @param tunnelId tunnel identify generated by tunnel producer
+     * @return Tunnel
+     */
+    Tunnel queryTunnel(TunnelId tunnelId);
+
+    /**
+     * Returns all tunnel subscription record by consumer.
+     *
+     * @param consumerId consumer identity
+     * @return Collection of TunnelSubscription
+     */
+    Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId consumerId);
+
+    /**
+     * Returns all specified type tunnels.
+     *
+     * @param type tunnel type
+     * @return Collection of tunnels
+     */
+    Collection<Tunnel> queryTunnel(Type type);
+
+    /**
+     * Returns all tunnels between source point and destination point.
+     *
+     * @param src a source point of tunnel.
+     * @param dst a destination point of tunnel.
+     * @return Collection of tunnels
+     */
+    Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst);
+
+    /**
+     * Returns all tunnels.
+     * @return all tunnels
+     */
+    int tunnelCount();
 }
diff --git a/core/api/src/main/java/org/onosproject/net/tunnel/TunnelSubscription.java b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelSubscription.java
new file mode 100644
index 0000000..428e41c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/tunnel/TunnelSubscription.java
@@ -0,0 +1,138 @@
+package org.onosproject.net.tunnel;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.AbstractAnnotated;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.tunnel.Tunnel.Type;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Represents for a order that consumer subscribe tunnel. ONOS maintains request
+ * information, it means ONOS knows how much resource echo consumer uses in the
+ * ONOS. Although there is no a tunnel that consumer want to use, when producer
+ * creates a new tunnel, ONOS will notify the consumers that want to use it.
+ */
+public final class TunnelSubscription extends AbstractAnnotated {
+    private final ApplicationId consumerId;
+    private final TunnelEndPoint src;
+    private final TunnelEndPoint dst;
+    private final Type type;
+    private final TunnelId tunnelId;
+    private final TunnelName tunnelName;
+
+    /**
+     * Creates a TunnelSubscription.
+     *
+     * @param consumerId consumer identity
+     * @param src source tunnel end point of tunnel
+     * @param dst destination tunnel end point of tunnel
+     * @param tunnelId tunnel identity
+     * @param type tunnel type
+     * @param tunnelName the name of a tunnel
+     * @param annotations parameter
+     */
+    public TunnelSubscription(ApplicationId consumerId, TunnelEndPoint src,
+                 TunnelEndPoint dst, TunnelId tunnelId, Type type,
+                 TunnelName tunnelName, Annotations... annotations) {
+        super(annotations);
+        checkNotNull(consumerId, "consumerId cannot be null");
+        this.consumerId = consumerId;
+        this.src = src;
+        this.dst = dst;
+        this.type = type;
+        this.tunnelId = tunnelId;
+        this.tunnelName = tunnelName;
+    }
+
+    /**
+     * Returns consumer identity.
+     *
+     * @return consumerId consumer id
+     */
+    public ApplicationId consumerId() {
+        return consumerId;
+    }
+
+    /**
+     * Returns source point of tunnel.
+     *
+     * @return source point
+     */
+    public TunnelEndPoint src() {
+        return src;
+    }
+
+    /**
+     * Returns destination point of tunnel.
+     *
+     * @return destination point
+     */
+    public TunnelEndPoint dst() {
+        return dst;
+    }
+
+    /**
+     * Returns tunnel type.
+     *
+     * @return tunnel type
+     */
+    public Type type() {
+        return type;
+    }
+
+    /**
+     * Returns tunnel identity.
+     *
+     * @return tunnel id
+     */
+    public TunnelId tunnelId() {
+        return tunnelId;
+    }
+
+    /**
+     * Returns tunnel name.
+     *
+     * @return tunnel name
+     */
+    public TunnelName tunnelName() {
+        return tunnelName;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(consumerId, src, dst, type, tunnelId, tunnelName);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof TunnelSubscription) {
+            final TunnelSubscription other = (TunnelSubscription) obj;
+            return Objects.equals(this.src, other.src)
+                    && Objects.equals(this.dst, other.dst)
+                    && Objects.equals(this.consumerId, other.consumerId)
+                    && Objects.equals(this.type, other.type)
+                    && Objects.equals(this.tunnelId, other.tunnelId)
+                    && Objects.equals(this.tunnelName, other.tunnelName);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("src", src)
+                .add("dst", dst)
+                .add("consumerId", consumerId)
+                .add("type", type)
+                .add("tunnelId", tunnelId)
+                .add("tunnelName", tunnelName).toString();
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/tunnel/DefaultTunnelTest.java b/core/api/src/test/java/org/onosproject/net/tunnel/DefaultTunnelTest.java
new file mode 100644
index 0000000..7ea5be2
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/tunnel/DefaultTunnelTest.java
@@ -0,0 +1,47 @@
+package org.onosproject.net.tunnel;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.net.provider.ProviderId;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Test of the default tunnel model entity.
+ */
+public class DefaultTunnelTest {
+    /**
+     * Checks that the Order class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultTunnel.class);
+    }
+
+    @Test
+    public void testEquality() {
+        TunnelEndPoint src = IpTunnelEndPoint.ipTunnelPoint(IpAddress
+                .valueOf(23423));
+        TunnelEndPoint dst = IpTunnelEndPoint.ipTunnelPoint(IpAddress
+                .valueOf(32421));
+        DefaultGroupId groupId = new DefaultGroupId(92034);
+        TunnelName tunnelName = TunnelName.tunnelName("TunnelName");
+        TunnelId tunnelId = TunnelId.valueOf(41654654);
+        ProviderId producerName1 = new ProviderId("producer1", "13");
+        ProviderId producerName2 = new ProviderId("producer2", "13");
+        Tunnel p1 = new DefaultTunnel(producerName1, src, dst, Tunnel.Type.VXLAN,
+                                      Tunnel.State.ACTIVE, groupId, tunnelId,
+                                      tunnelName);
+        Tunnel p2 = new DefaultTunnel(producerName1, src, dst, Tunnel.Type.VXLAN,
+                                      Tunnel.State.ACTIVE, groupId, tunnelId,
+                                      tunnelName);
+        Tunnel p3 = new DefaultTunnel(producerName2, src, dst, Tunnel.Type.OCH,
+                                      Tunnel.State.ACTIVE, groupId, tunnelId,
+                                      tunnelName);
+        new EqualsTester().addEqualityGroup(p1, p2).addEqualityGroup(p3)
+                .testEquals();
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/tunnel/TunnelEventTest.java b/core/api/src/test/java/org/onosproject/net/tunnel/TunnelEventTest.java
new file mode 100644
index 0000000..06a1f09
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/tunnel/TunnelEventTest.java
@@ -0,0 +1,46 @@
+package org.onosproject.net.tunnel;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.net.provider.ProviderId;
+
+/**
+ * Test of a tunnel event.
+ */
+public class TunnelEventTest {
+    /**
+     * Checks that the Order class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(TunnelEvent.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testConstructor() {
+        TunnelEndPoint src = IpTunnelEndPoint.ipTunnelPoint(IpAddress
+                .valueOf(23423));
+        TunnelEndPoint dst = IpTunnelEndPoint.ipTunnelPoint(IpAddress
+                .valueOf(32421));
+        DefaultGroupId groupId = new DefaultGroupId(92034);
+        TunnelName tunnelName = TunnelName.tunnelName("TunnelName");
+        TunnelId tunnelId = TunnelId.valueOf(41654654);
+        ProviderId producerName1 = new ProviderId("producer1", "13");
+        Tunnel p1 = new DefaultTunnel(producerName1, src, dst, Tunnel.Type.VXLAN,
+                                      Tunnel.State.ACTIVE, groupId, tunnelId,
+                                      tunnelName);
+        TunnelEvent e1 = new TunnelEvent(TunnelEvent.Type.TUNNEL_ADDED, p1);
+        assertThat(e1, is(notNullValue()));
+        assertThat(e1.type(), is(TunnelEvent.Type.TUNNEL_ADDED));
+        assertThat(e1.subject(), is(p1));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/tunnel/TunnelIdTest.java b/core/api/src/test/java/org/onosproject/net/tunnel/TunnelIdTest.java
new file mode 100644
index 0000000..aeba1e6
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/tunnel/TunnelIdTest.java
@@ -0,0 +1,50 @@
+package org.onosproject.net.tunnel;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for tunnel id class.
+ */
+public class TunnelIdTest {
+
+    final TunnelId tunnelId1 = TunnelId.valueOf(1);
+    final TunnelId sameAstunnelId1 = TunnelId.valueOf(1);
+    final TunnelId tunnelId2 = TunnelId.valueOf(2);
+
+    /**
+     * Checks that the TunnelId class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(TunnelId.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+        new EqualsTester()
+                .addEqualityGroup(tunnelId1, sameAstunnelId1)
+                .addEqualityGroup(tunnelId2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the construction of a FlowId object.
+     */
+    @Test
+    public void testConstruction() {
+        final long tunnelIdValue = 7777L;
+        final TunnelId tunnelId = TunnelId.valueOf(tunnelIdValue);
+        assertThat(tunnelId, is(notNullValue()));
+        assertThat(tunnelId.id(), is(tunnelIdValue));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/tunnel/TunnelNameTest.java b/core/api/src/test/java/org/onosproject/net/tunnel/TunnelNameTest.java
new file mode 100644
index 0000000..87421db
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/tunnel/TunnelNameTest.java
@@ -0,0 +1,48 @@
+package org.onosproject.net.tunnel;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for tunnel name class.
+ */
+public class TunnelNameTest {
+    final TunnelName name1 = TunnelName.tunnelName("name1");
+    final TunnelName sameAsName1 = TunnelName.tunnelName("name1");
+    final TunnelName name2 = TunnelName.tunnelName("name2");
+
+    /**
+     * Checks that the TunnelName class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(TunnelName.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+        new EqualsTester().addEqualityGroup(name1, sameAsName1)
+                .addEqualityGroup(name2).testEquals();
+    }
+
+    /**
+     * Checks the construction of a OpenFlowGroupId object.
+     */
+    @Test
+    public void testConstruction() {
+        final String nameValue = "name3";
+        final TunnelName name = TunnelName.tunnelName(nameValue);
+        assertThat(name, is(notNullValue()));
+        assertThat(name.value(), is(nameValue));
+    }
+
+}
diff --git a/core/api/src/test/java/org/onosproject/net/tunnel/TunnelSubscriptionTest.java b/core/api/src/test/java/org/onosproject/net/tunnel/TunnelSubscriptionTest.java
new file mode 100644
index 0000000..682796a
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/tunnel/TunnelSubscriptionTest.java
@@ -0,0 +1,43 @@
+package org.onosproject.net.tunnel;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Test of order model entity.
+ */
+public class TunnelSubscriptionTest {
+    /**
+     * Checks that the Order class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(TunnelSubscription.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquality() {
+        TunnelEndPoint src = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(23423));
+        TunnelEndPoint dst = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(32421));
+        ApplicationId appId = new DefaultApplicationId(243, "test");
+        ApplicationId appId2 = new DefaultApplicationId(2431, "test1");
+        TunnelId tunnelId = TunnelId.valueOf(41654654);
+        TunnelSubscription p1 = new TunnelSubscription(appId, src, dst, tunnelId, Tunnel.Type.VXLAN,
+                             null);
+        TunnelSubscription p2 = new TunnelSubscription(appId, src, dst, tunnelId, Tunnel.Type.VXLAN,
+                             null);
+        TunnelSubscription p3 = new TunnelSubscription(appId2, src, dst, tunnelId, Tunnel.Type.VXLAN,
+                             null);
+        new EqualsTester().addEqualityGroup(p1, p2).addEqualityGroup(p3)
+                .testEquals();
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/tunnel/impl/TunnelManager.java b/core/net/src/main/java/org/onosproject/net/tunnel/impl/TunnelManager.java
index 9d42836..563651c 100644
--- a/core/net/src/main/java/org/onosproject/net/tunnel/impl/TunnelManager.java
+++ b/core/net/src/main/java/org/onosproject/net/tunnel/impl/TunnelManager.java
@@ -15,52 +15,54 @@
  */
 package org.onosproject.net.tunnel.impl;
 
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+
 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.apache.felix.scr.annotations.Service;
+import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.event.EventDeliveryService;
 import org.onosproject.event.ListenerRegistry;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
+import org.onosproject.net.Annotations;
 import org.onosproject.net.Path;
 import org.onosproject.net.link.LinkEvent;
 import org.onosproject.net.link.LinkListener;
 import org.onosproject.net.provider.AbstractProviderRegistry;
 import org.onosproject.net.provider.AbstractProviderService;
 import org.onosproject.net.provider.ProviderId;
-import org.onosproject.net.resource.BandwidthResource;
-import org.onosproject.net.tunnel.Label;
 import org.onosproject.net.tunnel.Tunnel;
 import org.onosproject.net.tunnel.Tunnel.Type;
 import org.onosproject.net.tunnel.TunnelAdminService;
 import org.onosproject.net.tunnel.TunnelDescription;
+import org.onosproject.net.tunnel.TunnelEndPoint;
 import org.onosproject.net.tunnel.TunnelEvent;
 import org.onosproject.net.tunnel.TunnelId;
 import org.onosproject.net.tunnel.TunnelListener;
+import org.onosproject.net.tunnel.TunnelName;
 import org.onosproject.net.tunnel.TunnelProvider;
 import org.onosproject.net.tunnel.TunnelProviderRegistry;
 import org.onosproject.net.tunnel.TunnelProviderService;
 import org.onosproject.net.tunnel.TunnelService;
 import org.onosproject.net.tunnel.TunnelStore;
 import org.onosproject.net.tunnel.TunnelStoreDelegate;
+import org.onosproject.net.tunnel.TunnelSubscription;
 import org.slf4j.Logger;
 
-import java.util.Collection;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-
-import static org.slf4j.LoggerFactory.getLogger;
-
 /**
  * Provides implementation of the tunnel NB/SB APIs.
  */
 @Component(immediate = true, enabled = true)
 @Service
-public class TunnelManager extends AbstractProviderRegistry<TunnelProvider, TunnelProviderService>
+public class TunnelManager
+        extends AbstractProviderRegistry<TunnelProvider, TunnelProviderService>
         implements TunnelService, TunnelAdminService, TunnelProviderRegistry {
 
     private static final String TUNNNEL_ID_NULL = "Tunnel ID cannot be null";
@@ -120,53 +122,6 @@
         // TODO Auto-generated method stub
         return null;
     }
-    @Override
-    public void removeTunnels(Label src, Label dst) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeTunnels(ConnectPoint connectPoint) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeTunnels(DeviceId deviceId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public int getTunnelCount() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public Collection<Tunnel> getTunnels(Type type) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Set<Tunnel> getTunnels(ConnectPoint connectPoint, Type type) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Tunnel getTunnel(Label src, Label dst) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Tunnel getTunnel(TunnelId id) {
-        // TODO Auto-generated method stub
-        return null;
-    }
 
     @Override
     public void addListener(TunnelListener listener) {
@@ -205,9 +160,9 @@
         }
 
         @Override
-        public void tunnelAdded(TunnelDescription tunnel) {
+        public TunnelId tunnelAdded(TunnelDescription tunnel) {
             // TODO Auto-generated method stub
-
+            return null;
         }
 
         @Override
@@ -235,33 +190,21 @@
     }
 
     @Override
-    public void requestTunnel(ConnectPoint src, ConnectPoint dst,
-                                BandwidthResource bw, Path path) {
-        // TODO Auto-generated method stub
-    }
-
-
-    @Override
-    public void requestTunnel(ConnectPoint src, ConnectPoint dst, Type type,
-                              BandwidthResource bw, Path path) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
     public void removeTunnel(TunnelId tunnelId) {
         // TODO Auto-generated method stub
 
     }
 
     @Override
-    public void removeTunnels(ConnectPoint src, ConnectPoint dst) {
+    public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst,
+                              ProviderId producerName) {
         // TODO Auto-generated method stub
 
     }
 
     @Override
-    public void removeTunnels(ConnectPoint src, ConnectPoint dst, Type type) {
+    public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst,
+                              Type type, ProviderId producerName) {
         // TODO Auto-generated method stub
 
     }
@@ -273,9 +216,95 @@
     }
 
     @Override
-    public Collection<Tunnel> getTunnels(ConnectPoint src, ConnectPoint dst,
-                                       Type type) {
+    public Tunnel borrowTunnel(ApplicationId consumerId, TunnelId tunnelId,
+                               Annotations... annotations) {
         // TODO Auto-generated method stub
         return null;
     }
+
+    @Override
+    public Collection<Tunnel> borrowTunnel(ApplicationId consumerId,
+                                           TunnelName tunnelName,
+                                           Annotations... annotations) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Collection<Tunnel> borrowTunnel(ApplicationId consumerId,
+                                           TunnelEndPoint src,
+                                           TunnelEndPoint dst,
+                                           Annotations... annotations) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Collection<Tunnel> borrowTunnel(ApplicationId consumerId,
+                                           TunnelEndPoint src,
+                                           TunnelEndPoint dst, Type type,
+                                           Annotations... annotations) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean returnTunnel(ApplicationId consumerId, TunnelId tunnelId,
+                                Annotations... annotations) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean returnTunnel(ApplicationId consumerId,
+                                TunnelName tunnelName, Annotations... annotations) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src,
+                                TunnelEndPoint dst, Type type,
+                                Annotations... annotations) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src,
+                                TunnelEndPoint dst, Annotations... annotations) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Tunnel queryTunnel(TunnelId tunnelId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId consumerId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Collection<Tunnel> queryTunnel(Type type) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int tunnelCount() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
 }