[ONOS-5402] Resolvable entities under union type, is added to list, after cloning.

Change-Id: Ia96959b3e65e12060926c7f15d170b5e7302fa43
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
index 6458e93..92af172 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
@@ -15,15 +15,17 @@
  */
 package org.onosproject.yangutils.datamodel;
 
-import java.io.Serializable;
-import java.util.Map;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.datamodel.utils.Parsable;
 
+import java.io.Serializable;
+import java.util.Map;
+
 import static org.onosproject.yangutils.datamodel.TraversalType.CHILD;
 import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
 import static org.onosproject.yangutils.datamodel.TraversalType.SIBILING;
-import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.cloneLeaves;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.cloneListOfLeaf;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.cloneListOfLeafList;
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.updateClonedLeavesUnionEnumRef;
 
 /**
@@ -400,7 +402,8 @@
         clonedNode.referredSchemaNode = this;
         if (clonedNode instanceof YangLeavesHolder) {
             try {
-                cloneLeaves((YangLeavesHolder) clonedNode, yangUses);
+                cloneListOfLeaf((YangLeavesHolder) clonedNode, yangUses);
+                cloneListOfLeafList((YangLeavesHolder) clonedNode, yangUses);
             } catch (DataModelException e) {
                 throw new CloneNotSupportedException(e.getMessage());
             }
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
index d358fdb..6143483 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
@@ -33,10 +33,9 @@
 import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.COLLISION_DETECTION;
 import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.USES;
 import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.getErrorMsgCollision;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addUnresolvedType;
 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.resolveYangConstructsUnderGroupingForLeaf;
-import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveYangConstructsUnderGroupingForLeafList;
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.updateClonedLeavesUnionEnumRef;
 import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
 import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
@@ -180,13 +179,14 @@
      * @param entityToResolve entity to resolved
      * @throws DataModelException a violation of data model rules
      */
-    public void addEntityToResolve(YangEntityToResolveInfoImpl entityToResolve)
+    public void addEntityToResolve(
+            List<YangEntityToResolveInfoImpl> entityToResolve)
             throws DataModelException {
         if (entityToResolveInfoList == null) {
             entityToResolveInfoList = new
                     LinkedList<>();
         }
-        entityToResolveInfoList.add(entityToResolve);
+        entityToResolveInfoList.addAll(entityToResolve);
     }
 
     /**
@@ -387,52 +387,39 @@
                             " in " + getFileName() + "\"");
         }
 
-        YangLeavesHolder usesParentLeavesHolder = (YangLeavesHolder) usesParentNode;
+        YangLeavesHolder usesParent = (YangLeavesHolder) usesParentNode;
         if (referredGrouping.getListOfLeaf() != null) {
             for (YangLeaf leaf : referredGrouping.getListOfLeaf()) {
                 YangLeaf clonedLeaf;
                 try {
-                    ((CollisionDetector) usesParentLeavesHolder)
+                    ((CollisionDetector) usesParent)
                             .detectCollidingChild(leaf.getName(), LEAF_DATA);
                     clonedLeaf = leaf.clone();
                     clonedLeaf.setReferredLeaf(leaf);
-                    if (getCurrentGroupingDepth() == 0) {
-                        YangEntityToResolveInfoImpl resolveInfo
-                                = resolveYangConstructsUnderGroupingForLeaf(
-                                clonedLeaf, usesParentLeavesHolder, this);
-                        if (resolveInfo != null) {
-                            addEntityToResolve(resolveInfo);
-                        }
-                    }
+                    addUnresolvedType(this, clonedLeaf, (YangNode) usesParent);
                 } catch (CloneNotSupportedException | DataModelException e) {
                     throw new DataModelException(e.getMessage());
                 }
 
-                clonedLeaf.setContainedIn(usesParentLeavesHolder);
-                usesParentLeavesHolder.addLeaf(clonedLeaf);
+                clonedLeaf.setContainedIn(usesParent);
+                usesParent.addLeaf(clonedLeaf);
             }
         }
         if (referredGrouping.getListOfLeafList() != null) {
             for (YangLeafList leafList : referredGrouping.getListOfLeafList()) {
                 YangLeafList clonedLeafList;
                 try {
-                    ((CollisionDetector) usesParentLeavesHolder)
+                    ((CollisionDetector) usesParent)
                             .detectCollidingChild(leafList.getName(), LEAF_LIST_DATA);
                     clonedLeafList = leafList.clone();
                     clonedLeafList.setReferredSchemaLeafList(leafList);
-                    if (getCurrentGroupingDepth() == 0) {
-                        YangEntityToResolveInfoImpl resolveInfo =
-                                resolveYangConstructsUnderGroupingForLeafList(
-                                        clonedLeafList, usesParentLeavesHolder, this);
-                        if (resolveInfo != null) {
-                            addEntityToResolve(resolveInfo);
-                        }
-                    }
+                    addUnresolvedType(this, clonedLeafList,
+                                      (YangNode) usesParent);
                 } catch (CloneNotSupportedException | DataModelException e) {
                     throw new DataModelException(e.getMessage());
                 }
-                clonedLeafList.setContainedIn(usesParentLeavesHolder);
-                usesParentLeavesHolder.addLeafList(clonedLeafList);
+                clonedLeafList.setContainedIn(usesParent);
+                usesParent.addLeafList(clonedLeafList);
             }
         }
 
@@ -441,7 +428,7 @@
         } catch (DataModelException e) {
             throw new DataModelException(e.getMessage());
         }
-        updateClonedLeavesUnionEnumRef(usesParentLeavesHolder);
+        updateClonedLeavesUnionEnumRef(usesParent);
         return unmodifiableList(entityToResolveInfoList);
     }
 
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
index 58a1caf..411e88e 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
@@ -16,22 +16,6 @@
 
 package org.onosproject.yangutils.datamodel.utils;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
 import org.onosproject.yangutils.datamodel.CollisionDetector;
 import org.onosproject.yangutils.datamodel.ResolvableType;
 import org.onosproject.yangutils.datamodel.YangAtomicPath;
@@ -58,6 +42,22 @@
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
 /**
  * Represents utilities for data model tree.
  */
@@ -337,195 +337,306 @@
     }
 
     /**
-     * Clones the list of leaves and list of leaf list in the leaves holder.
+     * Adds the list of leaf present under a node to resolution list, after
+     * cloning. Under the cloned node, with cloned leaf, attributes are set
+     * and added to resolution list.
      *
-     * @param leavesHolder YANG node potentially containing leaves or leaf lists
-     * @param yangUses     instance of YANG uses
-     * @throws CloneNotSupportedException clone is not supported
+     * @param clonedNode holder node
+     * @param yangUses   YANG uses
+     * @throws CloneNotSupportedException clone not supported error
      * @throws DataModelException         data model error
      */
