[ONOS-5517] Identity-ref resolution of typedef and grouping.

Change-Id: I2e1a775bfa61efa9203efa32dad8992a67331918
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 5943f17..cfcd3e7 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
@@ -459,11 +459,11 @@
 
     /**
      * 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.
+     * If the type is leaf-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 dataTypes data type of type
      * @param type      type of leaf/leaf-list
@@ -486,10 +486,6 @@
                 entity = getLeafRefResolvableEntity(type, yangUses, holder);
                 break;
 
-            case IDENTITYREF:
-                entity = getIdentityRefResolvableEntity(type, holder);
-                break;
-
             case DERIVED:
                 entity = getDerivedResolvableEntity(type, holder, isLeaf);
                 break;
@@ -539,33 +535,6 @@
     }
 
     /**
-     * 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;
-        }
-
-        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.
diff --git a/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java b/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
index 3400cfe..7c97805 100644
--- a/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
+++ b/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
@@ -18,7 +18,6 @@
 
 import org.onosproject.yangutils.datamodel.DefaultLocationInfo;
 import org.onosproject.yangutils.datamodel.Resolvable;
-import org.onosproject.yangutils.datamodel.ResolvableType;
 import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
 import org.onosproject.yangutils.datamodel.TraversalType;
 import org.onosproject.yangutils.datamodel.YangAtomicPath;
@@ -61,7 +60,6 @@
 import java.util.List;
 import java.util.Stack;
 
-import static org.onosproject.yangutils.datamodel.ResolvableType.YANG_IDENTITYREF;
 import static org.onosproject.yangutils.datamodel.ResolvableType.YANG_LEAFREF;
 import static org.onosproject.yangutils.datamodel.TraversalType.CHILD;
 import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
@@ -91,7 +89,6 @@
 import static org.onosproject.yangutils.utils.UtilConstants.FAILED_TO_FIND_ANNOTATION;
 import static org.onosproject.yangutils.utils.UtilConstants.FAILED_TO_FIND_LEAD_INFO_HOLDER;
 import static org.onosproject.yangutils.utils.UtilConstants.FAILED_TO_LINK;
-import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
 import static org.onosproject.yangutils.utils.UtilConstants.INVALID_ENTITY;
 import static org.onosproject.yangutils.utils.UtilConstants.INVALID_LINKER_STATE;
 import static org.onosproject.yangutils.utils.UtilConstants.INVALID_RESOLVED_ENTITY;
@@ -253,96 +250,89 @@
     }
 
     /**
-     * Adds the leafref/identityref type to the type, which has derived type referring to
-     * typedef with leafref/identityref type.
+     * Adds leaf-ref to the resolution list, with different context if
+     * leaf-ref is defined under derived type. Leaf-ref must be resolved from
+     * where the typedef is referenced.
      */
     private void addDerivedRefTypeToRefTypeResolutionList()
             throws DataModelException {
 
         YangNode refNode = entityToResolveInfo.getHolderOfEntityToResolve();
-        YangType yangType = getValidateResolvableType();
+        YangDerivedInfo info = getValidResolvableType();
 
-        if (yangType == null) {
+        if (info == null) {
             return;
         }
 
-        YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType
+        YangType<T> type =
+                (YangType<T>) entityToResolveInfo.getEntityToResolve();
+
+        T extType = (T) info.getReferredTypeDef().getTypeDefBaseType()
                 .getDataTypeExtendedInfo();
 
-        YangDataTypes dataType = derivedInfo.getEffectiveBuiltInType();
-        // If the derived types referred type is not leafref/identityref return
-        if (dataType != YangDataTypes.LEAFREF &&
-                dataType != YangDataTypes.IDENTITYREF) {
-            return;
+        while (extType instanceof YangDerivedInfo) {
+            info = (YangDerivedInfo) extType;
+            extType = (T) info.getReferredTypeDef().getTypeDefBaseType()
+                    .getDataTypeExtendedInfo();
         }
-
-        T extendedInfo = (T) derivedInfo.getReferredTypeDef()
-                .getTypeDefBaseType().getDataTypeExtendedInfo();
-
-        while (extendedInfo instanceof YangDerivedInfo) {
-            YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
-            extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef()
-                    .getTypeDefBaseType().getDataTypeExtendedInfo();
-        }
-
         /*
-         * Backup the derived types leafref/identityref info, delete all the info in current type,
-         * but for resolution status as resolved. Copy the backed up leafref/identityref to types extended info,
-         * create a leafref/identityref resolution info using the current resolution info and
-         * add to leafref/identityref resolution list.
+         * Backup the leaf-ref info from derived type and deletes the derived
+         * type info. Copies the backed up leaf-ref data to the actual type in
+         * replacement of derived type. Adds to the resolution list in this
+         * context.
          */
-        if (dataType == YangDataTypes.LEAFREF) {
-            YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
-            addRefTypeInfo(YangDataTypes.LEAFREF, LEAFREF, extendedInfo,
-                           yangType, refNode, YANG_LEAFREF);
-            leafRefInTypeDef.setParentNode(refNode);
-        } else {
-            addRefTypeInfo(YangDataTypes.IDENTITYREF, IDENTITYREF, extendedInfo,
-                           yangType, refNode, YANG_IDENTITYREF);
-        }
+        addRefTypeInfo(extType, type, refNode);
     }
 
-    //Validates entity to resolve for YANG type and returns type
-    private YangType getValidateResolvableType() {
+    /**
+     * Returns the derived info if the holder is typedef, the entity is type
+     * and the effective type is leaf-ref; null otherwise.
+     *
+     * @return derived info
+     */
+    private YangDerivedInfo<?> getValidResolvableType() {
+
         YangNode refNode = entityToResolveInfo.getHolderOfEntityToResolve();
         T entity = entityToResolveInfo.getEntityToResolve();
-        // If holder is typedef return.
-        if (!(refNode instanceof YangTypeDef) && entity instanceof YangType) {
-            YangType yangType = (YangType) entity;
 
-            // If type is not resolved return.
-            if (yangType.getResolvableStatus() == RESOLVED) {
-                return (YangType) entity;
+        if (!(refNode instanceof YangTypeDef) && entity instanceof YangType) {
+            YangType<?> type = (YangType) entity;
+            YangDerivedInfo<?> info =
+                    (YangDerivedInfo) type.getDataTypeExtendedInfo();
+            YangDataTypes dataType = info.getEffectiveBuiltInType();
+            if ((type.getResolvableStatus() == RESOLVED) &&
+                    (dataType == YangDataTypes.LEAFREF)) {
+                return info;
             }
         }
         return null;
     }
 
     /**
-     * Adds referred type(leafref/identityref) info to resolution list.
+     * Adds resolvable type (leaf-ref) info to resolution list.
      *
-     * @param type     data type
-     * @param typeName type name
-     * @param info     extended info
-     * @param yangType YANG type
-     * @param refNode  referred node
-     * @param resType  resolution type
-     * @throws DataModelException when fails to do data model operations
+     * @param extType resolvable type
+     * @param type    YANG type
+     * @param holder  holder node
+     * @throws DataModelException if there is a data model error
      */
-    private void addRefTypeInfo(YangDataTypes type, String typeName, T info,
-                                YangType yangType, YangNode refNode,
-                                ResolvableType resType) throws DataModelException {
-        yangType.resetYangType();
-        yangType.setResolvableStatus(RESOLVED);
-        yangType.setDataType(type);
-        yangType.setDataTypeName(typeName);
-        yangType.setDataTypeExtendedInfo(info);
-        ((Resolvable) info).setResolvableStatus(UNRESOLVED);
-        YangResolutionInfoImpl resolutionInfoImpl
-                = new YangResolutionInfoImpl<>(info, refNode,
-                                               getLineNumber(), getCharPosition());
-        curRefResolver.addToResolutionList(resolutionInfoImpl, resType);
-        curRefResolver.resolveSelfFileLinking(resType);
+    private void addRefTypeInfo(T extType, YangType<T> type, YangNode holder)
+            throws DataModelException {
+
+        type.resetYangType();
+        type.setResolvableStatus(RESOLVED);
+        type.setDataType(YangDataTypes.LEAFREF);
+        type.setDataTypeName(LEAFREF);
+        type.setDataTypeExtendedInfo(extType);
+
+        YangLeafRef leafRef = (YangLeafRef) extType;
+        (leafRef).setResolvableStatus(UNRESOLVED);
+        leafRef.setParentNode(holder);
+
+        YangResolutionInfoImpl info = new YangResolutionInfoImpl<>(
+                leafRef, holder, getLineNumber(), getCharPosition());
+        curRefResolver.addToResolutionList(info, YANG_LEAFREF);
+        curRefResolver.resolveSelfFileLinking(YANG_LEAFREF);
     }
 
     /**
diff --git a/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/StringGenerator.java b/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/StringGenerator.java
index dfe2826..2ab8bc3 100644
--- a/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/StringGenerator.java
+++ b/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/StringGenerator.java
@@ -27,9 +27,23 @@
 import org.onosproject.yangutils.utils.io.YangPluginConfig;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BOOLEAN;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.DECIMAL64;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.EMPTY;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT16;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT32;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT64;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT8;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT16;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT32;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT64;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT8;
 import static org.onosproject.yangutils.translator.tojava.utils.BracketType.OPEN_CLOSE_BRACKET;
 import static org.onosproject.yangutils.translator.tojava.utils.BracketType.OPEN_CLOSE_BRACKET_WITH_VALUE;
 import static org.onosproject.yangutils.translator.tojava.utils.BracketType.OPEN_CLOSE_BRACKET_WITH_VALUE_AND_RETURN_TYPE;
@@ -148,6 +162,12 @@
  */
 public final class StringGenerator {
 
+    private static final Set<YangDataTypes> PRIMITIVE_TYPES =
+            new HashSet<>(Arrays.asList(INT8, INT16, INT32, INT64, UINT8,
+                                        UINT16, UINT32, UINT64, DECIMAL64,
+                                        BOOLEAN, EMPTY));
+
+    // No instantiation.
     private StringGenerator() {
     }
 
@@ -746,48 +766,59 @@
      */
     static String getParseFromStringMethod(String targetDataType,
                                            YangType<?> yangType) {
-        YangDataTypes type = yangType.getDataType();
 
+        YangDataTypes type = yangType.getDataType();
         switch (type) {
             case INT8:
                 return BYTE_WRAPPER + PERIOD + PARSE_BYTE;
+
             case INT16:
                 return SHORT_WRAPPER + PERIOD + PARSE_SHORT;
+
             case INT32:
                 return INTEGER_WRAPPER + PERIOD + PARSE_INT;
+
             case INT64:
                 return LONG_WRAPPER + PERIOD + PARSE_LONG;
+
             case UINT8:
                 return SHORT_WRAPPER + PERIOD + PARSE_SHORT;
+
             case UINT16:
                 return INTEGER_WRAPPER + PERIOD + PARSE_INT;
+
             case UINT32:
                 return LONG_WRAPPER + PERIOD + PARSE_LONG;
+
             case UINT64:
                 return NEW + SPACE + BIG_INTEGER;
+
             case DECIMAL64:
                 return NEW + SPACE + BIG_DECIMAL;
+
+            case INSTANCE_IDENTIFIER:
             case STRING:
             case IDENTITYREF:
                 return EMPTY_STRING;
+
             case EMPTY:
             case BOOLEAN:
                 return BOOLEAN_WRAPPER + PERIOD + PARSE_BOOLEAN;
+
             case ENUMERATION:
                 return targetDataType + PERIOD + OF;
+
             case DERIVED:
             case UNION:
                 return targetDataType + PERIOD + FROM_STRING_METHOD_NAME;
+
             default:
-                throw new TranslatorException("given data type is not " +
-                                                      "supported. " +
-                                                      yangType.getDataTypeName() +
-                                                      " in " +
-                                                      yangType.getLineNumber() +
-                                                      " at " +
-                                                      yangType.getCharPosition() +
-                                                      " in " +
-                                                      yangType.getFileName());
+                throw new TranslatorException(
+                        "Given data type is not supported. " +
+                                yangType.getDataTypeName() + " in " +
+                                yangType.getLineNumber() + " at " +
+                                yangType.getCharPosition() + " in " +
+                                yangType.getFileName());
         }
     }
 
@@ -873,6 +904,16 @@
     }
 
     /**
+     * Returns true, if the data type is primitive; false otherwise.
+     *
+     * @param dataType data type
+     * @return true if the data type is primitive; false otherwise
+     */
+    public static boolean isPrimitiveDataType(YangDataTypes dataType) {
+        return PRIMITIVE_TYPES.contains(dataType);
+    }
+
+    /**
      * Returns list string.
      *
      * @return list string
diff --git a/parser/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java b/parser/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
index 4ca9c5a..393f09e 100644
--- a/parser/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
+++ b/parser/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
@@ -54,7 +54,7 @@
 import org.onosproject.yangutils.parser.impl.listeners.FractionDigitsListener;
 import org.onosproject.yangutils.parser.impl.listeners.GroupingListener;
 import org.onosproject.yangutils.parser.impl.listeners.IdentityListener;
-import org.onosproject.yangutils.parser.impl.listeners.IdentityrefListener;
+import org.onosproject.yangutils.parser.impl.listeners.IdentityRefListener;
 import org.onosproject.yangutils.parser.impl.listeners.IfFeatureListener;
 import org.onosproject.yangutils.parser.impl.listeners.ImportListener;
 import org.onosproject.yangutils.parser.impl.listeners.IncludeListener;
@@ -862,14 +862,14 @@
     @Override
     public void enterIdentityrefSpecification(GeneratedYangParser.IdentityrefSpecificationContext ctx) {
         if (getUnsupportedYangConstructDepth() == 0) {
-            IdentityrefListener.processIdentityrefEntry(this, ctx);
+            IdentityRefListener.processIdentityRefEntry(this, ctx);
         }
     }
 
     @Override
     public void exitIdentityrefSpecification(GeneratedYangParser.IdentityrefSpecificationContext ctx) {
         if (getUnsupportedYangConstructDepth() == 0) {
-            IdentityrefListener.processIdentityrefExit(this, ctx);
+            IdentityRefListener.processIdentityRefExit(this, ctx);
         }
     }
 
diff --git a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IdentityRefListener.java b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IdentityRefListener.java
new file mode 100644
index 0000000..a6fbd1e
--- /dev/null
+++ b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IdentityRefListener.java
@@ -0,0 +1,187 @@
+/*
+ * 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.parser.impl.listeners;
+
+import org.onosproject.yangutils.datamodel.YangIdentityRef;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
+import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.datamodel.utils.Parsable;
+import org.onosproject.yangutils.linker.impl.YangResolutionInfoImpl;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
+import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
+import static org.onosproject.yangutils.datamodel.utils.YangConstructType.BASE_DATA;
+import static org.onosproject.yangutils.datamodel.utils.YangConstructType.IDENTITYREF_DATA;
+import static org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser.IdentityrefSpecificationContext;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidNodeIdentifier;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
+import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
+
+/*
+ * Reference: RFC6020 and YANG ANTLR Grammar
+ * <p/>
+ * ABNF grammar as per RFC6020
+ * identityref-specification =
+ * base-stmt stmtsep
+ * base-stmt           = base-keyword sep identifier-ref-arg-str
+ * optsep stmtend*
+ * identifier-ref-arg  = [prefix ":"] identifier
+ */
+
+/**
+ * Represents listener based call back function corresponding to the
+ * "identityref" rule defined in ANTLR grammar file for corresponding ABNF
+ * rule in RFC 6020.
+ */
+public final class IdentityRefListener {
+
+    // No instantiation.
+    private IdentityRefListener() {
+    }
+
+    /**
+     * Performs validation and updates the data model tree when parser receives an input
+     * matching the grammar rule (identity-ref).
+     *
+     * @param listener listener object
+     * @param ctx      context object
+     */
+    public static void processIdentityRefEntry(TreeWalkListener listener,
+                                               IdentityrefSpecificationContext ctx) {
+
+        // Check for stack to be non empty.
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, IDENTITYREF_DATA,
+                             EMPTY_STRING, ENTRY);
+
+        if (!(listener.getParsedDataStack().peek() instanceof YangType)) {
+            throw new ParserException(constructListenerErrorMessage(
+                    INVALID_HOLDER, IDENTITYREF_DATA, EMPTY_STRING, ENTRY));
+        }
+
+        YangIdentityRef idRef = new YangIdentityRef();
+        Parsable typeData = listener.getParsedDataStack().pop();
+        YangResolutionInfoImpl<YangIdentityRef> resolutionInfo;
+
+        // Validate node identifier.
+        YangNodeIdentifier nodeId = getValidNodeIdentifier(
+                ctx.baseStatement().string().getText(), BASE_DATA, ctx);
+        idRef.setBaseIdentity(nodeId);
+        ((YangType) typeData).setDataTypeExtendedInfo(idRef);
+
+        int errLine = ctx.getStart().getLine();
+        int errPos = ctx.getStart().getCharPositionInLine();
+
+        idRef.setLineNumber(errLine);
+        idRef.setCharPosition(errPos);
+        idRef.setFileName(listener.getFileName());
+
+        Parsable tmpData = listener.getParsedDataStack().peek();
+        Parsable parentNode;
+        switch (tmpData.getYangConstructType()) {
+
+            case LEAF_DATA:
+                Parsable leaf = listener.getParsedDataStack().pop();
+                parentNode = listener.getParsedDataStack().peek();
+                listener.getParsedDataStack().push(leaf);
+                break;
+
+            case LEAF_LIST_DATA:
+                Parsable leafList = listener.getParsedDataStack().pop();
+                parentNode = listener.getParsedDataStack().peek();
+                listener.getParsedDataStack().push(leafList);
+                break;
+
+            case UNION_DATA:
+                parentNode = listener.getParsedDataStack().peek();
+                break;
+
+            case TYPEDEF_DATA:
+                parentNode = listener.getParsedDataStack().peek();
+                break;
+
+            default:
+                throw new ParserException(
+                        constructListenerErrorMessage(INVALID_HOLDER,
+                                                      IDENTITYREF_DATA,
+                                                      ctx.getText(), EXIT));
+        }
+
+        if (!(parentNode instanceof YangNode)) {
+            throw new ParserException(
+                    constructListenerErrorMessage(INVALID_HOLDER,
+                                                  IDENTITYREF_DATA,
+                                                  ctx.getText(), EXIT));
+        }
+        idRef.setResolvableStatus(UNRESOLVED);
+        // Adds resolution information to the list
+        resolutionInfo = new YangResolutionInfoImpl<>(
+                idRef, (YangNode) parentNode, errLine, errPos);
+        addToResolution(resolutionInfo, ctx);
+
+        listener.getParsedDataStack().push(typeData);
+        listener.getParsedDataStack().push(idRef);
+    }
+
+    /**
+     * Performs validations and update the data model tree when parser exits
+     * from grammar rule (identity-ref).
+     *
+     * @param listener Listener's object
+     * @param ctx      context object
+     */
+    public static void processIdentityRefExit(TreeWalkListener listener,
+                                              IdentityrefSpecificationContext ctx) {
+
+        // Check for stack to be non empty.
+        checkStackIsNotEmpty(listener, MISSING_CURRENT_HOLDER, IDENTITYREF_DATA,
+                             ctx.getText(), EXIT);
+
+        Parsable parsableType = listener.getParsedDataStack().pop();
+        if (!(parsableType instanceof YangIdentityRef)) {
+            throw new ParserException(constructListenerErrorMessage(
+                    INVALID_HOLDER, IDENTITYREF_DATA, ctx.getText(), EXIT));
+        }
+    }
+
+    /**
+     * Adds to resolution list.
+     *
+     * @param info resolution info
+     * @param ctx  context object
+     */
+    private static void addToResolution(YangResolutionInfoImpl<YangIdentityRef> info,
+                                        IdentityrefSpecificationContext ctx) {
+        try {
+            addResolutionInfo(info);
+        } catch (DataModelException e) {
+            throw new ParserException(constructExtendedListenerErrorMessage(
+                    UNHANDLED_PARSED_DATA, IDENTITYREF_DATA, ctx.getText(),
+                    ENTRY, e.getMessage()));
+        }
+    }
+}
diff --git a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IdentityrefListener.java b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IdentityrefListener.java
deleted file mode 100644
index 17f197a..0000000
--- a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IdentityrefListener.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * 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.parser.impl.listeners;
-
-import org.onosproject.yangutils.datamodel.YangIdentityRef;
-import org.onosproject.yangutils.datamodel.YangNode;
-import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
-import org.onosproject.yangutils.datamodel.YangType;
-import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
-import org.onosproject.yangutils.datamodel.utils.Parsable;
-import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
-import org.onosproject.yangutils.linker.impl.YangResolutionInfoImpl;
-import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
-import org.onosproject.yangutils.parser.exceptions.ParserException;
-import org.onosproject.yangutils.parser.impl.TreeWalkListener;
-
-import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
-import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
-import static org.onosproject.yangutils.datamodel.utils.YangConstructType.BASE_DATA;
-import static org.onosproject.yangutils.datamodel.utils.YangConstructType.IDENTITYREF_DATA;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
-        .constructExtendedListenerErrorMessage;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
-        .constructListenerErrorMessage;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidNodeIdentifier;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
-
-/**
- * Reference: RFC6020 and YANG ANTLR Grammar
- *
- * ABNF grammar as per RFC6020
- * identityref-specification =
- *                        base-stmt stmtsep
- * base-stmt           = base-keyword sep identifier-ref-arg-str
- *                          optsep stmtend*
- * identifier-ref-arg  = [prefix ":"] identifier
- */
-
-/**
- * Represents listener based call back function corresponding to the "identityref"
- * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
- */
-public final class IdentityrefListener {
-
-    //Creates a new type listener.
-    private IdentityrefListener() {
-    }
-
-    /**
-     * Performs validation and updates the data model tree when parser receives an input
-     * matching the grammar rule (identityref).
-     *
-     * @param listener listener's object
-     * @param ctx      context object of the grammar rule
-     */
-    public static void processIdentityrefEntry(TreeWalkListener listener,
-                                               GeneratedYangParser.IdentityrefSpecificationContext ctx) {
-
-        // Check for stack to be non empty.
-        checkStackIsNotEmpty(listener, MISSING_HOLDER, IDENTITYREF_DATA, "", ENTRY);
-
-        if (listener.getParsedDataStack().peek() instanceof YangType) {
-
-            YangIdentityRef identityRef = new YangIdentityRef();
-            Parsable typeData = listener.getParsedDataStack().pop();
-            YangDataTypes yangDataTypes = ((YangType) typeData).getDataType();
-            YangResolutionInfoImpl resolutionInfo;
-
-            // Validate node identifier.
-            YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(ctx.baseStatement().string().getText(),
-                    BASE_DATA, ctx);
-            identityRef.setBaseIdentity(nodeIdentifier);
-            ((YangType) typeData).setDataTypeExtendedInfo(identityRef);
-
-            int errorLine = ctx.getStart().getLine();
-            int errorPosition = ctx.getStart().getCharPositionInLine();
-
-            identityRef.setLineNumber(errorLine);
-            identityRef.setCharPosition(errorPosition);
-            identityRef.setFileName(listener.getFileName());
-            Parsable tmpData = listener.getParsedDataStack().peek();
-            switch (tmpData.getYangConstructType()) {
-                case LEAF_DATA:
-
-                    // Pop the stack entry to obtain the parent YANG node.
-                    Parsable leaf = listener.getParsedDataStack().pop();
-                    Parsable parentNodeOfLeaf = listener.getParsedDataStack().peek();
-
-                    // Push the popped entry back to the stack.
-                    listener.getParsedDataStack().push(leaf);
-
-                    // Verify parent node of leaf
-                    if (!(parentNodeOfLeaf instanceof YangNode)) {
-                        throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
-                                IDENTITYREF_DATA, ctx.getText(), EXIT));
-                    }
-
-                    identityRef.setResolvableStatus(UNRESOLVED);
-
-                    if (listener.getGroupingDepth() == 0) {
-                        // Add resolution information to the list
-                        resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
-                                (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
-                        addToResolutionList(resolutionInfo, ctx);
-                    } else {
-                        identityRef.setInGrouping(true);
-                    }
-                    break;
-                case LEAF_LIST_DATA:
-
-                    // Pop the stack entry to obtain the parent YANG node.
-                    Parsable leafList = listener.getParsedDataStack().pop();
-                    Parsable parentNodeOfLeafList = listener.getParsedDataStack().peek();
-
-                    // Push the popped entry back to the stack.
-                    listener.getParsedDataStack().push(leafList);
-
-                    // Verify parent node of leaf
-                    if (!(parentNodeOfLeafList instanceof YangNode)) {
-                        throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
-                                IDENTITYREF_DATA, ctx.getText(), EXIT));
-                    }
-
-                    identityRef.setResolvableStatus(UNRESOLVED);
-
-                    if (listener.getGroupingDepth() == 0) {
-                        // Add resolution information to the list
-                        resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
-                                (YangNode) parentNodeOfLeafList, errorLine, errorPosition);
-                        addToResolutionList(resolutionInfo, ctx);
-                    } else {
-                        identityRef.setInGrouping(true);
-                    }
-                    break;
-                case UNION_DATA:
-
-                    Parsable parentNodeOfUnionNode = listener.getParsedDataStack().peek();
-
-                    // Verify parent node of leaf
-                    if (!(parentNodeOfUnionNode instanceof YangNode)) {
-                        throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
-                                IDENTITYREF_DATA, ctx.getText(), EXIT));
-                    }
-
-                    identityRef.setResolvableStatus(UNRESOLVED);
-
-                    if (listener.getGroupingDepth() == 0) {
-                        // Add resolution information to the list
-                        resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
-                                (YangNode) parentNodeOfUnionNode, errorLine, errorPosition);
-                        addToResolutionList(resolutionInfo, ctx);
-                    } else {
-                        identityRef.setInGrouping(true);
-                    }
-                    break;
-                case TYPEDEF_DATA:
-                    if (listener.getGroupingDepth() != 0) {
-                        identityRef.setInGrouping(true);
-                    }
-                    /**
-                     * Do not add the identity ref to resolution list. It needs to be
-                     * added to resolution list, when leaf/leaf list references to
-                     * this typedef. At this time that leaf/leaf-list becomes the
-                     * parent for the identityref.
-                     */
-                    break;
-                default:
-                    throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, IDENTITYREF_DATA,
-                            ctx.getText(), EXIT));
-            }
-            listener.getParsedDataStack().push(typeData);
-            listener.getParsedDataStack().push(identityRef);
-        } else {
-            throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, IDENTITYREF_DATA, "", ENTRY));
-        }
-    }
-
-    /**
-     * Performs validations and update the data model tree when parser exits from grammar
-     * rule (identityref).
-     *
-     * @param listener Listener's object
-     * @param ctx      context object of the grammar rule
-     */
-    public static void processIdentityrefExit(TreeWalkListener listener,
-                                              GeneratedYangParser.IdentityrefSpecificationContext ctx) {
-
-        // Check for stack to be non empty.
-        checkStackIsNotEmpty(listener, MISSING_CURRENT_HOLDER, IDENTITYREF_DATA, ctx.getText(), EXIT);
-
-        Parsable parsableType = listener.getParsedDataStack().pop();
-        if (!(parsableType instanceof YangIdentityRef)) {
-            throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, IDENTITYREF_DATA,
-                    ctx.getText(), EXIT));
-        }
-    }
-
-    /**
-     * Adds to resolution list.
-     *
-     * @param resolutionInfo resolution information
-     * @param ctx            context object of the grammar rule
-     */
-    private static void addToResolutionList(YangResolutionInfoImpl<YangIdentityRef> resolutionInfo,
-                                            GeneratedYangParser.IdentityrefSpecificationContext ctx) {
-        try {
-            addResolutionInfo(resolutionInfo);
-        } catch (DataModelException e) {
-            throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
-                    IDENTITYREF_DATA, ctx.getText(), ENTRY, e.getMessage()));
-        }
-    }
-}
diff --git a/plugin/maven/src/test/java/org/onosproject/yangutils/parser/impl/listeners/IdentityListenerTest.java b/plugin/maven/src/test/java/org/onosproject/yangutils/parser/impl/listeners/IdentityListenerTest.java
index b0ae937..b407c1b 100644
--- a/plugin/maven/src/test/java/org/onosproject/yangutils/parser/impl/listeners/IdentityListenerTest.java
+++ b/plugin/maven/src/test/java/org/onosproject/yangutils/parser/impl/listeners/IdentityListenerTest.java
@@ -18,6 +18,7 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
 import org.onosproject.yangutils.datamodel.YangIdentity;
 import org.onosproject.yangutils.datamodel.YangIdentityRef;
 import org.onosproject.yangutils.datamodel.YangLeaf;
