diff --git a/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java b/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
index 72f8ac0..d07e516 100644
--- a/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
+++ b/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2015-2016 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.
@@ -21,7 +21,6 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
@@ -50,12 +49,12 @@
 public abstract class ResourcePath {
 
     private final Discrete parent;
-    private final Object last;
+    private final Key key;
 
     public static final Discrete ROOT = new Discrete();
 
     public static ResourcePath discrete(DeviceId device) {
-        return new Discrete(ImmutableList.of(device));
+        return new Discrete(Key.of(device));
     }
 
     /**
@@ -66,10 +65,7 @@
      * @return resource path instance
      */
     public static ResourcePath discrete(DeviceId device, Object... components) {
-        return new Discrete(ImmutableList.builder()
-                .add(device)
-                .add(components)
-                .build());
+        return new Discrete(Key.of(device, components));
     }
 
     /**
@@ -81,11 +77,7 @@
      * @return resource path instance
      */
     public static ResourcePath discrete(DeviceId device, PortNumber port, Object... components) {
-        return new Discrete(ImmutableList.builder()
-                .add(device)
-                .add(port)
-                .add(components)
-                .build());
+        return new Discrete(Key.of(device, port, components));
     }
 
     /**
@@ -100,10 +92,7 @@
         checkArgument(components.length > 0,
                 "Length of components must be greater thant 0, but " + components.length);
 
-        return new Continuous(ImmutableList.builder()
-                .add(device)
-                .add(components)
-                .build(), value);
+        return new Continuous(Key.of(device, components), value);
     }
 
     /**
@@ -116,49 +105,29 @@
      * @return resource path instance
      */
     public static ResourcePath continuous(double value, DeviceId device, PortNumber port, Object... components) {
-        return new Continuous(ImmutableList.builder()
-                .add(device)
-                .add(port)
-                .add(components)
-                .build(), value);
+        return new Continuous(Key.of(device, port, components), value);
     }
 
     /**
-     * Creates an resource path from the specified components.
+     * Creates an resource path from the specified key.
      *
-     * @param components components of the path. The order represents hierarchical structure of the resource.
+     * @param key key of the path
      */
-    protected ResourcePath(List<Object> components) {
-        checkNotNull(components);
-        checkArgument(!components.isEmpty());
+    protected ResourcePath(Key key) {
+        checkNotNull(key);
 
-        LinkedList<Object> children = new LinkedList<>(components);
-        this.last = children.pollLast();
-        if (children.isEmpty()) {
+        this.key = key;
+        if (key.components.size() == 1) {
             this.parent = ROOT;
         } else {
-            this.parent = new Discrete(children);
+            this.parent = new Discrete(key.parent());
         }
     }
 
-    /**
-     * Creates an resource path from the specified parent and child.
-     *
-     * @param parent the parent of this resource
-     * @param last a child of the parent
-     */
-    protected ResourcePath(Discrete parent, Object last) {
-        checkNotNull(parent);
-        checkNotNull(last);
-
-        this.parent = parent;
-        this.last = last;
-    }
-
     // for serialization
     private ResourcePath() {
         this.parent = null;
-        this.last = null;
+        this.key = Key.ROOT;
     }
 
     /**
@@ -167,15 +136,7 @@
      * @return the components of this resource path
      */
     public List<Object> components() {
-        LinkedList<Object> components = new LinkedList<>();
-
-        ResourcePath current = this;
-        while (current.parent().isPresent()) {
-            components.addFirst(current.last);
-            current = current.parent;
-        }
-
-        return components;
+        return key.components;
     }
 
     /**
@@ -199,7 +160,7 @@
     public ResourcePath child(Object child) {
         checkState(this instanceof Discrete);
 
-        return new Discrete((Discrete) this, child);
+        return new Discrete(key().child(child));
     }
 
     /**
@@ -213,7 +174,7 @@
     public ResourcePath child(Object child, double value) {
         checkState(this instanceof Discrete);
 
-        return new Continuous((Discrete) this, child, value);
+        return new Continuous(key.child(child), value);
     }
 
     /**
@@ -223,12 +184,24 @@
      * The return value is equal to the last object of {@code components()}.
      */
     public Object last() {
-        return last;
+        if (key.components.isEmpty()) {
+            return null;
+        }
+        return key.components.get(key.components.size() - 1);
+    }
+
+    /**
+     * Returns the key of this resource path.
+     *
+     * @return the key of this resource path
+     */
+    public Key key() {
+        return key;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(this.parent, this.last);
+        return key.hashCode();
     }
 
     @Override
@@ -240,15 +213,13 @@
             return false;
         }
         final ResourcePath that = (ResourcePath) obj;
-        return Objects.equals(this.parent, that.parent)
-                && Objects.equals(this.last, that.last);
+        return Objects.equals(this.key, that.key);
     }
 
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(this)
-                .add("parent", parent)
-                .add("last", last)
+                .add("key", key)
                 .toString();
     }
 
