[ONOS-4842] Leafref implementation for augment and uses
Change-Id: I919553a64d683aff65a8f16e2de783702dd5a45f
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java
index 571873b..c4091a9 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java
@@ -22,8 +22,10 @@
 /**
  * Abstraction of YANG resolvable information. Abstracted to obtain the
  * information required for linking resolution.
+ *
+ * @param <T>  YANG resolvable info
  */
-public interface Resolvable {
+public interface Resolvable<T> {
 
     /**
      * Returns the status of resolution. If completely resolved returns enum
@@ -48,8 +50,9 @@
     /**
      * Resolves the linking.
      *
+     * @return list of entities to be added for resolution
      * @throws DataModelException data model exception
      */
-    void resolve()
+    T resolve()
             throws DataModelException;
 }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangAugment.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangAugment.java
index 6d475cb..21c7bd3 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangAugment.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangAugment.java
@@ -442,8 +442,9 @@
     }
 
     @Override
-    public void resolve() throws DataModelException {
+    public Object resolve() throws DataModelException {
         // Resolving of target node is being done in XPathLinker.
+        return null;
     }
 
     /**
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBase.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBase.java
index 40c2293..8d118d2 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBase.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBase.java
@@ -109,6 +109,7 @@
     }
 
     @Override
-    public void resolve() throws DataModelException {
+    public Object resolve() throws DataModelException {
+        return null;
     }
 }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java
index b7bdf08..7aa0d5d 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java
@@ -18,6 +18,7 @@
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
+
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.datamodel.utils.Parsable;
 import org.onosproject.yangutils.datamodel.utils.YangConstructType;
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangEntityToResolveInfoImpl.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangEntityToResolveInfoImpl.java
new file mode 100644
index 0000000..8fe6b22
--- /dev/null
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangEntityToResolveInfoImpl.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2016-present 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.yangutils.datamodel;
+
+import java.io.Serializable;
+
+/**
+ * Represents implementation of information about entity being resolved.
+ *
+ * @param <T> type of entity being resolved, uses / grouping
+ */
+public class YangEntityToResolveInfoImpl<T> implements YangEntityToResolveInfo<T>, Serializable, LocationInfo {
+
+    private static final long serialVersionUID = 806201659L;
+
+    /**
+     * Parsable node for which resolution is to be performed.
+     */
+    private T entityToResolve;
+
+    /**
+     * Holder of the YANG construct for which resolution has to be carried out.
+     */
+    private YangNode holderOfEntityToResolve;
+
+    /**
+     * Error line number.
+     */
+    private transient int lineNumber;
+
+    /**
+     * Error character position in number.
+     */
+    private transient int charPositionInLine;
+
+    @Override
+    public T getEntityToResolve() {
+        return entityToResolve;
+    }
+
+    @Override
+    public void setEntityToResolve(T entityToResolve) {
+        this.entityToResolve = entityToResolve;
+    }
+
+    @Override
+    public YangNode getHolderOfEntityToResolve() {
+        return holderOfEntityToResolve;
+    }
+
+    @Override
+    public void setHolderOfEntityToResolve(YangNode holderOfEntityToResolve) {
+        this.holderOfEntityToResolve = holderOfEntityToResolve;
+    }
+
+    @Override
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    @Override
+    public int getCharPosition() {
+        return charPositionInLine;
+    }
+
+    @Override
+    public void setLineNumber(int lineNumber) {
+        this.lineNumber = lineNumber;
+    }
+
+    @Override
+    public void setCharPosition(int charPositionInLine) {
+        this.charPositionInLine = charPositionInLine;
+    }
+}
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIdentityRef.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIdentityRef.java
index d03fcf4..2019339 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIdentityRef.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIdentityRef.java
@@ -80,7 +80,7 @@
     }
 
     @Override