@@ -37,16 +38,18 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.IDENTITYREF;
 
 /**
  * Test case for identity listener.
  */
 public class IdentityListenerTest {
-    @Rule
-    public ExpectedException thrown = ExpectedException.none();
 
     private final YangUtilsParserManager manager = new YangUtilsParserManager();
 
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
     /**
      * Checks for updating datamodel for identity/identityref.
      */
@@ -174,14 +177,20 @@
         YangLeaf leafInfo = leafIterator.next();
 
         assertThat(leafInfo.getName(), is("tunnel-value"));
-        assertThat(leafInfo.getDataType().getDataTypeName(), is("identityref"));
-        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.IDENTITYREF));
-        YangIdentityRef yangIdentityRef = (YangIdentityRef) leafInfo.getDataType().getDataTypeExtendedInfo();
-        assertThat(yangIdentityRef.getName(), is("tunnel"));
-        assertThat(yangIdentityRef.getBaseIdentity().getName(), is("tunnel"));
-        assertThat(yangIdentityRef.getReferredIdentity().getName(), is("tunnel"));
-        assertThat(yangIdentityRef.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
-   }
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("type15"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.DERIVED));
+
+        YangDerivedInfo info = (YangDerivedInfo) leafInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        assertThat(info.getEffectiveBuiltInType(), is(IDENTITYREF));
+        YangType type1 = info.getReferredTypeDef().getTypeList().get(0);
+        YangIdentityRef idRef1 =
+                (YangIdentityRef) type1.getDataTypeExtendedInfo();
+        assertThat(idRef1.getName(), is("tunnel"));
+        assertThat(idRef1.getBaseIdentity().getName(), is("tunnel"));
+        assertThat(idRef1.getReferredIdentity().getName(), is("tunnel"));
+        assertThat(idRef1.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
+    }
 
     /**
      * Checks for updating datamodel for unresolved status of identityref used in tydedef.
@@ -211,10 +220,11 @@
         assertThat(type.getDataType(), is(YangDataTypes.IDENTITYREF));
         assertThat(type.getDataTypeName(), is("identityref"));
 
-        YangIdentityRef identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
-        assertThat(identityRef.getName(), is("tunnel"));
-        assertThat(identityRef.getBaseIdentity().getName(), is("tunnel"));
-        assertThat(identityRef.getResolvableStatus(), is(ResolvableStatus.UNRESOLVED));
+        YangIdentityRef idRef =
+                (YangIdentityRef) type.getDataTypeExtendedInfo();
+        assertThat(idRef.getName(), is("tunnel"));
+        assertThat(idRef.getBaseIdentity().getName(), is("tunnel"));
+        assertThat(idRef.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
 
     }
 }
diff --git a/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileIdentityLinkingTest.java b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileIdentityLinkingTest.java
index 6c29c28..45bc03d 100644
--- a/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileIdentityLinkingTest.java
+++ b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileIdentityLinkingTest.java
@@ -15,12 +15,11 @@
  */
 package org.onosproject.yangutils.plugin.manager;
 