@@ -266,12 +237,8 @@
             super();
         }
 
-        private Discrete(List<Object> components) {
-            super(components);
-        }
-
-        private Discrete(Discrete parent, Object last) {
-            super(parent, last);
+        private Discrete(Key key) {
+            super(key);
         }
     }
 
@@ -284,17 +251,34 @@
      */
     @Beta
     public static final class Continuous extends ResourcePath {
-        // Note: value is not taken into account for equality
         private final double value;
 
-        private Continuous(List<Object> components, double value) {
-            super(components);
+        private Continuous(Key key, double value) {
+            super(key);
             this.value = value;
         }
 
-        public Continuous(Discrete parent, Object last, double value) {
-            super(parent, last);
-            this.value = value;
+        @Override
+        public int hashCode() {
+            return Objects.hash(this.key(), this.value);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+
+            if (!(obj instanceof Continuous)) {
+                return false;
+            }
+
+            if (!super.equals(obj)) {
+                return false;
+            }
+
+            final Continuous other = (Continuous) obj;
+            return Objects.equals(this.key(), other.key());
         }
 
         /**
@@ -306,4 +290,80 @@
             return value;
         }
     }
+
+    /**
+     * Represents key of resource path used as a key in ResourceStore.
+     * This class is exposed to public, but intended to use only in ResourceStore implementations.
+     */
+    @Beta
+    public static final class Key {
+        private static final Key ROOT = new Key();
+
+        private final ImmutableList<Object> components;
+
+        private static Key of(DeviceId device, Object... components) {
+            return new Key(ImmutableList.builder()
+                    .add(device)
+                    .add(components)
+                    .build());
+        }
+
+        private static Key of(DeviceId device, PortNumber port, Object... components) {
+            return new Key(ImmutableList.builder()
+                    .add(device)
+                    .add(port)
+                    .add(components)
+                    .build());
+        }
+
+        private Key(ImmutableList<Object> components) {
+            this.components = checkNotNull(components);
+        }
+
+        // for serializer
+        private Key() {
+            this.components = ImmutableList.of();
+        }
+
+        // IndexOutOfBoundsException is raised when the instance is equal to ROOT
+        private Key parent() {
+            if (components.size() == 1) {
+                return ROOT;
+            } else {
+                return new Key(components.subList(0, components.size() - 1));
+            }
+        }
+
+        private Key child(Object child) {
+            return new Key(ImmutableList.builder()
+                    .add(components)
+                    .add(child)
+                    .build());
+        }
+
+        @Override
+        public int hashCode() {
+            return components.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (!(obj instanceof Key)) {
+                return false;
+            }
+
+            Key other = (Key) obj;
+            return Objects.equals(this.components, other.components);
+        }
+
+        @Override
+        public String toString() {
+            return MoreObjects.toStringHelper(this)
+                    .add("components", components)
+                    .toString();
+        }
+    }
 }