-    public static void cloneLeaves(YangLeavesHolder leavesHolder, YangUses yangUses)
+    public static void cloneListOfLeaf(
+            YangLeavesHolder clonedNode, YangUses yangUses)
             throws CloneNotSupportedException, DataModelException {
-        List<YangLeaf> currentListOfLeaves = leavesHolder.getListOfLeaf();
-        if (currentListOfLeaves != null) {
-            List<YangLeaf> clonedLeavesList = new LinkedList<>();
-            for (YangLeaf leaf : currentListOfLeaves) {
+
+        List<YangLeaf> leaves = clonedNode.getListOfLeaf();
+        if (isListPresent(leaves)) {
+            List<YangLeaf> clonedLeaves = new LinkedList<>();
+            for (YangLeaf leaf : leaves) {
                 YangLeaf clonedLeaf = leaf.clone();
                 clonedLeaf.setReferredLeaf(leaf);
-                if (yangUses != null && yangUses.getCurrentGroupingDepth() == 0) {
-                    YangEntityToResolveInfoImpl resolveInfo =
-                            resolveYangConstructsUnderGroupingForLeaf(clonedLeaf, leavesHolder, yangUses);
-                    if (resolveInfo != null) {
-                        yangUses.addEntityToResolve(resolveInfo);
-                    }
-                }
-                clonedLeaf.setContainedIn(leavesHolder);
-                clonedLeavesList.add(clonedLeaf);
+                addUnresolvedType(yangUses, clonedLeaf, (YangNode) clonedNode);
+                clonedLeaf.setContainedIn(clonedNode);
+                clonedLeaves.add(clonedLeaf);
             }
-            leavesHolder.setListOfLeaf(clonedLeavesList);
+            clonedNode.setListOfLeaf(clonedLeaves);
         }
+    }
 
-        List<YangLeafList> currentListOfLeafList = leavesHolder.getListOfLeafList();
-        if (currentListOfLeafList != null) {
-            List<YangLeafList> clonedListOfLeafList = new LinkedList<>();
-            for (YangLeafList leafList : currentListOfLeafList) {
+    /**
+     * Adds all the unresolved type under leaf/leaf-list to the resolution
+     * list, after cloning. This makes the resolution to happen after cloning
+     * of the grouping. Adds resolution with cloned node holder under which
+     * cloned type is present.
+     *
+     * @param yangUses   YANG uses
+     * @param clonedObj  cloned type object
+     * @param clonedNode holder node
+     * @throws DataModelException data model error
+     */
+    public static void addUnresolvedType(
+            YangUses yangUses, Object clonedObj,
+            YangNode clonedNode) throws DataModelException {
+
+        List<YangEntityToResolveInfoImpl> infoList;
+        if (yangUses != null && yangUses.getCurrentGroupingDepth() == 0) {
+            infoList = getTypesToBeResolved(clonedObj, clonedNode, yangUses);
+            if (isListPresent(infoList)) {
+                yangUses.addEntityToResolve(infoList);
+            }
+        }
+    }
+
+    /**
+     * Returns true if list object is non-null and non-empty; false otherwise.
+     *
+     * @param listObj list object
+     * @return true if list object is non-null and non-empty; false otherwise
+     */
+    private static boolean isListPresent(List listObj) {
+        return listObj != null && !listObj.isEmpty();
+    }
+
+    /**
+     * Adds the list of leaf-list present under a node to resolution list,
+     * after cloning. Under the cloned node, with cloned leaf-list,
+     * attributes are set and added to resolution list.
+     *
+     * @param clonedNode cloned holder
+     * @param yangUses   YANG uses
+     * @throws CloneNotSupportedException clone not supported error
+     * @throws DataModelException         data model error
+     */
+    public static void cloneListOfLeafList(
+            YangLeavesHolder clonedNode, YangUses yangUses)
+            throws CloneNotSupportedException, DataModelException {
+
+        List<YangLeafList> listOfLeafList = clonedNode.getListOfLeafList();
+        if (isListPresent(listOfLeafList)) {
+            List<YangLeafList> clonedList = new LinkedList<>();
+            for (YangLeafList leafList : listOfLeafList) {
                 YangLeafList clonedLeafList = leafList.clone();
                 clonedLeafList.setReferredSchemaLeafList(leafList);
-                if (yangUses != null && yangUses.getCurrentGroupingDepth() == 0) {
-                    YangEntityToResolveInfoImpl resolveInfo =
-                            resolveYangConstructsUnderGroupingForLeafList(clonedLeafList, leavesHolder,
-                                    yangUses);
-                    if (resolveInfo != null) {
-                        yangUses.addEntityToResolve(resolveInfo);
-                    }
-                }
-                clonedLeafList.setContainedIn(leavesHolder);
-                clonedListOfLeafList.add(clonedLeafList);
+                addUnresolvedType(yangUses, clonedLeafList,
+                                  (YangNode) clonedNode);
+                clonedLeafList.setContainedIn(clonedNode);
+                clonedList.add(clonedLeafList);
             }
-            leavesHolder.setListOfLeafList(clonedListOfLeafList);
+            clonedNode.setListOfLeafList(clonedList);
         }
     }
 
     /**
-     * Resolves leafref in leaf, which are under grouping by adding it to the resolution list.
+     * Returns types that has to be resolved for a single leaf/leaf-list.
+     * Identifies the object to be leaf/leaf-list and assigns respective
+     * parameters to resolve the types under leaf/leaf-list.
      *
-     * @param clonedLeaf       cloned leaf in uses from grouping
-     * @param leafParentHolder holder of the leaf from uses
-     * @param yangUses         YANG uses
-     * @return entity of leafref which has to be resolved
+     * @param clonedObj  leaf/leaf-list object
+     * @param holderNode holder node
+     * @param yangUses   YANG uses
+     * @return list of resolvable entities in a leaf/leaf-list
      * @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;
+    private static List<YangEntityToResolveInfoImpl> getTypesToBeResolved(
+            Object clonedObj, YangNode holderNode,
+            YangUses yangUses) throws DataModelException {
+
+        YangType type;
+        if (clonedObj instanceof YangLeaf) {
+            YangLeaf clonedLeaf = (YangLeaf) clonedObj;
+            type = clonedLeaf.getDataType();
+            return getUnresolvedTypeList(type.getDataType(), type, holderNode,
+                                         yangUses, true);
         }
-        return null;
+        YangLeafList clonedLeafList = (YangLeafList) clonedObj;
+        type = clonedLeafList.getDataType();
+        return getUnresolvedTypeList(type.getDataType(), type, holderNode,
+                                     yangUses, false);
     }
 
     /**
-     * Resolves leafRef, identityRef and derived type in leaf, which are under grouping by adding it to the resolution
-     * list.
+     * Returns list of resolvable entities from the type of leaf/leaf-list.
+     * If the type is leaf-ref, identity-ref, derived or union with type
+     * resolution required, it has to be resolved from the place where it is
+     * cloned. So, the resolution list added with these entities. When a type
+     * require no resolution then null is returned, so it will never be added
+     * to resolution list.
      *
-     * @param clonedLeaf       cloned leaf in uses from grouping
-     * @param leafParentHolder holder of the leaf from uses
-     * @param yangUses         YANG uses
-     * @return entity of leafRef/identityRef/derived type which has to be resolved
+     * @param dataTypes data type of type
+     * @param type      type of leaf/leaf-list
+     * @param holder    holder node of type
+     * @param yangUses  YANG uses
+     * @param isLeaf    leaf or leaf-list
+     * @return list of resolvable entities for a leaf/leaf-list.
      * @throws DataModelException data model error
      */
-    public static YangEntityToResolveInfoImpl resolveYangConstructsUnderGroupingForLeaf(YangLeaf clonedLeaf,
-                                                                                        YangLeavesHolder leafParentHolder, YangUses yangUses)
-            throws DataModelException {
-        int lineNumber;
-        int charPosition;
-        YangDataTypes dataTypes = clonedLeaf.getDataType().getDataType();
-        YangEntityToResolveInfoImpl yangEntityToResolveInfo = new YangEntityToResolveInfoImpl();
+    private static List<YangEntityToResolveInfoImpl> getUnresolvedTypeList(
+            YangDataTypes dataTypes, YangType type, YangNode holder,
+            YangUses yangUses, boolean isLeaf) throws DataModelException {
+
+        List<YangEntityToResolveInfoImpl> infoList = new ArrayList<>();
+        YangEntityToResolveInfoImpl entity = null;
+        List<YangEntityToResolveInfoImpl> entityList = null;
 
         switch (dataTypes) {
             case LEAFREF:
-                YangLeafRef leafRefForCloning = (YangLeafRef) clonedLeaf.getDataType().getDataTypeExtendedInfo();
-                // Conversion of prefixes in absolute path while cloning them.
-                convertThePrefixesDuringChange(leafRefForCloning, yangUses);
-                leafRefForCloning.setParentNodeOfLeafref((YangNode) leafParentHolder);
-                yangEntityToResolveInfo.setEntityToResolve(leafRefForCloning);
-                lineNumber = leafRefForCloning.getCharPosition();
-                charPosition = leafRefForCloning.getLineNumber();
+                entity = getLeafRefResolvableEntity(type, yangUses, holder);
                 break;
 
             case IDENTITYREF:
-                YangIdentityRef identityRef = (YangIdentityRef) clonedLeaf.getDataType().getDataTypeExtendedInfo();
-                if (identityRef.isIdentityForInterFileGroupingResolution()) {
-                    return null;
-                }
-                yangEntityToResolveInfo.setEntityToResolve(identityRef);
-                lineNumber = identityRef.getCharPosition();
-                charPosition = identityRef.getLineNumber();
+                entity = getIdentityRefResolvableEntity(type, holder);
                 break;
 
             case DERIVED:
-                YangType type = clonedLeaf.getDataType();
-                if (type.isTypeForInterFileGroupingResolution()) {
-                    return null;
-                }
-                yangEntityToResolveInfo.setEntityToResolve(type);
-                lineNumber = type.getCharPosition();
-                charPosition = type.getLineNumber();
+                entity = getDerivedResolvableEntity(type, holder, isLeaf);
+                break;
+
+            case UNION:
+                entityList = getUnionResolvableEntity(type, isLeaf);
                 break;
 
             default:
                 return null;
         }
-
-        yangEntityToResolveInfo.setHolderOfEntityToResolve((YangNode) leafParentHolder);
-        yangEntityToResolveInfo.setCharPosition(charPosition);
-        yangEntityToResolveInfo.setLineNumber(lineNumber);
-        return yangEntityToResolveInfo;
+        infoList.add(entity);
+        if (isListPresent(entityList)) {
+            infoList.addAll(entityList);
+        }
+        return infoList;
     }
 
     /**
-     * Resolves leafRef, identityRef and derived type in leaf-list, which are under grouping by adding it to the
-     * resolution list.
+     * Returns resolvable entity when the type is leaf-ref. It changes the
+     * prefixes from grouping to uses, then changes the parent node to the
+     * cloned node, sets needed information to entity such as line number,
+     * position number and holder.
      *
-     * @param clonedLeafList   cloned leaf-list in uses from grouping
-     * @param leafParentHolder holder of the leaf from uses
-     * @param yangUses         YANG uses
-     * @return entity of leafRef/identityRef/derived type which has to be resolved
+     * @param type     YANG type of leaf-ref
+     * @param yangUses YANG uses
+     * @param holder   cloned holder
+     * @return entity to resolve for leaf-ref
      * @throws DataModelException data model error
      */
-    public static YangEntityToResolveInfoImpl resolveYangConstructsUnderGroupingForLeafList(
-            YangLeafList clonedLeafList, YangLeavesHolder leafParentHolder, YangUses yangUses)
+    private static YangEntityToResolveInfoImpl getLeafRefResolvableEntity(
+            YangType type, YangUses yangUses, YangNode holder)
             throws DataModelException {
-        int lineNumber;
-        int charPosition;
-        YangDataTypes dataTypes = clonedLeafList.getDataType().getDataType();
-        YangEntityToResolveInfoImpl yangEntityToResolveInfo = new YangEntityToResolveInfoImpl();
-        switch (dataTypes) {
-            case LEAFREF:
-                YangLeafRef leafRefForCloning = (YangLeafRef) clonedLeafList.getDataType().getDataTypeExtendedInfo();
-                // Conversion of prefixes in absolute path while cloning them.
-                convertThePrefixesDuringChange(leafRefForCloning, yangUses);
-                leafRefForCloning.setParentNodeOfLeafref((YangNode) leafParentHolder);
-                yangEntityToResolveInfo.setEntityToResolve(leafRefForCloning);
-                lineNumber = leafRefForCloning.getCharPosition();
-                charPosition = leafRefForCloning.getLineNumber();
-                break;
-            case IDENTITYREF:
-                YangIdentityRef identityRef = (YangIdentityRef) clonedLeafList.getDataType().getDataTypeExtendedInfo();
 
-                if (identityRef.isIdentityForInterFileGroupingResolution()) {
-                    return null;
-                }
-                yangEntityToResolveInfo.setEntityToResolve(identityRef);
-                lineNumber = identityRef.getCharPosition();
-                charPosition = identityRef.getLineNumber();
-                break;
-            case DERIVED:
-                YangType type = clonedLeafList.getDataType();
-                if (type.isTypeForInterFileGroupingResolution() && type.isTypeNotResolvedTillRootNode()) {
-                    return null;
-                }
-                yangEntityToResolveInfo.setEntityToResolve(type);
-                lineNumber = type.getCharPosition();
-                charPosition = type.getLineNumber();
-                break;
-            default:
-                return null;
+        YangEntityToResolveInfoImpl<YangLeafRef> leafRefInfo =
+                new YangEntityToResolveInfoImpl<>();
+        YangLeafRef leafRef = (YangLeafRef) type.getDataTypeExtendedInfo();
+
+        // Conversion of prefixes in absolute path while cloning them.
+        convertThePrefixesDuringChange(leafRef, yangUses);
+        leafRef.setParentNodeOfLeafref(holder);
+        leafRefInfo.setEntityToResolve(leafRef);
+
+        return setInformationInEntity(
+                leafRefInfo, holder, leafRef.getCharPosition(),
+                leafRef.getLineNumber());
+    }
+
+    /**
+     * Returns resolvable entity when the type is identity-ref. It sets needed
+     * information to entity such as line number,position number and holder.
+     * Returns null when identity is for inter grouping.
+     *
+     * @param type   YANG type for identity-ref
+     * @param holder holder node
+     * @return entity to resolve for identity-ref
+     */
+    private static YangEntityToResolveInfoImpl getIdentityRefResolvableEntity(
+            YangType type, YangNode holder) {
+
+        YangEntityToResolveInfoImpl<YangIdentityRef> identityRefInfo =
+                new YangEntityToResolveInfoImpl<>();
+        YangIdentityRef identityRef =
+                (YangIdentityRef) type.getDataTypeExtendedInfo();
+
+        if (identityRef.isIdentityForInterFileGroupingResolution()) {
+            return null;
         }
-        yangEntityToResolveInfo.setHolderOfEntityToResolve((YangNode) leafParentHolder);
-        yangEntityToResolveInfo.setCharPosition(charPosition);
-        yangEntityToResolveInfo.setLineNumber(lineNumber);
-        return yangEntityToResolveInfo;
+
+        identityRefInfo.setEntityToResolve(identityRef);
+        return setInformationInEntity(
+                identityRefInfo, holder, identityRef.getCharPosition(),
+                identityRef.getLineNumber());
+    }
+
+    /**
+     * Returns resolvable entity when the type is derived. It sets needed
+     * information to entity such as line number,position number and holder.
+     * Returns null when identity is for inter grouping.
+     *
+     * @param type   derived YANG type
+     * @param holder holder node
+     * @param isLeaf leaf or leaf-list
+     * @return entity to resolve for derived type
+     */
+    private static YangEntityToResolveInfoImpl getDerivedResolvableEntity(
+            YangType<?> type, YangNode holder, boolean isLeaf) {
+
+        YangEntityToResolveInfoImpl<YangType<?>> derivedInfo =
+                new YangEntityToResolveInfoImpl<>();
+        if (type.isTypeForInterFileGroupingResolution()) {
+            return null;
+        }
+        if (!isLeaf && type.isTypeNotResolvedTillRootNode()) {
+            return null;
+        }
+
+        derivedInfo.setEntityToResolve(type);
+        return setInformationInEntity(
+                derivedInfo, holder, type.getCharPosition(),
+                type.getLineNumber());
+    }
+
+    /**
+     * Sets the information needed for adding the entity into resolution
+     * list, such as line number, position number and cloned holder node.
+     *
+     * @param entity  resolvable entity
+     * @param holder  cloned holder node
+     * @param charPos character position
+     * @param lineNum line number
+     * @return resolvable entity after setting info
+     */
+    private static YangEntityToResolveInfoImpl<?> setInformationInEntity(
+            YangEntityToResolveInfoImpl<?> entity, YangNode holder,
+            int charPos, int lineNum) {
+
+        entity.setHolderOfEntityToResolve(holder);
+        entity.setCharPosition(charPos);
+        entity.setLineNumber(lineNum);
+        return entity;
+    }
+
+    /**
+     * Returns resolvable entity under union. When types under union have
+     * identity-ref, derived and union, the function call is done recursively
+     * to get resolvable entity and adds it to list.
+     *
+     * @param type   union YANG type
+     * @param isLeaf leaf or leaf-list
+     * @return resolvable entity list after setting info
+     * @throws DataModelException data model error
+     */
+    private static List<YangEntityToResolveInfoImpl> getUnionResolvableEntity(
+            YangType type, boolean isLeaf) throws DataModelException {
+
+        YangUnion union = (YangUnion) type.getDataTypeExtendedInfo();
+        List<YangType<?>> typeList = union.getTypeList();
+        List<YangEntityToResolveInfoImpl> unionList = new ArrayList<>();
+        List<YangEntityToResolveInfoImpl> entity;
+
+        for (YangType unionType : typeList) {
+            entity = getUnresolvedTypeList(unionType.getDataType(),
+                                           unionType, union, null, isLeaf);
+            if (isListPresent(entity)) {
+                unionList.addAll(entity);
+            }
+        }
+        return unionList;
     }
 
     /**
diff --git a/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/TypeLinkingAfterCloningTest.java b/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/TypeLinkingAfterCloningTest.java
new file mode 100644
index 0000000..038e991
--- /dev/null
+++ b/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/TypeLinkingAfterCloningTest.java
@@ -0,0 +1,616 @@
+/*
+ * 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.plugin.manager;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onosproject.yangutils.datamodel.YangContainer;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
+import org.onosproject.yangutils.datamodel.YangIdentityRef;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangLeafList;
+import org.onosproject.yangutils.datamodel.YangLeafRef;
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yangutils.datamodel.YangTypeDef;
+import org.onosproject.yangutils.datamodel.YangUnion;
+import org.onosproject.yangutils.linker.impl.YangLinkerManager;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yangutils.datamodel.YangNodeType.MODULE_NODE;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.DERIVED;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.STRING;
+import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.updateFilePriority;
+import static org.onosproject.yangutils.utils.io.impl.YangFileScanner.getYangFiles;
+
+/**
+ * Test cases for type linking after cloning happens grouping.
+ */
+public class TypeLinkingAfterCloningTest {
+    private static final String MODULE = "module";
+    private static final String OPEN_ROAD = "org-open-road-m-device";
+    private static final String NODE_ID = "node-id";
+    private static final String LEAF = "leaf";
+    private static final String LEAF_LIST = "leaf-list";
+    private static final String NODE_REF = "node-ref";
+    private static final String FACILITY = "facility";
+    private static final String FACILITY_SYS_LOG = "syslog-facility";
+    private static final String USABILITY_SYS_LOG = "syslog-usability";
+    private static final String AVAILABILITY_SYS_LOG = "syslog-availability";
+    private static final String THIRD = "third";
+    private static final String SECOND = "second";
+    private static final String FIRST = "first";
+    private static final String TYPEDEF = "typedef";
+    private static final String CORRECT = "correct";
+
+    private final YangUtilManager utilMgr = new YangUtilManager();
+    private final YangLinkerManager linkerMgr = new YangLinkerManager();
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    /**
+     * Returns the error message as the node name incorrect, when assert fails.
+     *
+     * @param node     YANG node
+     * @param nodeName node name
+     * @return error message as the name is incorrect
+     */
+    private static String getInCrtName(String node, Object nodeName) {
+        return getCapitalCase(node) + "'s name " + nodeName + " is incorrect.";
+    }
+
+    /**
+     * Returns the capital cased first letter of the given string.
+     *
+     * @param name string to be capital cased
+     * @return capital cased string
+     */
+    private static String getCapitalCase(String name) {
+        return name.substring(0, 1).toUpperCase() + name.substring(1);
+    }
+
+    /**
+     * Returns the error message as the node type incorrect, when assert fails.
+     *
+     * @param node     YANG node
+     * @param nodeName node name
+     * @return error message as the type is incorrect
+     */
+    private static String getInCrtLeafType(String node, String nodeName) {
+        return "The " + node + " " + nodeName + " has incorrect data type.";
+    }
+
+    /**
+     * Returns the error message, stating the union and identity-ref level in
+     * the type, has not resolved to the referred identity.
+     *
+     * @param unionLvl union level in node
+     * @param idLvl    identity-ref level in node
+     * @param baseName referred base
+     * @param node     YANG node having type
+     * @param nodeName node name
+     * @return error message for incorrect identity-ref in union.
+     */
+    public static String getInCrtUnionWithIdRef(
+            String unionLvl, String idLvl, String baseName, String node,
+            String nodeName) {
+        return "The " + idLvl + " direct occurrence identity-ref in " +
+                unionLvl + " level union, of " + node + " " + nodeName +
+                " is not " + baseName;
+    }
+
+    /**
+     * Processes leaf-ref after its cloned to uses from grouping.
+     *
+     * @throws IOException io error when finding file
+     */
+    @Test
+    public void processLeafRefAfterCloning() throws IOException {
+
+        String searchDir = "src/test/resources/typelinkingaftercloning" +
+                "/leafref/intrafile";
+        utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+        utilMgr.parseYangFileInfoSet();
+        utilMgr.createYangNodeSet();
+        YangNode selfNode;
+
+        // Create YANG node set
+        linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+
+        // Add references to import list.
+        linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+        updateFilePriority(utilMgr.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+
+        Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+
+        selfNode = nodeItr.next();
+
+        ListIterator<YangLeaf> leafItr;
+        YangLeaf leafInfo;
+        ListIterator<YangLeafList> leafListItr;
+        YangLeafList leafListInfo;
+        YangLeafRef leafRef;
+
+        // Checks whether the data model tree returned is of type module.
+        assertThat((selfNode instanceof YangModule), is(true));
+
+        // Checks whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+        assertThat(getInCrtName(MODULE, OPEN_ROAD), selfNode.getName(),
+                   is(OPEN_ROAD));
+
+        YangList list = (YangList) selfNode.getChild().getNextSibling()
+                .getNextSibling();
+
+        leafItr = list.getListOfLeaf().listIterator();
+        leafInfo = leafItr.next();
+
+        // Checks whether the information in the leaf is correct under list.
+        assertThat(getInCrtName(LEAF, NODE_ID), leafInfo.getName(),
+                   is(NODE_ID));
+        leafRef = (YangLeafRef) leafInfo.getDataType()
+                .getDataTypeExtendedInfo();
+
+        // Checks the effective type for the leaf.
+        assertThat(getInCrtLeafType(LEAF, NODE_ID),
+                   leafRef.getEffectiveDataType().getDataType(), is(STRING));
+
+        leafListItr = list.getListOfLeafList().listIterator();
+        leafListInfo = leafListItr.next();
+
+        // Checks whether the information in the leaf-list is correct.
+        assertThat(getInCrtName(LEAF_LIST, NODE_REF), leafListInfo.getName(),
+                   is(NODE_REF));
+        leafRef = (YangLeafRef) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+
+        assertThat(getInCrtLeafType(LEAF_LIST, NODE_REF),
+                   leafRef.getEffectiveDataType().getDataType(), is(DERIVED));
+
+        // Checks whether the information under cloned container is correct.
+        YangContainer container = (YangContainer) list.getChild()
+                .getNextSibling();
+
+        leafItr = container.getListOfLeaf().listIterator();
+        leafInfo = leafItr.next();
+
+        // Checks whether the information in the leaf is correct under cont.
+        assertThat(getInCrtName(LEAF, NODE_ID), leafInfo.getName(),
+                   is(NODE_ID));
+        leafRef = (YangLeafRef) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        assertThat(getInCrtLeafType(LEAF, NODE_ID),
+                   leafRef.getEffectiveDataType().getDataType(), is(DERIVED));
+
+        leafListItr = container.getListOfLeafList().listIterator();
+        leafListInfo = leafListItr.next();
+
+        // Checks whether the information in the leaf-list is correct.
+        assertThat(getInCrtName(LEAF_LIST, NODE_REF), leafListInfo.getName(),
+                   is(NODE_REF));
+        leafRef = (YangLeafRef) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        assertThat(getInCrtLeafType(LEAF_LIST, NODE_REF),
+                   leafRef.getEffectiveDataType().getDataType(),
+                   is(STRING));
+    }
+
+    /**
+     * Processed invalid scenario where a leaf-ref is present in union.
+     *
+     * @throws IOException io error when finding file
+     */
+    @Test
+    public void processInvalidLeafRef() throws IOException {
+        thrown.expect(ParserException.class);
+        thrown.expectMessage("Union member type must not be one of the " +
+                                     "built-in types \"empty\" or " +
+                                     "\"leafref\"node-id_union");
+        String searchDir = "src/test/resources/typelinkingaftercloning" +
+                "/leafref/invalid";
+        utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+        utilMgr.parseYangFileInfoSet();
+    }
+
+    /**
+     * Processes simple identity-ref after it gets cloned from grouping.
+     *
+     * @throws IOException io error when finding file
+     */
+    @Test
+    public void processIdentityRefAfterCloning() throws IOException {
+
+        String searchDir = "src/test/resources/typelinkingaftercloning" +
+                "/identityref";
+        utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+        utilMgr.parseYangFileInfoSet();
+        utilMgr.createYangNodeSet();
+        YangNode selfNode;
+
+        // Create YANG node set
+        linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+
+        // Add references to import list.
+        linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+        updateFilePriority(utilMgr.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+
+        Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+
+        selfNode = nodeItr.next();
+
+        ListIterator<YangLeaf> leafItr;
+        YangLeaf leafInfo;
+        ListIterator<YangLeafList> leafListItr;
+        YangLeafList leafListInfo;
+        YangIdentityRef identityRef;
+        YangUnion union;
+        Iterator<YangType<?>> unionTypeItr;
+        YangType type;
+
+        // Checks whether the data model tree returned is of type module.
+        assertThat((selfNode instanceof YangModule), is(true));
+
+        // Checks whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+        assertThat(getInCrtName(MODULE, OPEN_ROAD), selfNode.getName(),
+                   is(OPEN_ROAD));
+
+        YangList list = (YangList) selfNode.getChild().getNextSibling()
+                .getNextSibling().getNextSibling();
+
+        leafItr = list.getListOfLeaf().listIterator();
+        leafInfo = leafItr.next();
+
+        // Checks if the leaf has identity-ref in union.
+        assertThat(getInCrtName(LEAF, FACILITY), leafInfo.getName(),
+                   is(FACILITY));
+        union = (YangUnion) leafInfo.getDataType().getDataTypeExtendedInfo();
+        unionTypeItr = union.getTypeList().listIterator();
+        type = unionTypeItr.next();
+        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+
+        // Checks the effective type for the leaf.
+        assertThat(getInCrtLeafType(LEAF, FACILITY),
+                   identityRef.getBaseIdentity().getName(),
+                   is(FACILITY_SYS_LOG));
+
+        leafInfo = leafItr.next();
+
+        // Checks whether the information in the leaf is correct under list.
+        assertThat(getInCrtName(LEAF, NODE_ID), leafInfo.getName(),
+                   is(NODE_ID));
+        identityRef = (YangIdentityRef) leafInfo.getDataType()
+                .getDataTypeExtendedInfo();
+
+        // Checks the effective type for the leaf.
+        assertThat(getInCrtLeafType(LEAF, NODE_ID),
+                   identityRef.getBaseIdentity().getName(),
+                   is(FACILITY_SYS_LOG));
+
+        leafListItr = list.getListOfLeafList().listIterator();
+        leafListInfo = leafListItr.next();
+
+        // Checks if the information in the leaf-list is correct under list.
+        assertThat(getInCrtName(LEAF_LIST, NODE_REF), leafListInfo.getName(),
+                   is(NODE_REF));
+
+        identityRef = (YangIdentityRef) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+
+        // Checks the effective type for the leaf-list.
+        assertThat(getInCrtLeafType(LEAF, NODE_REF),
+                   identityRef.getBaseIdentity().getName(),
+                   is(FACILITY_SYS_LOG));
+
+        YangContainer container = (YangContainer) list.getChild()
+                .getNextSibling().getNextSibling();
+
+        leafListItr = container.getListOfLeafList().listIterator();
+        leafListInfo = leafListItr.next();
+
+        // Checks the leaf-list information is correct.
+        assertThat(getInCrtName(LEAF_LIST, FACILITY), leafListInfo.getName(),
+                   is(FACILITY));
+        union = (YangUnion) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        unionTypeItr = union.getTypeList().listIterator();
+        type = unionTypeItr.next();
+        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+
+        // Checks the effective type for the leaf-list.
+        assertThat(getInCrtLeafType(LEAF_LIST, FACILITY),
+                   identityRef.getBaseIdentity().getName(),
+                   is(FACILITY_SYS_LOG));
+
+        leafListInfo = leafListItr.next();
+
+        // Checks the leaf-list information is correct.
+        assertThat(getInCrtName(LEAF_LIST, NODE_REF), leafListInfo.getName(),
+                   is(NODE_REF));
+        identityRef = (YangIdentityRef) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+
+        // Checks the effective type for the leaf.
+        assertThat(getInCrtLeafType(LEAF_LIST, NODE_REF),
+                   identityRef.getBaseIdentity().getName(),
+                   is(FACILITY_SYS_LOG));
+
+        leafItr = container.getListOfLeaf().listIterator();
+        leafInfo = leafItr.next();
+
+        // Checks the leaf information is correct.
+        assertThat(getInCrtName(LEAF, NODE_ID), leafInfo.getName(),
+                   is(NODE_ID));
+        identityRef = (YangIdentityRef) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+
+        assertThat(getInCrtLeafType(LEAF, NODE_ID),
+                   identityRef.getBaseIdentity().getName(),
+                   is(FACILITY_SYS_LOG));
+
+    }
+
+    /**
+     * Processes union having different recursive level with identity-ref.
+     *
+     * @throws IOException io error when finding file
+     */
+    @Test
+    public void processUnionAfterCloning() throws IOException {
+
+        String searchDir = "src/test/resources/typelinkingaftercloning/union";
+        utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+        utilMgr.parseYangFileInfoSet();
+        utilMgr.createYangNodeSet();
+        YangNode selfNode;
+
+        // Create YANG node set
+        linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+
+        // Add references to import list.
+        linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+        updateFilePriority(utilMgr.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+        Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+        selfNode = nodeItr.next();
+
+        YangIdentityRef identityRef;
+        YangUnion union;
+        Iterator<YangType<?>> unionTypeItr;
+        YangType type;
+        YangUnion union2;
+        Iterator<YangType<?>> unionTypeItr2;
+        YangType type2;
+        YangUnion union3;
+        Iterator<YangType<?>> unionTypeItr3;
+        YangType type3;
+        YangDerivedInfo derivedInfo;
+        YangTypeDef typeDef;
+        Iterator<YangType<?>> typeDefItr;
+
+        // Checks whether the data model tree returned is of type module.
+        assertThat((selfNode instanceof YangModule), is(true));
+
+        // Checks whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+        assertThat(getInCrtName(MODULE, OPEN_ROAD), selfNode.getName(),
+                   is(OPEN_ROAD));
+
+        YangList list = (YangList) selfNode.getChild().getNextSibling()
+                .getNextSibling().getNextSibling().getNextSibling()
+                .getNextSibling().getNextSibling();
+
+        Iterator<YangLeaf> leafItr = list.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafItr.next();
+
+        // Checks if the leaf has identity-ref in union.
+        assertThat(getInCrtName(LEAF, FACILITY), leafInfo.getName(),
+                   is(FACILITY));
+
+        // Gets the first level union and the list of type in it.
+        union = (YangUnion) leafInfo.getDataType().getDataTypeExtendedInfo();
+        unionTypeItr = union.getTypeList().listIterator();
+        type = unionTypeItr.next();
+
+        // Gets the second level union and types in it.
+        union2 = (YangUnion) type.getDataTypeExtendedInfo();
+        unionTypeItr2 = union2.getTypeList().listIterator();
+        type2 = unionTypeItr2.next();
+
+        // Gets the third level union and types in it.
+        union3 = (YangUnion) type2.getDataTypeExtendedInfo();
+        unionTypeItr3 = union3.getTypeList().listIterator();
+        type3 = unionTypeItr3.next();
+
+        // Checks the first identity-ref in third level union.
+        identityRef = (YangIdentityRef) type3.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                THIRD, FIRST, USABILITY_SYS_LOG, LEAF, FACILITY),
+                   identityRef.getBaseIdentity().getName(),
+                   is(USABILITY_SYS_LOG));
+
+        // Checks the first identity-ref in second level union.
+        type2 = unionTypeItr2.next();
+        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                SECOND, FIRST, FACILITY_SYS_LOG, LEAF, FACILITY),
+                   identityRef.getBaseIdentity().getName(),
+                   is(FACILITY_SYS_LOG));
+
+        // Checks the first identity-ref in first level union.
+        type = unionTypeItr.next();
+        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                FIRST, FIRST, AVAILABILITY_SYS_LOG, LEAF, FACILITY),
+                   identityRef.getBaseIdentity().getName(),
+                   is(AVAILABILITY_SYS_LOG));
+
+        // Checks derived type in third level union.
+        type3 = unionTypeItr3.next();
+        derivedInfo = (YangDerivedInfo) type3.getDataTypeExtendedInfo();
+        typeDef = derivedInfo.getReferredTypeDef();
+        typeDefItr = typeDef.getTypeList().listIterator();
+        type = typeDefItr.next();
+
+        // Gets the first level union and the list of type in it.
+        union = (YangUnion) type.getDataTypeExtendedInfo();
+        unionTypeItr = union.getTypeList().listIterator();
+        type = unionTypeItr.next();
+
+        // Gets the first level union and the list of type in it.
+        union2 = (YangUnion) type.getDataTypeExtendedInfo();
+        unionTypeItr2 = union2.getTypeList().listIterator();
+        type2 = unionTypeItr2.next();
+
+        // Checks the first identity-ref in second level union.
+        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                SECOND, FIRST, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
+                   identityRef.getBaseIdentity().getName(),
+                   is(AVAILABILITY_SYS_LOG));
+
+        // Checks the second identity-ref in second level union.
+        type2 = unionTypeItr2.next();
+        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                SECOND, SECOND, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
+                   identityRef.getBaseIdentity().getName(),
+                   is(AVAILABILITY_SYS_LOG));
+
+        // Checks the first identity-ref in first level union.
+        type = unionTypeItr.next();
+        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                FIRST, FIRST, USABILITY_SYS_LOG, TYPEDEF, CORRECT),
+                   identityRef.getBaseIdentity().getName(),
+                   is(USABILITY_SYS_LOG));
+
+        YangContainer container = (YangContainer) list.getChild()
+                .getNextSibling().getNextSibling();
+
+
+        Iterator<YangLeafList> leafListItr = container.getListOfLeafList()
+                .listIterator();
+        YangLeafList leafListInfo = leafListItr.next();
+
+        // Checks if the leaf-list has identity-ref in union.
+        assertThat(getInCrtName(LEAF_LIST, FACILITY), leafListInfo.getName(),
+                   is(FACILITY));
+
+        // Gets the first level union and the list of type in it.
+        union = (YangUnion) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        unionTypeItr = union.getTypeList().listIterator();
+        type = unionTypeItr.next();
+
+        // Gets the second level union and types in it.
+        union2 = (YangUnion) type.getDataTypeExtendedInfo();
+        unionTypeItr2 = union2.getTypeList().listIterator();
+        type2 = unionTypeItr2.next();
+
+        // Gets the third level union and types in it.
+        union3 = (YangUnion) type2.getDataTypeExtendedInfo();
+        unionTypeItr3 = union3.getTypeList().listIterator();
+        type3 = unionTypeItr3.next();
+
+        // Checks the first identity-ref in third level union.
+        identityRef = (YangIdentityRef) type3.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                THIRD, FIRST, USABILITY_SYS_LOG, LEAF_LIST, FACILITY),
+                   identityRef.getBaseIdentity().getName(),
+                   is(USABILITY_SYS_LOG));
+
+        // Checks the first identity-ref in second level union.
+        type2 = unionTypeItr2.next();
+        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                SECOND, FIRST, FACILITY_SYS_LOG, LEAF_LIST, FACILITY),
+                   identityRef.getBaseIdentity().getName(),
+                   is(FACILITY_SYS_LOG));
+
+        // Checks the first identity-ref in first level union.
+        type = unionTypeItr.next();
+        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                FIRST, FIRST, AVAILABILITY_SYS_LOG, LEAF_LIST, FACILITY),
+                   identityRef.getBaseIdentity().getName(),
+                   is(AVAILABILITY_SYS_LOG));
+
+        // Checks derived type in third level union.
+        type3 = unionTypeItr3.next();
+        derivedInfo = (YangDerivedInfo) type3.getDataTypeExtendedInfo();
+        typeDef = derivedInfo.getReferredTypeDef();
+        typeDefItr = typeDef.getTypeList().listIterator();
+        type = typeDefItr.next();
+
+        // Gets the first level union and the list of type in it.
+        union = (YangUnion) type.getDataTypeExtendedInfo();
+        unionTypeItr = union.getTypeList().listIterator();
+        type = unionTypeItr.next();
+
+        // Gets the first level union and the list of type in it.
+        union2 = (YangUnion) type.getDataTypeExtendedInfo();
+        unionTypeItr2 = union2.getTypeList().listIterator();
+        type2 = unionTypeItr2.next();
+
+        // Checks the first identity-ref in second level union.
+        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                SECOND, FIRST, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
+                   identityRef.getBaseIdentity().getName(),
+                   is(AVAILABILITY_SYS_LOG));
+
+        // Checks the second identity-ref in second level union.
+        type2 = unionTypeItr2.next();
+        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                SECOND, SECOND, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
+                   identityRef.getBaseIdentity().getName(),
+                   is(AVAILABILITY_SYS_LOG));
+
+        // Checks the first identity-ref in first level union.
+        type = unionTypeItr.next();
+        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        assertThat(getInCrtUnionWithIdRef(
+                FIRST, FIRST, USABILITY_SYS_LOG, TYPEDEF, CORRECT),
+                   identityRef.getBaseIdentity().getName(),
+                   is(USABILITY_SYS_LOG));
+    }
+}
diff --git a/plugin/src/test/resources/typelinkingaftercloning/identityref/IntraFileIdentityRefAfterCloning.yang b/plugin/src/test/resources/typelinkingaftercloning/identityref/IntraFileIdentityRefAfterCloning.yang
new file mode 100644
index 0000000..9fbc024
--- /dev/null
+++ b/plugin/src/test/resources/typelinkingaftercloning/identityref/IntraFileIdentityRefAfterCloning.yang
@@ -0,0 +1,74 @@
+module org-open-road-m-device {
+    namespace "http://org/openroadm/device";
+    prefix org-open-road-m-device;
+
+    identity syslog-facility {
+        description
+            "The base identity to represent syslog facilities";
+    }
+    typedef value {
+        type identityref {
+            base syslog-facility;
+        }
+    }
+
+    grouping device-common {
+        leaf facility {
+            type union {
+                type identityref {
+                    base syslog-facility;
+                }
+                type enumeration {
+                    enum "all" {
+                        description
+                            "This enum describes the case where all
+                            facilities are requested.";
+                    }
+                }
+            }
+        }
+        leaf node-id {
+            type identityref {
+                base syslog-facility;
+            }
+            description
+                "Globally unique identifier for a device.";
+            config true;
+        }
+        leaf-list node-ref {
+            type value;
+        }
+        container network-ref {
+            leaf-list facility {
+                type union {
+                    type identityref {
+                        base syslog-facility;
+                    }
+                    type enumeration {
+                        enum "all" {
+                            description
+                                "This enum describes the case where all
+                                facilities are requested.";
+                        }
+                    }
+                }
+            }
+            leaf-list node-ref {
+                type identityref {
+                    base syslog-facility;
+                }
+                description
+                    "Globally unique identifier for a device.";
+                config true;
+            }
+            leaf node-id {
+                type value;
+            }
+        }
+    }
+
+    list node {
+        config false;
+        uses device-common;
+    }
+}
diff --git a/plugin/src/test/resources/typelinkingaftercloning/leafref/intrafile/IntraFileLeafrefAfterCloning.yang b/plugin/src/test/resources/typelinkingaftercloning/leafref/intrafile/IntraFileLeafrefAfterCloning.yang
new file mode 100644
index 0000000..a73280d
--- /dev/null
+++ b/plugin/src/test/resources/typelinkingaftercloning/leafref/intrafile/IntraFileLeafrefAfterCloning.yang
@@ -0,0 +1,52 @@
+module org-open-road-m-device {
+    namespace "http://org/openroadm/device";
+    prefix org-open-road-m-device;
+
+    leaf uri {
+        type string;
+    }
+    leaf-list id {
+        type value;
+    }
+    typedef value {
+        type uint8;
+    }
+
+    grouping device-common {
+        leaf node-id {
+            type leafref {
+                path "/uri";
+            }
+            description
+                "Globally unique identifier for a device.";
+            config true;
+            default "open-road-m";
+        }
+        leaf-list node-ref {
+            type leafref {
+                path "/id";
+            }
+        }
+        container network-ref {
+            leaf node-id {
+                type leafref {
+                    path "/id";
+                }
+                description
+                    "Globally unique identifier for a device.";
+                config true;
+                default "open-road-m";
+            }
+            leaf-list node-ref {
+                type leafref {
+                    path "/uri";
+                }
+            }
+        }
+    }
+
+    list node {
+        config false;
+        uses device-common;
+    }
+}
diff --git a/plugin/src/test/resources/typelinkingaftercloning/leafref/invalid/invalidleafref.yang b/plugin/src/test/resources/typelinkingaftercloning/leafref/invalid/invalidleafref.yang
new file mode 100644
index 0000000..79491e1
--- /dev/null
+++ b/plugin/src/test/resources/typelinkingaftercloning/leafref/invalid/invalidleafref.yang
@@ -0,0 +1,28 @@
+module org-open-road-m-device {
+    namespace "http://org/openroadm/device";
+    prefix org-open-road-m-device;
+
+    leaf uri {
+        type string;
+    }
+
+    grouping device-common {
+        leaf node-id {
+            type union {
+                type leafref {
+                    path "/uri";
+                }
+                type string;
+            }
+            description
+                "Globally unique identifier for a device.";
+            config true;
+            default "open-road-m";
+        }
+    }
+
+    list node {
+        config false;
+        uses device-common;
+    }
+}
diff --git a/plugin/src/test/resources/typelinkingaftercloning/union/IntraFileUnionAfterCloning.yang b/plugin/src/test/resources/typelinkingaftercloning/union/IntraFileUnionAfterCloning.yang
new file mode 100644
index 0000000..a69a5a1
--- /dev/null
+++ b/plugin/src/test/resources/typelinkingaftercloning/union/IntraFileUnionAfterCloning.yang
@@ -0,0 +1,81 @@
+module org-open-road-m-device {
+    namespace "http://org/openroadm/device";
+    prefix org-open-road-m-device;
+
+    identity syslog-facility {
+        description
+            "The base identity to represent syslog facilities";
+    }
+
+    identity syslog-usability {
+        description
+            "The base identity to represent syslog usabilities";
+    }
+
+    identity syslog-availability {
+        description
+            "The base identity to represent syslog availabilities";
+    }
+
+    typedef value {
+        type identityref {
+            base syslog-availability;
+        }
+    }
+
+    typedef correct {
+        type union {
+            type union {
+                type identityref {
+                    base syslog-availability;
+                }
+                type value;
+            }
+            type identityref {
+                base syslog-usability;
+            }
+        }
+    }
+
+    grouping device-common {
+        leaf facility {
+            type union {
+               type union {
+                   type union {
+                       type identityref {
+                           base syslog-usability;
+                       }
+                       type correct;
+                   }
+                   type identityref {
+                       base syslog-facility;
+                   }
+               }
+               type value;
+            }
+        }
+        container network-ref {
+            leaf-list facility {
+                type union {
+                   type union {
+                       type union {
+                           type identityref {
+                               base syslog-usability;
+                           }
+                           type correct;
+                       }
+                       type identityref {
+                           base syslog-facility;
+                       }
+                   }
+                   type value;
+                }
+            }
+        }
+    }
+
+    list node {
+        config false;
+        uses device-common;
+    }
+}