-import java.io.IOException;
-import java.util.ListIterator;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
 import org.onosproject.yangutils.datamodel.YangIdentity;
 import org.onosproject.yangutils.datamodel.YangIdentityRef;
 import org.onosproject.yangutils.datamodel.YangLeaf;
@@ -36,21 +35,26 @@
 import org.onosproject.yangutils.parser.exceptions.ParserException;
 import org.onosproject.yangutils.utils.io.impl.YangFileScanner;
 
+import java.io.IOException;
+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.IDENTITYREF;
 import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.updateFilePriority;
 
 /**
  * Test cases for testing inter file linking for identity.
  */
 public class InterFileIdentityLinkingTest {
-    @Rule
-    public ExpectedException thrown = ExpectedException.none();
 
     private final YangUtilManager utilManager = new YangUtilManager();
     private final YangLinkerManager yangLinkerManager = new YangLinkerManager();
 
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
     /**
      * Checks inter file feature linking with imported file.
      */
@@ -556,7 +560,8 @@
         YangIdentityRef identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
         assertThat(identityRef.getName(), is("ref-address-family"));
         assertThat(identityRef.getBaseIdentity().getName(), is("ref-address-family"));
-        assertThat(identityRef.getResolvableStatus(), is(ResolvableStatus.UNRESOLVED));
+        assertThat(identityRef.getResolvableStatus(),
+                   is(ResolvableStatus.RESOLVED));
     }
 
     /**
@@ -633,23 +638,26 @@
         YangLeaf leafInfo = leafIterator.next();
 
         assertThat(leafInfo.getName(), is("tunnel"));
-        assertThat(leafInfo.getDataType().getDataTypeName(), is("identityref"));
-        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.IDENTITYREF));
-        YangIdentityRef yangIdentityRef = (YangIdentityRef) leafInfo.getDataType().getDataTypeExtendedInfo();
-        assertThat(yangIdentityRef.getName(), is("ref-address-family"));
-        assertThat(yangIdentityRef.getBaseIdentity().getName(), is("ref-address-family"));
-        assertThat(yangIdentityRef.getReferredIdentity().getName(), is("ref-address-family"));
-        assertThat(yangIdentityRef.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
+        YangDerivedInfo info = (YangDerivedInfo) leafInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        assertThat(info.getEffectiveBuiltInType(), is(IDENTITYREF));
+        YangType type1 = info.getReferredTypeDef().getTypeList().get(0);
+        YangIdentityRef idRef1 =
+                (YangIdentityRef) type1.getDataTypeExtendedInfo();
+        assertThat(idRef1.getResolvableStatus(),
+                   is(ResolvableStatus.RESOLVED));
 
-        ListIterator<YangLeafList> leafListIterator = yangNode.getListOfLeafList().listIterator();
-        YangLeafList leafListInfo = leafListIterator.next();
+        ListIterator<YangLeafList> itr =
+                yangNode.getListOfLeafList().listIterator();
+        YangLeafList leafListInfo = itr.next();
 
         // Check whether the information in the leaf is correct.
         assertThat(leafListInfo.getName(), is("network-ref"));
-        assertThat(leafListInfo.getDataType().getDataTypeName(), is("identityref"));
-        assertThat(leafListInfo.getDataType().getDataType(), is(YangDataTypes.IDENTITYREF));
-        yangIdentityRef = (YangIdentityRef) (leafListInfo.getDataType().getDataTypeExtendedInfo());
-        // Check whether leafref type got resolved.
-        assertThat(yangIdentityRef.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
+        info = (YangDerivedInfo) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        assertThat(info.getEffectiveBuiltInType(), is(IDENTITYREF));
+        type1 = info.getReferredTypeDef().getTypeList().get(0);
+        idRef1 = (YangIdentityRef) type1.getDataTypeExtendedInfo();
+        assertThat(idRef1.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
     }
 }
diff --git a/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/TypeLinkingAfterCloningTest.java b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/TypeLinkingAfterCloningTest.java
index 038e991..441a40b 100644
--- a/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/TypeLinkingAfterCloningTest.java
+++ b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/TypeLinkingAfterCloningTest.java
@@ -31,6 +31,7 @@
 import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.datamodel.YangTypeDef;
 import org.onosproject.yangutils.datamodel.YangUnion;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 import org.onosproject.yangutils.linker.impl.YangLinkerManager;
 import org.onosproject.yangutils.parser.exceptions.ParserException;
 
@@ -42,6 +43,7 @@
 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.IDENTITYREF;
 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;
@@ -50,6 +52,7 @@
  * 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";
@@ -65,6 +68,12 @@
     private static final String FIRST = "first";
     private static final String TYPEDEF = "typedef";
     private static final String CORRECT = "correct";
+    private static final String UNI = "with-uni";
+    private static final String UNION = "union";
+    private static final String BASE1 = "id2";
+    private static final String BASE2 = "id1";
+    private static final String DIR =
+            "src/test/resources/typelinkingaftercloning/";
 
     private final YangUtilManager utilMgr = new YangUtilManager();
     private final YangLinkerManager linkerMgr = new YangLinkerManager();
@@ -72,6 +81,21 @@
     @Rule
     public ExpectedException thrown = ExpectedException.none();
 
+    private ListIterator<YangLeaf> leafItr;
+    private YangLeaf leafInfo;
+    private ListIterator<YangLeafList> leafListItr;
+    private YangLeafList leafListInfo;
+    private YangIdentityRef idRef;
+    private YangUnion union;
+    private Iterator<YangType<?>> unionTypeItr;
+    private YangType type;
+    private YangDerivedInfo derInfo;
+    private YangType type2;
+    private YangType type3;
+    private YangType type1;
+    private YangDerivedInfo derInfo1;
+    private YangTypeDef typedef1;
+
     /**
      * Returns the error message as the node name incorrect, when assert fails.
      *
@@ -126,14 +150,12 @@
     /**
      * Processes leaf-ref after its cloned to uses from grouping.
      *
-     * @throws IOException io error when finding file
+     * @throws IOException if violates IO operation
      */
     @Test
     public void processLeafRefAfterCloning() throws IOException {
 
-        String searchDir = "src/test/resources/typelinkingaftercloning" +
-                "/leafref/intrafile";
-        utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "leafref/intrafile"));
         utilMgr.parseYangFileInfoSet();
         utilMgr.createYangNodeSet();
         YangNode selfNode;