-    public void resolve() throws DataModelException {
+    public Object resolve() throws DataModelException {
 
         // Check if the derived info is present.
         YangIdentity identity = getReferredIdentity();
@@ -92,10 +92,11 @@
         while (identity.getBaseNode() != null) {
             if (identity.getBaseNode().getResolvableStatus() != ResolvableStatus.RESOLVED) {
                 setResolvableStatus(ResolvableStatus.INTRA_FILE_RESOLVED);
-                return;
+                return null;
             }
             identity = identity.getBaseNode().getReferredIdentity();
         }
+        return null;
     }
 
     /**
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIfFeature.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIfFeature.java
index a44fbdc..c2c8709 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIfFeature.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIfFeature.java
@@ -170,7 +170,7 @@
     }
 
     @Override
-    public void resolve() throws DataModelException {
+    public Object resolve() throws DataModelException {
         YangFeature feature = getReferredFeature();
 
         // check whether feature has if-feature
@@ -181,9 +181,10 @@
                 YangIfFeature ifFeature = ifFeatureIterator.next();
                 if (ifFeature.getResolvableStatus() != ResolvableStatus.RESOLVED) {
                     setResolvableStatus(ResolvableStatus.INTRA_FILE_RESOLVED);
-                    return;
+                    return null;
                 }
             }
         }
+        return null;
     }
 }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
index 4973303..104d701 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
@@ -16,17 +16,18 @@
 
 package org.onosproject.yangutils.datamodel;
 
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.datamodel.utils.Parsable;
 import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
 import org.onosproject.yangutils.datamodel.utils.YangConstructType;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
 import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
 import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
 import static org.onosproject.yangutils.datamodel.utils.YangErrMsgConstants.DATA_MISSING_ERROR_TAG;
@@ -47,7 +48,7 @@
  * @param <T> YANG leafref info
  */
 public class YangLeafRef<T> implements Parsable, Resolvable, Serializable, YangIfFeatureHolder,
-        YangXPathResolver, YangAppErrorHolder {
+        YangXPathResolver, YangAppErrorHolder, LocationInfo {
 
     private static final long serialVersionUID = 286201644L;
 
@@ -100,6 +101,61 @@
     private List<YangIfFeature> ifFeatureList;
 
     /**
+     * Parent node of the leafref's leaf.
+     */
+    private YangNode parentNodeOfLeafref;
+
+    /**
+     * Error line number.
+     */
+    private transient int lineNumber;
+
+    /**
+     * Error character position in number.
+     */
+    private transient int charPositionInLine;
+
+    /**
+     * Prefix in the nodes of the leafref path and its imported node name.
+     */
+    private Map<String, String> prefixAndItsImportedModule;
+
+    /**
+     * Returns the prefix in the leafref path and its imported node name.
+     *
+     * @return the list of leafref prefix and imported node name
+     */
+    public Map<String, String> getPrefixAndItsImportedModule() {
+        return prefixAndItsImportedModule;
+    }
+
+    /**
+     * Sets the prefix in the leafref path and its imported node name.
+     *
+     * @param prefixAndItsImportedModule the list of leafref prefix and imported node name
+     */
+    public void setPrefixAndItsImportedModule(Map<String, String> prefixAndItsImportedModule) {
+        this.prefixAndItsImportedModule = prefixAndItsImportedModule;
+    }
+
+    /**
+     * Returns the parent node from the leafref's leaf.
+     *
+     * @return parent node of the leafref
+     */
+    public YangNode getParentNodeOfLeafref() {
+        return parentNodeOfLeafref;
+    }
+
+    /**
+     * Sets the parent node from the leafref's leaf.
+     *
+     * @param parentNodeOfLeafref parent node of the leafref
+     */
+    public void setParentNodeOfLeafref(YangNode parentNodeOfLeafref) {
+        this.parentNodeOfLeafref = parentNodeOfLeafref;
+    }
+    /**
      * YANG application error information.
      */
     private YangAppErrorInfo yangAppErrorInfo;
@@ -294,7 +350,7 @@
     }
 
     @Override
-    public void resolve() throws DataModelException {
+    public Object resolve() throws DataModelException {
 
         if (getReferredLeafOrLeafList() == null) {
             throw new DataModelException("Linker Error: The leafref does not refer to any leaf/leaf-list.");
@@ -306,6 +362,7 @@
         } catch (DataModelException e) {
             throw new DataModelException(e.getMessage());
         }
+        return null;
     }
 
     /**
@@ -443,4 +500,24 @@
             throw new DataModelException("Linker Error: The leafref must refer only to leaf/leaf-list.");
         }
     }
+
+    @Override
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    @Override
+    public int getCharPosition() {
+        return charPositionInLine;
+    }
+
+    @Override
+    public void setLineNumber(int lineNumber) {
+        this.lineNumber = lineNumber;
+    }
+
+    @Override
+    public void setCharPosition(int charPositionInLine) {
+        this.charPositionInLine = charPositionInLine;
+    }
 }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangList.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangList.java
index d5eafb1..2b2426a 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangList.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangList.java
@@ -16,15 +16,15 @@
 
 package org.onosproject.yangutils.datamodel;
 
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.datamodel.utils.Parsable;
 import org.onosproject.yangutils.datamodel.utils.YangConstructType;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
 
 /*
@@ -119,6 +119,26 @@
     private List<String> keyList;
 
     /**
+     * Reference RFC 6020.
+     *
+     * The "unique" statement is used to put constraints on valid list
+     * entries.  It takes as an argument a string that contains a space-
+     * separated list of schema node identifiers, which MUST be given in the
+     * descendant form.  Each such schema node identifier MUST refer to a leaf.
+     *
+     * If one of the referenced leafs represents configuration data, then
+     * all of the referenced leafs MUST represent configuration data.
+     *
+     * The "unique" constraint specifies that the combined values of all the
+     * leaf instances specified in the argument string, including leafs with
+     * default values, MUST be unique within all list entry instances in
+     * which all referenced leafs exist.
+     *
+     * List of unique leaf/leaf-list names
+     */
+    private List<String> uniqueList;
+
+    /**
      * List of leaves.
      */
     private List<YangLeaf> listOfLeaf;
@@ -271,6 +291,24 @@
     }
 
     /**
+     * Returns the list of unique field names.
+     *
+     * @return the list of unique field names
+     */
+    public List<String> getUniqueList() {
+        return uniqueList;
+    }
+
+    /**
+     * Sets the list of unique field names.
+     *
+     * @param uniqueList the list of unique field names
+     */
+    private void setUniqueList(List<String> uniqueList) {
+        this.uniqueList = uniqueList;
+    }
+
+    /**
      * Returns the list of key field names.
      *
      * @return the list of key field names
@@ -309,6 +347,24 @@
     }
 
     /**
+     * Adds a unique field name.
+     *
+     * @param unique unique field name.
+     * @throws DataModelException a violation of data model rules
+     */
+    public void addUnique(String unique)
+            throws DataModelException {
+        if (getUniqueList() == null) {
+            setUniqueList(new LinkedList<>());
+        }
+        if (getUniqueList().contains(unique)) {
+            throw new DataModelException("A leaf identifier must not appear more than once in the\n" +
+                    "   unique");
+        }
+        getUniqueList().add(unique);
+    }
+
+    /**
      * Returns the list of leaves.
      *
      * @return the list of leaves
@@ -489,11 +545,11 @@
         validateConfig(leaves, leafLists);
 
         /* A list must have atleast one key leaf if config is true */
-        if (isConfig && (keys == null || leaves == null && leafLists == null) && !isUsesPresentInList()
+        if (isConfig && (keys == null || leaves == null) && !isUsesPresentInList()
                 && !isListPresentInGrouping()) {
             throw new DataModelException("A list must have atleast one key leaf if config is true;");
         } else if (keys != null) {
-            validateKey(leaves, leafLists, keys);
+            validateKey(leaves, keys);
         }
     }
 
@@ -501,7 +557,7 @@
      * Sets the config's value to all leaf if leaf's config statement is not
      * specified.
      *
-     * @param leaves list of leaf attributes of YANG list
+     * @param leaves    list of leaf attributes of YANG list
      * @param leafLists list of leaf-list attributes of YANG list
      */
     private void setDefaultConfigValueToChild(List<YangLeaf> leaves, List<YangLeafList> leafLists) {
@@ -534,7 +590,7 @@
     /**
      * Validates config statement of YANG list.
      *
-     * @param leaves list of leaf attributes of YANG list
+     * @param leaves    list of leaf attributes of YANG list
      * @param leafLists list of leaf-list attributes of YANG list
      * @throws DataModelException a violation of data model rules
      */
@@ -567,16 +623,15 @@
     /**
      * Validates key statement of list.
      *
-     * @param leaves list of leaf attributes of list
+     * @param leaves    list of leaf attributes of list
      * @param leafLists list of leaf-list attributes of list
-     * @param keys list of key attributes of list
+     * @param keys      list of key attributes of list
      * @throws DataModelException a violation of data model rules
      */
-    private void validateKey(List<YangLeaf> leaves, List<YangLeafList> leafLists, List<String> keys)
+    private void validateKey(List<YangLeaf> leaves, List<String> keys)
             throws DataModelException {
         boolean leafFound = false;
         List<YangLeaf> keyLeaves = new LinkedList<>();
-        List<YangLeafList> keyLeafLists = new LinkedList<>();
 
         /*
          * 1. Leaf identifier must refer to a child leaf of the list 2. A leaf
@@ -597,20 +652,6 @@
                 }
             }
 
-            if (leafLists != null && !leafLists.isEmpty()) {
-                for (YangLeafList leafList : leafLists) {
-                    if (key.equals(leafList.getName())) {
-                        if (leafList.getDataType().getDataType() == YangDataTypes.EMPTY) {
-                            throw new DataModelException(" A leaf-list that is part of the key" +
-                                    " must not be the built-in type \"empty\".");
-                        }
-                        leafFound = true;
-                        keyLeafLists.add(leafList);
-                        break;
-                    }
-                }
-            }
-
             if (!leafFound && !isUsesPresentInList() && !isListPresentInGrouping()) {
                 throw new DataModelException("An identifier, in key, must refer to a child leaf of the list");
             }
@@ -627,17 +668,6 @@
                         " \"config\" as the list itself.");
             }
         }
-
-         /*
-         * All key leafs in a list MUST have the same value for their "config"
-         * as the list itself.
-         */
-        for (YangLeafList keyLeafList : keyLeafLists) {
-            if (isConfig() != keyLeafList.isConfig()) {
-                throw new DataModelException("All key leaf-lists in a list must have the same value for their" +
-                        " \"config\" as the list itself.");
-            }
-        }
     }
 
     @Override
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
index be90e76..381a39a 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
@@ -272,12 +272,12 @@
      * @throws CloneNotSupportedException clone is not supported by the referred
      *                                    node
      */
-    public YangNode clone()
+    public YangNode clone(YangUses yangUses)
             throws CloneNotSupportedException {
         YangNode clonedNode = (YangNode) super.clone();
         if (clonedNode instanceof YangLeavesHolder) {
             try {
-                cloneLeaves((YangLeavesHolder) clonedNode);
+                cloneLeaves((YangLeavesHolder) clonedNode, yangUses);
             } catch (DataModelException e) {
                 throw new CloneNotSupportedException(e.getMessage());
             }
@@ -299,7 +299,7 @@
      * @param dstRootNode destination node where the sub tree needs to be cloned
      * @throws DataModelException data model error
      */
-    public static void cloneSubTree(YangNode srcRootNode, YangNode dstRootNode)
+    public static void cloneSubTree(YangNode srcRootNode, YangNode dstRootNode, YangUses yangUses)
             throws DataModelException {
 
         YangNode nextNodeToClone = srcRootNode;
@@ -327,7 +327,7 @@
                     throw new DataModelException("Internal error: Cloning failed, source tree null pointer reached");
                 }
                 if (curTraversal != PARENT) {
-                    newNode = nextNodeToClone.clone();
+                    newNode = nextNodeToClone.clone(yangUses);
                     detectCollisionWhileCloning(clonedTreeCurNode, newNode, curTraversal);
                 }
 
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
index c0ac20d..d49241e 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
@@ -239,7 +239,7 @@
     }
 
     @Override
-    public void resolve()
+    public Object resolve()
             throws DataModelException {
         /*
          * Check whether the data type is derived.
@@ -260,6 +260,7 @@
         } catch (DataModelException e) {
             throw new DataModelException(e.getMessage());
         }
+        return null;
     }
 
     /**
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
index 51cd310..5cd1e7a 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
@@ -26,6 +26,8 @@
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.getParentNodeInGenCode;
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.updateClonedLeavesUnionEnumRef;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveLeafrefUnderGroupingForLeaf;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveLeafrefUnderGroupingForLeafList;
 
 /*-
  * Reference RFC 6020.
@@ -126,6 +128,16 @@
     private List<List<YangLeafList>> resolvedGroupingLeafLists;
 
     /**
+     * Effective list of leaf lists of grouping that needs to replicated at YANG uses.
+     */
+    private List<YangEntityToResolveInfoImpl> entityToResolveInfoList;
+
+    /**
+     * Current grouping depth for uses.
+     */
+    private int currentGroupingDepth;
+
+    /**
      * Creates an YANG uses node.
      */
     public YangUses() {
@@ -138,6 +150,38 @@
     }
 
     /**
+     * Returns the list of entity to resolve.
+     *
+     * @return the list of entity to resolve
+     */
+    public List<YangEntityToResolveInfoImpl> getEntityToResolveInfoList() {
+        return entityToResolveInfoList;
+    }
+
+    /**
+     * Sets the list of entity to resolve.
+     *
+     * @param entityToResolveInfoList the list of entity to resolve
+     */
+    public void setEntityToResolveInfoList(List<YangEntityToResolveInfoImpl> entityToResolveInfoList) {
+        this.entityToResolveInfoList = entityToResolveInfoList;
+    }
+
+    /**
+     * Adds an entity to resolve in list.
+     *
+     * @param entityToResolve entity to resolved
+     * @throws DataModelException a violation of data model rules
+     */
+    public void addEntityToResolve(YangEntityToResolveInfoImpl entityToResolve)
+            throws DataModelException {
+        if (getEntityToResolveInfoList() == null) {
+            setEntityToResolveInfoList(new LinkedList<YangEntityToResolveInfoImpl>());
+        }
+        getEntityToResolveInfoList().add(entityToResolve);
+    }
+
+    /**
      * Returns the referred group.
      *
      * @return the referred group
@@ -314,7 +358,7 @@
     }
 
     @Override
-    public void resolve()
+    public Object resolve()
             throws DataModelException {
 
         YangGrouping referredGrouping = getRefGroup();
@@ -337,7 +381,13 @@
                     ((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leaf.getName(),
                             YangConstructType.LEAF_DATA);
                     clonedLeaf = leaf.clone();
-
+                    if (getCurrentGroupingDepth() == 0) {
+                        YangEntityToResolveInfoImpl resolveInfo = resolveLeafrefUnderGroupingForLeaf(clonedLeaf,
+                                usesParentLeavesHolder, this);
+                        if (resolveInfo != null) {
+                            addEntityToResolve(resolveInfo);
+                        }
+                    }
                 } catch (CloneNotSupportedException | DataModelException e) {
                     throw new DataModelException(e.getMessage());
                 }
@@ -353,7 +403,13 @@
                     ((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leafList.getName(),
                             YangConstructType.LEAF_LIST_DATA);
                     clonedLeafList = leafList.clone();
-
+                    if (getCurrentGroupingDepth() == 0) {
+                        YangEntityToResolveInfoImpl resolveInfo =
+                                    resolveLeafrefUnderGroupingForLeafList(clonedLeafList, usesParentLeavesHolder);
+                        if (resolveInfo != null) {
+                            addEntityToResolve(resolveInfo);
+                        }
+                    }
                 } catch (CloneNotSupportedException | DataModelException e) {
                     throw new DataModelException(e.getMessage());
                 }
@@ -364,11 +420,12 @@
         }
 
         try {
-            YangNode.cloneSubTree(referredGrouping, usesParentNode);
+            YangNode.cloneSubTree(referredGrouping, usesParentNode, this);
         } catch (DataModelException e) {
             throw new DataModelException(e.getMessage());
         }
         updateClonedLeavesUnionEnumRef(usesParentLeavesHolder);
+        return getEntityToResolveInfoList();
     }
 
     /**
@@ -378,7 +435,7 @@
      * @param usesHolder     holder of uses
      */
     private void addResolvedUsesInfoOfGrouping(YangUses usesInGrouping,
-            YangLeavesHolder usesHolder) throws DataModelException {
+                                               YangLeavesHolder usesHolder) throws DataModelException {
         for (YangNode usesResolvedNode : usesInGrouping.getUsesResolvedNodeList()) {
             addNodeOfGrouping(usesResolvedNode);
         }
@@ -402,7 +459,7 @@
      * @throws DataModelException a violation in data model rule
      */
     private List<YangLeaf> cloneLeavesList(List<YangLeaf> listOfLeaves,
-            YangLeavesHolder usesParentNode) throws DataModelException {
+                                           YangLeavesHolder usesParentNode) throws DataModelException {
         if (listOfLeaves == null || listOfLeaves.size() == 0) {
             throw new DataModelException("No leaves to clone");
         }
@@ -433,7 +490,7 @@
      * @return cloned list of leaf list
      */
     private List<YangLeafList> cloneListOfLeafList(List<YangLeafList> listOfLeafList,
-            YangLeavesHolder usesParentNode) throws DataModelException {
+                                                   YangLeavesHolder usesParentNode) throws DataModelException {
         if (listOfLeafList == null || listOfLeafList.size() == 0) {
             throw new DataModelException("No leaf lists to clone");
         }
@@ -556,4 +613,13 @@
     public void setIfFeatureList(List<YangIfFeature> ifFeatureList) {
         this.ifFeatureList = ifFeatureList;
     }
+
+    public void setCurrentGroupingDepth(int currentGroupingDepth) {
+        this.currentGroupingDepth = currentGroupingDepth;
+    }
+
+    public int getCurrentGroupingDepth() {
+        return currentGroupingDepth;
+    }
+
 }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
index 64f2c78..503bebe 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
@@ -16,25 +16,21 @@
 
 package org.onosproject.yangutils.datamodel.utils;
 
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
 import org.onosproject.yangutils.datamodel.CollisionDetector;
 import org.onosproject.yangutils.datamodel.ResolvableType;
-import org.onosproject.yangutils.datamodel.YangIfFeature;
+import org.onosproject.yangutils.datamodel.YangAtomicPath;
 import org.onosproject.yangutils.datamodel.YangAugment;
 import org.onosproject.yangutils.datamodel.YangBase;
+import org.onosproject.yangutils.datamodel.YangEntityToResolveInfoImpl;
 import org.onosproject.yangutils.datamodel.YangEnumeration;
 import org.onosproject.yangutils.datamodel.YangIdentityRef;
+import org.onosproject.yangutils.datamodel.YangIfFeature;
+import org.onosproject.yangutils.datamodel.YangImport;
 import org.onosproject.yangutils.datamodel.YangLeaf;
 import org.onosproject.yangutils.datamodel.YangLeafList;
 import org.onosproject.yangutils.datamodel.YangLeafRef;
 import org.onosproject.yangutils.datamodel.YangLeavesHolder;
+import org.onosproject.yangutils.datamodel.YangModule;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangReferenceResolver;
 import org.onosproject.yangutils.datamodel.YangResolutionInfo;
@@ -45,6 +41,16 @@
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 /**
  * Represents utilities for data model tree.
  */
@@ -206,7 +212,7 @@
      * @throws DataModelException a violation of data model rules
      */
     public static void resolveLinkingForResolutionList(List<YangResolutionInfo> resolutionList,
-            YangReferenceResolver dataModelRootNode)
+                                                       YangReferenceResolver dataModelRootNode)
             throws DataModelException {
 
         for (YangResolutionInfo resolutionInfo : resolutionList) {
@@ -222,7 +228,7 @@
      * @throws DataModelException a violation of data model rules
      */
     public static void linkInterFileReferences(List<YangResolutionInfo> resolutionList,
-            YangReferenceResolver dataModelRootNode)
+                                               YangReferenceResolver dataModelRootNode)
             throws DataModelException {
         /*
          * Run through the resolution list, find type/uses referring to inter
@@ -316,16 +322,24 @@
      * Clones the list of leaves and list of leaf list in the leaves holder.
      *
      * @param leavesHolder YANG node potentially containing leaves or leaf lists
+     * @param yangUses     instance of YANG uses
      * @throws CloneNotSupportedException clone is not supported
      * @throws DataModelException         data model error
      */
-    public static void cloneLeaves(YangLeavesHolder leavesHolder)
+    public static void cloneLeaves(YangLeavesHolder leavesHolder, YangUses yangUses)
             throws CloneNotSupportedException, DataModelException {
         List<YangLeaf> currentListOfLeaves = leavesHolder.getListOfLeaf();
         if (currentListOfLeaves != null) {
             List<YangLeaf> clonedLeavesList = new LinkedList<YangLeaf>();
             for (YangLeaf leaf : currentListOfLeaves) {
                 YangLeaf clonedLeaf = leaf.clone();
+                if (yangUses.getCurrentGroupingDepth() == 0) {
+                    YangEntityToResolveInfoImpl resolveInfo =
+                            resolveLeafrefUnderGroupingForLeaf(clonedLeaf, leavesHolder, yangUses);
+                    if (resolveInfo != null) {
+                        yangUses.addEntityToResolve(resolveInfo);
+                    }
+                }
                 clonedLeaf.setContainedIn(leavesHolder);
                 clonedLeavesList.add(clonedLeaf);
             }
@@ -337,6 +351,13 @@
             List<YangLeafList> clonedListOfLeafList = new LinkedList<YangLeafList>();
             for (YangLeafList leafList : currentListOfLeafList) {
                 YangLeafList clonedLeafList = leafList.clone();
+                if (yangUses.getCurrentGroupingDepth() == 0) {
+                    YangEntityToResolveInfoImpl resolveInfo =
+                            resolveLeafrefUnderGroupingForLeafList(clonedLeafList, leavesHolder);
+                    if (resolveInfo != null) {
+                        yangUses.addEntityToResolve(resolveInfo);
+                    }
+                }
                 clonedLeafList.setContainedIn(leavesHolder);
                 clonedListOfLeafList.add(clonedLeafList);
             }
@@ -345,6 +366,112 @@
     }
 
     /**
+     * Resolves leafref in leaf, which are under grouping by adding it to the resolution list.
+     *
+     * @param clonedLeaf       cloned leaf in uses from grouping
+     * @param leafParentHolder holder of the leaf from uses
+     * @return entity of leafref which has to be resolved
+     * @throws DataModelException data model error
+     */
+    public static YangEntityToResolveInfoImpl resolveLeafrefUnderGroupingForLeaf(YangLeaf clonedLeaf,
+                                                                                 YangLeavesHolder leafParentHolder,
+                                                                                 YangUses yangUses) throws
+            DataModelException {
+        if (clonedLeaf.getDataType().getDataTypeExtendedInfo() instanceof YangLeafRef) {
+            YangLeafRef leafrefForCloning = (YangLeafRef) clonedLeaf.getDataType().getDataTypeExtendedInfo();
+            // Conversion of prefixes in absolute path while cloning them.
+            convertThePrefixesDuringChange(leafrefForCloning, yangUses);
+            leafrefForCloning.setParentNodeOfLeafref((YangNode) leafParentHolder);
+            YangEntityToResolveInfoImpl yangEntityToResolveInfo = new YangEntityToResolveInfoImpl();
+            yangEntityToResolveInfo.setEntityToResolve(leafrefForCloning);
+            yangEntityToResolveInfo.setHolderOfEntityToResolve((YangNode) leafParentHolder);
+            yangEntityToResolveInfo.setLineNumber(leafrefForCloning.getLineNumber());
+            yangEntityToResolveInfo.setCharPosition(leafrefForCloning.getCharPosition());
+            return yangEntityToResolveInfo;
+        }
+        return null;
+    }
+
+    /**
+     * Converts the prefixes in all the nodes of the leafref with respect to the uses node.
+     *
+     * @param leafrefForCloning leafref that is to be cloned
+     * @param yangUses          instance of YANG uses where cloning is done
+     * @throws DataModelException data model error
+     */
+    private static void convertThePrefixesDuringChange(YangLeafRef leafrefForCloning, YangUses yangUses) throws
+            DataModelException {
+        List<YangAtomicPath> atomicPathList = leafrefForCloning.getAtomicPath();
+        if (atomicPathList != null && !atomicPathList.isEmpty()) {
+            Iterator<YangAtomicPath> atomicPathIterator = atomicPathList.listIterator();
+            while (atomicPathIterator.hasNext()) {
+                YangAtomicPath atomicPath = atomicPathIterator.next();
+                Map<String, String> prefixesAndItsImportNameNode = leafrefForCloning.getPrefixAndItsImportedModule();
+                if (!prefixesAndItsImportNameNode.isEmpty() || prefixesAndItsImportNameNode != null) {
+                    String prefixInPath = atomicPath.getNodeIdentifier().getPrefix();
+                    String importedNodeName = prefixesAndItsImportNameNode.get(prefixInPath);
+                    assignCurrentLeafrefWithNewPrefixes(importedNodeName, atomicPath, yangUses);
+                }
+            }
+        }
+    }
+
+    /**
+     * Assigns leafref with new prefixes while cloning.
+     *
+     * @param importedNodeName imported node name from grouping
+     * @param atomicPath       atomic path in leafref
+     * @param node             instance of YANG uses where cloning is done
+     * @throws DataModelException data model error
+     */
+    private static void assignCurrentLeafrefWithNewPrefixes(String importedNodeName, YangAtomicPath atomicPath,
+                                                            YangNode node) throws DataModelException {
+        while (!(node instanceof YangReferenceResolver)) {
+            node = node.getParent();
+            if (node == null) {
+                throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
+            }
+        }
+        if (node instanceof YangModule) {
+            List<YangImport> importInUsesList = ((YangModule) node).getImportList();
+            if (importInUsesList != null && !importInUsesList.isEmpty()) {
+                Iterator<YangImport> importInUsesListIterator = importInUsesList.listIterator();
+                while (importInUsesListIterator.hasNext()) {
+                    YangImport importInUsesNode = importInUsesListIterator.next();
+                    if (importInUsesNode.getModuleName().equals(importedNodeName)) {
+                        atomicPath.getNodeIdentifier().setPrefix(importInUsesNode.getPrefixId());
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Resolves leafref in leaf-list, which are under grouping by adding it to the resolution list.
+     *
+     * @param clonedLeafList       cloned leaf-list in uses from grouping
+     * @param leafListParentHolder holder of the leaf-list from uses
+     * @return entity of leafref which has to be resolved
+     * @throws DataModelException data model error
+     */
+    public static YangEntityToResolveInfoImpl resolveLeafrefUnderGroupingForLeafList(YangLeafList clonedLeafList,
+                                                                                     YangLeavesHolder
+                                                                                             leafListParentHolder)
+            throws DataModelException {
+        if (clonedLeafList.getDataType().getDataTypeExtendedInfo() instanceof YangLeafRef) {
+            YangLeafRef leafrefForCloning = (YangLeafRef) clonedLeafList.getDataType().getDataTypeExtendedInfo();
+            leafrefForCloning.setParentNodeOfLeafref((YangNode) leafListParentHolder);
+            YangEntityToResolveInfoImpl yangEntityToResolveInfo = new YangEntityToResolveInfoImpl();
+            yangEntityToResolveInfo.setEntityToResolve(leafrefForCloning);
+            yangEntityToResolveInfo.setHolderOfEntityToResolve((YangNode) leafListParentHolder);
+            yangEntityToResolveInfo.setLineNumber(leafrefForCloning.getLineNumber());
+            yangEntityToResolveInfo.setCharPosition(leafrefForCloning.getCharPosition());
+            return yangEntityToResolveInfo;
+        }
+        return null;
+    }
+
+    /**
      * Clones the union or enum leaves. If there is any cloned leaves whose type is union/enum then the corresponding
      * type info needs to be updated to the cloned new type node.
      *