@@ -153,12 +175,6 @@
 
         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));
 
@@ -171,6 +187,8 @@
         YangList list = (YangList) selfNode.getChild().getNextSibling()
                 .getNextSibling();
 
+        YangLeafRef leafRef;
+
         leafItr = list.getListOfLeaf().listIterator();
         leafInfo = leafItr.next();
 
@@ -225,7 +243,7 @@
     }
 
     /**
-     * Processed invalid scenario where a leaf-ref is present in union.
+     * Processes invalid scenario where a leaf-ref is present in union.
      *
      * @throws IOException io error when finding file
      */
@@ -235,23 +253,19 @@
         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.createYangFileInfoSet(getYangFiles(DIR + "leafref/invalid"));
         utilMgr.parseYangFileInfoSet();
     }
 
     /**
      * Processes simple identity-ref after it gets cloned from grouping.
      *
-     * @throws IOException io error when finding file
+     * @throws IOException if violates IO operation
      */
     @Test
-    public void processIdentityRefAfterCloning() throws IOException {
+    public void processIdentityRefBeforeCloning() throws IOException {
 
-        String searchDir = "src/test/resources/typelinkingaftercloning" +
-                "/identityref";
-        utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "identityref"));
         utilMgr.parseYangFileInfoSet();
         utilMgr.createYangNodeSet();
         YangNode selfNode;
@@ -271,15 +285,6 @@
 
         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));
 
@@ -301,11 +306,11 @@
         union = (YangUnion) leafInfo.getDataType().getDataTypeExtendedInfo();
         unionTypeItr = union.getTypeList().listIterator();
         type = unionTypeItr.next();
-        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        idRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
 
         // Checks the effective type for the leaf.
         assertThat(getInCrtLeafType(LEAF, FACILITY),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(FACILITY_SYS_LOG));
 
         leafInfo = leafItr.next();
@@ -313,12 +318,12 @@
         // 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()
+        idRef = (YangIdentityRef) leafInfo.getDataType()
                 .getDataTypeExtendedInfo();
 
         // Checks the effective type for the leaf.
         assertThat(getInCrtLeafType(LEAF, NODE_ID),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(FACILITY_SYS_LOG));
 
         leafListItr = list.getListOfLeafList().listIterator();
@@ -328,12 +333,15 @@
         assertThat(getInCrtName(LEAF_LIST, NODE_REF), leafListInfo.getName(),
                    is(NODE_REF));
 
-        identityRef = (YangIdentityRef) leafListInfo.getDataType()
+        derInfo = (YangDerivedInfo) leafListInfo.getDataType()
                 .getDataTypeExtendedInfo();
 
+        type = derInfo.getReferredTypeDef().getTypeList().get(0);
+        idRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+
         // Checks the effective type for the leaf-list.
         assertThat(getInCrtLeafType(LEAF, NODE_REF),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(FACILITY_SYS_LOG));
 
         YangContainer container = (YangContainer) list.getChild()
@@ -349,11 +357,11 @@
                 .getDataTypeExtendedInfo();
         unionTypeItr = union.getTypeList().listIterator();
         type = unionTypeItr.next();
-        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        idRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
 
         // Checks the effective type for the leaf-list.
         assertThat(getInCrtLeafType(LEAF_LIST, FACILITY),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(FACILITY_SYS_LOG));
 
         leafListInfo = leafListItr.next();
@@ -361,12 +369,12 @@
         // Checks the leaf-list information is correct.
         assertThat(getInCrtName(LEAF_LIST, NODE_REF), leafListInfo.getName(),
                    is(NODE_REF));
-        identityRef = (YangIdentityRef) leafListInfo.getDataType()
+        idRef = (YangIdentityRef) leafListInfo.getDataType()
                 .getDataTypeExtendedInfo();
 
         // Checks the effective type for the leaf.
         assertThat(getInCrtLeafType(LEAF_LIST, NODE_REF),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(FACILITY_SYS_LOG));
 
         leafItr = container.getListOfLeaf().listIterator();
@@ -375,11 +383,11 @@
         // Checks the leaf information is correct.
         assertThat(getInCrtName(LEAF, NODE_ID), leafInfo.getName(),
                    is(NODE_ID));
-        identityRef = (YangIdentityRef) leafListInfo.getDataType()
+        idRef = (YangIdentityRef) leafListInfo.getDataType()
                 .getDataTypeExtendedInfo();
 
         assertThat(getInCrtLeafType(LEAF, NODE_ID),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(FACILITY_SYS_LOG));
 
     }
@@ -387,13 +395,12 @@
     /**
      * Processes union having different recursive level with identity-ref.
      *
-     * @throws IOException io error when finding file
+     * @throws IOException if violates IO operation
      */
     @Test
     public void processUnionAfterCloning() throws IOException {
 
-        String searchDir = "src/test/resources/typelinkingaftercloning/union";
-        utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "union"));
         utilMgr.parseYangFileInfoSet();
         utilMgr.createYangNodeSet();
         YangNode selfNode;
@@ -410,16 +417,10 @@
         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<?>> unionTypeItr2;
         Iterator<YangType<?>> unionTypeItr3;
-        YangType type3;
         YangDerivedInfo derivedInfo;
         YangTypeDef typeDef;
         Iterator<YangType<?>> typeDefItr;
@@ -460,26 +461,28 @@
         type3 = unionTypeItr3.next();
 
         // Checks the first identity-ref in third level union.
-        identityRef = (YangIdentityRef) type3.getDataTypeExtendedInfo();
+        idRef = (YangIdentityRef) type3.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 THIRD, FIRST, USABILITY_SYS_LOG, LEAF, FACILITY),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(USABILITY_SYS_LOG));
 
         // Checks the first identity-ref in second level union.
         type2 = unionTypeItr2.next();
-        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        idRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 SECOND, FIRST, FACILITY_SYS_LOG, LEAF, FACILITY),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(FACILITY_SYS_LOG));
 
         // Checks the first identity-ref in first level union.
         type = unionTypeItr.next();
-        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        derInfo = (YangDerivedInfo) type.getDataTypeExtendedInfo();
+        type = derInfo.getReferredTypeDef().getTypeList().get(0);
+        idRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 FIRST, FIRST, AVAILABILITY_SYS_LOG, LEAF, FACILITY),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(AVAILABILITY_SYS_LOG));
 
         // Checks derived type in third level union.
@@ -500,26 +503,28 @@
         type2 = unionTypeItr2.next();
 
         // Checks the first identity-ref in second level union.
-        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        idRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 SECOND, FIRST, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(AVAILABILITY_SYS_LOG));
 
         // Checks the second identity-ref in second level union.
         type2 = unionTypeItr2.next();
-        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        derInfo = (YangDerivedInfo) type2.getDataTypeExtendedInfo();
+        type2 = derInfo.getReferredTypeDef().getTypeList().get(0);
+        idRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 SECOND, SECOND, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(AVAILABILITY_SYS_LOG));
 
         // Checks the first identity-ref in first level union.
         type = unionTypeItr.next();
-        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        idRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 FIRST, FIRST, USABILITY_SYS_LOG, TYPEDEF, CORRECT),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(USABILITY_SYS_LOG));
 
         YangContainer container = (YangContainer) list.getChild()
@@ -551,26 +556,28 @@
         type3 = unionTypeItr3.next();
 
         // Checks the first identity-ref in third level union.
-        identityRef = (YangIdentityRef) type3.getDataTypeExtendedInfo();
+        idRef = (YangIdentityRef) type3.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 THIRD, FIRST, USABILITY_SYS_LOG, LEAF_LIST, FACILITY),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(USABILITY_SYS_LOG));
 
         // Checks the first identity-ref in second level union.
         type2 = unionTypeItr2.next();
-        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        idRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 SECOND, FIRST, FACILITY_SYS_LOG, LEAF_LIST, FACILITY),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(FACILITY_SYS_LOG));
 
         // Checks the first identity-ref in first level union.
         type = unionTypeItr.next();
-        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        derInfo = (YangDerivedInfo) type.getDataTypeExtendedInfo();
+        type = derInfo.getReferredTypeDef().getTypeList().get(0);
+        idRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 FIRST, FIRST, AVAILABILITY_SYS_LOG, LEAF_LIST, FACILITY),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(AVAILABILITY_SYS_LOG));
 
         // Checks derived type in third level union.
@@ -591,26 +598,220 @@
         type2 = unionTypeItr2.next();
 
         // Checks the first identity-ref in second level union.
-        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        idRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 SECOND, FIRST, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(AVAILABILITY_SYS_LOG));
 
         // Checks the second identity-ref in second level union.
         type2 = unionTypeItr2.next();
-        identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        derInfo = (YangDerivedInfo) type2.getDataTypeExtendedInfo();
+        type2 = derInfo.getReferredTypeDef().getTypeList().get(0);
+        idRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 SECOND, SECOND, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(AVAILABILITY_SYS_LOG));
 
         // Checks the first identity-ref in first level union.
         type = unionTypeItr.next();
-        identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        idRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
         assertThat(getInCrtUnionWithIdRef(
                 FIRST, FIRST, USABILITY_SYS_LOG, TYPEDEF, CORRECT),
-                   identityRef.getBaseIdentity().getName(),
+                   idRef.getBaseIdentity().getName(),
                    is(USABILITY_SYS_LOG));
     }
+
+    /**
+     * Processes identity-ref when present under typedef, during intra and
+     * inter file linking.
+     *
+     * @throws IOException if violates IO operation
+     */
+    @Test
+    public void processIdentityRefWithTypeDef() throws IOException {
+
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "idreftypedef"));
+        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();
+        YangNode rootNode = nodeItr.next();
+
+        if (rootNode.getName().equals("IdRefInTypeDef1")) {
+            selfNode = rootNode;
+        } else {
+            selfNode = nodeItr.next();
+        }
+
+        YangDerivedInfo derInfo2;
+        YangTypeDef typedef2;
+        YangDerivedInfo derInfo3;
+        YangTypeDef typedef3;
+
+        YangModule module = (YangModule) selfNode;
+        leafItr = module.getListOfLeaf().listIterator();
+
+        // Gets the first leaf, which has three typedef with effective id-ref.
+        leafInfo = leafItr.next();
+        assertThat(getInCrtName(LEAF, LEAF), leafInfo.getName(), is(LEAF));
+        assertThat(getInCrtLeafType(LEAF, LEAF),
+                   leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        // Traverses through the three typedef in it.
+        derInfo1 = (YangDerivedInfo) leafInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        typedef1 = derInfo1.getReferredTypeDef();
+        type1 = typedef1.getTypeList().get(0);
+        derInfo2 = (YangDerivedInfo) type1.getDataTypeExtendedInfo();
+        typedef2 = derInfo2.getReferredTypeDef();
+        type2 = typedef2.getTypeList().get(0);
+        derInfo3 = (YangDerivedInfo) type2.getDataTypeExtendedInfo();
+        typedef3 = derInfo3.getReferredTypeDef();
+        type3 = typedef3.getTypeList().get(0);
+        idRef = (YangIdentityRef) type3.getDataTypeExtendedInfo();
+
+        assertThat(getInCrtLeafType(TYPEDEF, typedef1.getName()),
+                   derInfo1.getEffectiveBuiltInType(), is(IDENTITYREF));
+        assertThat(getInCrtLeafType(TYPEDEF, typedef3.getName()),
+                   idRef.getBaseIdentity().getName(), is(BASE1));
+
+        leafListItr = module.getListOfLeafList().listIterator();
+
+        // Gets the first leaf, which has two typedef with effective id-ref.
+        leafListInfo = leafListItr.next();
+        assertThat(getInCrtName(LEAF_LIST, LEAF_LIST), leafListInfo.getName(),
+                   is(LEAF_LIST));
+        assertThat(getInCrtLeafType(LEAF_LIST, LEAF_LIST),
+                   leafListInfo.getDataType().getDataType(), is(DERIVED));
+
+        // Traverses through the two typedef in it.
+        derInfo1 = (YangDerivedInfo) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        typedef1 = derInfo1.getReferredTypeDef();
+        type1 = typedef1.getTypeList().get(0);
+        derInfo2 = (YangDerivedInfo) type1.getDataTypeExtendedInfo();
+        typedef2 = derInfo2.getReferredTypeDef();
+        type2 = typedef2.getTypeList().get(0);
+        idRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+
+        assertThat(getInCrtLeafType(TYPEDEF, typedef1.getName()),
+                   derInfo1.getEffectiveBuiltInType(), is(IDENTITYREF));
+        assertThat(getInCrtLeafType(TYPEDEF, typedef3.getName()),
+                   idRef.getBaseIdentity().getName(), is(BASE1));
+
+        // Gets the leaf with union having typedef referred from other file.
+        leafInfo = leafItr.next();
+        assertThat(getInCrtName(LEAF, UNI), leafInfo.getName(), is(UNI));
+        assertThat(getInCrtLeafType(LEAF, UNI),
+                   leafInfo.getDataType().getDataType(),
+                   is(YangDataTypes.UNION));
+
+        union = (YangUnion) leafInfo.getDataType().getDataTypeExtendedInfo();
+        type1 = union.getTypeList().get(0);
+        idRef = (YangIdentityRef) type1.getDataTypeExtendedInfo();
+
+        assertThat(getInCrtLeafType(UNION, "first type"),
+                   idRef.getBaseIdentity().getName(), is(BASE1));
+
+        type1 = union.getTypeList().get(1);
+        derInfo1 = (YangDerivedInfo) type1.getDataTypeExtendedInfo();
+        typedef1 = derInfo1.getReferredTypeDef();
+        type2 = typedef1.getTypeList().get(0);
+        idRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+        assertThat(getInCrtLeafType(UNION, "second type"),
+                   idRef.getBaseIdentity().getName(), is("id3"));
+    }
+
+    /**
+     * Processes identity-ref when present in grouping used by inter file uses.
+     *
+     * @throws IOException if violates IO operation
+     */
+    @Test
+    public void processIdentityRefInGrouping() throws IOException {
+
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "idrefingrouping"));
+        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();
+        YangNode rootNode = nodeItr.next();
+
+        if (rootNode.getName().equals("IdRefInGrouping2")) {
+            selfNode = rootNode;
+        } else {
+            selfNode = nodeItr.next();
+        }
+
+        YangModule module = (YangModule) selfNode;
+        YangContainer cont = (YangContainer) module.getChild();
+
+        leafItr = cont.getListOfLeaf().listIterator();
+
+        // Gets the first leaf, which has three typedef with effective id-ref.
+        leafInfo = leafItr.next();
+        assertThat(getInCrtName(LEAF, LEAF), leafInfo.getName(), is(LEAF));
+        assertThat(getInCrtLeafType(LEAF, LEAF),
+                   leafInfo.getDataType().getDataType(), is(IDENTITYREF));
+
+        idRef = (YangIdentityRef) leafInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        assertThat(getInCrtLeafType(LEAF, LEAF),
+                   idRef.getBaseIdentity().getName(), is(BASE1));
+
+        leafListItr = cont.getListOfLeafList().listIterator();
+
+        // Gets the first leaf, which has two typedef with effective id-ref.
+        leafListInfo = leafListItr.next();
+        assertThat(getInCrtName(LEAF_LIST, LEAF_LIST), leafListInfo.getName(),
+                   is(LEAF_LIST));
+        assertThat(getInCrtLeafType(LEAF_LIST, LEAF_LIST),
+                   leafListInfo.getDataType().getDataType(), is(DERIVED));
+
+        // Traverses through the two typedef in it.
+        derInfo1 = (YangDerivedInfo) leafListInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        typedef1 = derInfo1.getReferredTypeDef();
+        type1 = typedef1.getTypeList().get(0);
+        idRef = (YangIdentityRef) type1.getDataTypeExtendedInfo();
+
+        assertThat(getInCrtLeafType(TYPEDEF, typedef1.getName()),
+                   derInfo1.getEffectiveBuiltInType(), is(IDENTITYREF));
+        assertThat(getInCrtLeafType(TYPEDEF, typedef1.getName()),
+                   idRef.getBaseIdentity().getName(), is(BASE2));
+
+        YangContainer cont2 = (YangContainer) cont.getChild().getNextSibling();
+        leafItr = cont2.getListOfLeaf().listIterator();
+        leafInfo = leafItr.next();
+
+        assertThat(getInCrtName(LEAF, LEAF), leafInfo.getName(), is(LEAF));
+        assertThat(getInCrtLeafType(LEAF, LEAF),
+                   leafInfo.getDataType().getDataType(), is(IDENTITYREF));
+        idRef = (YangIdentityRef) leafInfo.getDataType()
+                .getDataTypeExtendedInfo();
+        assertThat(getInCrtLeafType(LEAF, LEAF),
+                   idRef.getBaseIdentity().getName(), is(BASE2));
+    }
 }
diff --git a/plugin/maven/src/test/resources/typelinkingaftercloning/idrefingrouping/idrefingrouping1.yang b/plugin/maven/src/test/resources/typelinkingaftercloning/idrefingrouping/idrefingrouping1.yang
new file mode 100644
index 0000000..8837d49
--- /dev/null
+++ b/plugin/maven/src/test/resources/typelinkingaftercloning/idrefingrouping/idrefingrouping1.yang
@@ -0,0 +1,37 @@
+module IdRefInGrouping1 {
+    namespace "http://org/IdRefInGrouping1";
+    prefix id-ref-in-grouping-1;
+
+    identity id1 {
+        description "base identity";
+    }
+
+    identity id2 {
+        base id1;
+    }
+
+    typedef id {
+        type identityref {
+            base id1;
+        }
+    }
+
+    grouping value {
+        leaf leaf {
+            type identityref {
+                base id2;
+            }
+        }
+        leaf-list leaf-list {
+            type id;
+        }
+        container a {
+            leaf leaf {
+                type identityref {
+                    base id1;
+                }
+            }
+        }
+    }
+
+}
diff --git a/plugin/maven/src/test/resources/typelinkingaftercloning/idrefingrouping/idrefingrouping2.yang b/plugin/maven/src/test/resources/typelinkingaftercloning/idrefingrouping/idrefingrouping2.yang
new file mode 100644
index 0000000..2a347f1
--- /dev/null
+++ b/plugin/maven/src/test/resources/typelinkingaftercloning/idrefingrouping/idrefingrouping2.yang
@@ -0,0 +1,12 @@
+module IdRefInGrouping2 {
+    namespace "http://org/IdRefInGrouping2";
+    prefix id-ref-in-grouping-2;
+
+    import IdRefInGrouping1 {
+        prefix idref1;
+    }
+
+    container content {
+        uses idref1:value;
+    }
+}
diff --git a/plugin/maven/src/test/resources/typelinkingaftercloning/idreftypedef/IdRefInTypeDef1.yang b/plugin/maven/src/test/resources/typelinkingaftercloning/idreftypedef/IdRefInTypeDef1.yang
new file mode 100644
index 0000000..4d2642c
--- /dev/null
+++ b/plugin/maven/src/test/resources/typelinkingaftercloning/idreftypedef/IdRefInTypeDef1.yang
@@ -0,0 +1,57 @@
+module IdRefInTypeDef1 {
+    namespace "http://org/IdRefInTypeDef1";
+    prefix id-ref-in-type-1;
+
+    import IdRefInTypeDef2 {
+        prefix id;
+    }
+
+    identity id1 {
+        description "base identity";
+    }
+
+    identity id2 {
+        base id1;
+    }
+
+    typedef forleaf3 {
+        type identityref {
+            base id2;
+        }
+    }
+
+    typedef forleaf2 {
+        type forleaf3;
+    }
+
+    typedef forleaf1 {
+        type forleaf2;
+    }
+
+    leaf leaf {
+        type forleaf1;
+    }
+
+    leaf-list leaf-list {
+        type forleaf2;
+    }
+
+    container cont {
+        leaf leaf {
+            type forleaf1;
+        }
+
+        leaf leaf-list {
+            type forleaf2;
+        }
+    }
+
+    leaf with-uni {
+        type union {
+            type identityref {
+                base id2;
+            }
+            type id:value;
+        }
+    }
+}
diff --git a/plugin/maven/src/test/resources/typelinkingaftercloning/idreftypedef/IdRefInTypeDef2.yang b/plugin/maven/src/test/resources/typelinkingaftercloning/idreftypedef/IdRefInTypeDef2.yang
new file mode 100644
index 0000000..646a3f6
--- /dev/null
+++ b/plugin/maven/src/test/resources/typelinkingaftercloning/idreftypedef/IdRefInTypeDef2.yang
@@ -0,0 +1,18 @@
+module IdRefInTypeDef2 {
+    namespace "http://org/IdRefInTypeDef2";
+    prefix id-ref-in-type-2;
+
+    identity id4 {
+        description "base identity";
+    }
+
+    identity id3 {
+        base id4;
+    }
+
+    typedef value {
+        type identityref {
+            base id3;
+        }
+    }
+}