[ONOS-7385] Identity extend-list updation to the parent nodes.

Change-Id: Ic30036ff05abb9d3f1eaa35698329d79c8de2645
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangIdentity.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangIdentity.java
index 608c1ea..8890aa4 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangIdentity.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangIdentity.java
@@ -70,6 +70,9 @@
     //YANG reference of the identity.
     private String reference;
 
+    //Status if identity is added to all the parent.
+    private boolean isAddedToAllParent;
+
     /*
      * Identity extend list to contain list of all the direct/indirect derived
      * identities.
@@ -213,4 +216,22 @@
     public void setConflictFlag() {
         nameConflict = true;
     }
+
+    /**
+     * Returns if the identity is added to all the parent nodes.
+     *
+     * @return returns true if added; false otherwise
+     */
+    public boolean isAddedToAllParent() {
+        return isAddedToAllParent;
+    }
+
+    /**
+     * Sets if the identity is added to all the parent nodes.
+     *
+     * @param addedToAllParent sets true if added; false otherwise
+     */
+    public void setAddedToAllParent(boolean addedToAllParent) {
+        isAddedToAllParent = addedToAllParent;
+    }
 }
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java
index ca23010..adc73c1 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java
@@ -16,6 +16,7 @@
 package org.onosproject.yang.compiler.datamodel;
 
 import org.onosproject.yang.compiler.datamodel.exceptions.DataModelException;
+import org.onosproject.yang.compiler.datamodel.utils.IdentityHandler;
 import org.onosproject.yang.compiler.datamodel.utils.Parsable;
 import org.onosproject.yang.compiler.datamodel.utils.YangConstructType;
 import org.onosproject.yang.model.YangNamespace;
@@ -701,6 +702,18 @@
     }
 
     /**
+     * Adds all the derived identities to the base identity.
+     *
+     * @throws DataModelException a violation of data model rules
+     */
+    public void resolveIdentityExtendList() throws DataModelException {
+        for (YangResolutionInfo base : baseResolutionList) {
+           new IdentityHandler((YangBase) base.getEntityToResolveInfo()
+                   .getEntityToResolve());
+        }
+    }
+
+    /**
      * Returns the type of the parsed data.
      *
      * @return returns MODULE_DATA
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangReferenceResolver.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangReferenceResolver.java
index 865b020..9688b2a 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangReferenceResolver.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangReferenceResolver.java
@@ -149,6 +149,13 @@
     void resolveUniqueLinking() throws DataModelException;
 
     /**
+     * Resolves identity extend list.
+     *
+     * @throws DataModelException a violation in data model rule
+     */
+    void resolveIdentityExtendList() throws DataModelException;
+
+    /**
      * Adds references to include.
      *
      * @param yangNodeSet YANG node info set
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java
index bab5092..a4ff0fc 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java
@@ -16,6 +16,7 @@
 package org.onosproject.yang.compiler.datamodel;
 
 import org.onosproject.yang.compiler.datamodel.exceptions.DataModelException;
+import org.onosproject.yang.compiler.datamodel.utils.IdentityHandler;
 import org.onosproject.yang.compiler.datamodel.utils.Parsable;
 import org.onosproject.yang.compiler.datamodel.utils.YangConstructType;
 import org.onosproject.yang.model.YangNamespace;
@@ -965,6 +966,18 @@
         }
     }
 
+    /**
+     * Adds all the derived identities to the base identity.
+     *
+     * @throws DataModelException a violation of data model rules
+     */
+    public void resolveIdentityExtendList() throws DataModelException {
+        for (YangResolutionInfo base : baseResolutionList) {
+            new IdentityHandler((YangBase) base.getEntityToResolveInfo()
+                    .getEntityToResolve());
+        }
+    }
+
     @Override
     public void addToIdentityTypedefMap(String name, YangNode node)
             throws DataModelException {
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/IdentityHandler.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/IdentityHandler.java
new file mode 100644
index 0000000..94c0c26
--- /dev/null
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/IdentityHandler.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.yang.compiler.datamodel.utils;
+
+import org.onosproject.yang.compiler.datamodel.YangBase;
+import org.onosproject.yang.compiler.datamodel.YangIdentity;
+
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * Represents identity extend-list handling.
+ */
+public class IdentityHandler {
+
+    /**
+     * Stack to store the resolvable identities.
+     */
+    private Stack<YangIdentity> stack;
+
+    /**
+     * Creates a new identity handler.
+     *
+     * @param base YANG base
+     */
+    public IdentityHandler(YangBase base) {
+        stack = new Stack<>();
+        YangIdentity id = base.getParentIdentity();
+        if (id.isAddedToAllParent()) {
+            return;
+        }
+        stack.push(id);
+        addToExtendList();
+    }
+
+    /**
+     * Adds to the extend list for all the parent nodes with its complete tree.
+     */
+    public void addToExtendList() {
+        while (!stack.empty()) {
+            YangIdentity baseId = stack.peek();
+            List<YangIdentity> exList = baseId.getExtendList();
+            if (exList != null && !exList.isEmpty()) {
+                for (YangIdentity id : exList) {
+                    if (!id.isAddedToAllParent()) {
+                        stack.push(id);
+                    }
+                }
+            }
+            YangIdentity resolvingId = stack.pop();
+            addToAllParent(resolvingId, resolvingId.getBaseNode().getReferredIdentity());
+        }
+    }
+
+    /**
+     * Adds an identity to all the parent nodes.
+     *
+     * @param referredId referred identity
+     * @param baseId     base identity
+     */
+    private void addToAllParent(YangIdentity referredId, YangIdentity baseId) {
+        YangIdentity baseIdentity = baseId;
+        while (baseIdentity != null) {
+            List<YangIdentity> list = baseIdentity.getExtendList();
+            if (!list.contains(referredId)) {
+                baseIdentity.addToExtendList(referredId);
+            }
+
+            YangBase base = baseIdentity.getBaseNode();
+            baseIdentity = null;
+            if (base != null) {
+                baseIdentity = base.getReferredIdentity();
+            }
+        }
+        referredId.setAddedToAllParent(true);
+    }
+}
diff --git a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerManager.java b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerManager.java
index 743207b..dacc201 100644
--- a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerManager.java
+++ b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerManager.java
@@ -96,6 +96,42 @@
         processInterFileLinking(yangNodeSet);
 
         processUniqueLinking(yangNodeSet);
+
+        processIdentityExtendList(yangNodeSet);
+    }
+
+    /**
+     * Processes the identities and add it to all the parents respectively.
+     *
+     * @param nodeSet set of YANG files info
+     */
+    public void processIdentityExtendList(Set<YangNode> nodeSet) {
+        List<YangNode> list = new LinkedList<>();
+        list.addAll(nodeSet);
+        sort(list);
+        for (YangNode yangNode : list) {
+            try {
+                YangReferenceResolver resolver =
+                        ((YangReferenceResolver) yangNode);
+                resolver.resolveIdentityExtendList();
+            } catch (DataModelException e) {
+                String errorInfo = "Error in file: " + yangNode.getName() +
+                        " in " + yangNode.getFileName() + " at " +
+                        "line: " + e.getLineNumber() + " at position: " +
+                        e.getCharPositionInLine() + NEW_LINE +
+                        e.getLocalizedMessage();
+                throw new LinkerException(errorInfo);
+                // TODO add file path in exception message in util manager.
+            } catch (LinkerException e) {
+                String errorInfo = "Error in file: " + yangNode.getName() +
+                        " in " + yangNode.getFileName() + " at " +
+                        "line: " + e.getLineNumber() + " at position: " +
+                        e.getCharPositionInLine() + NEW_LINE +
+                        e.getLocalizedMessage();
+                throw new LinkerException(errorInfo);
+                // TODO add file path in exception message in util manager.
+            }
+        }
     }
 
     /**
diff --git a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangResolutionInfoImpl.java b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangResolutionInfoImpl.java
index 9e894dc..9d3ae68 100644
--- a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangResolutionInfoImpl.java
+++ b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangResolutionInfoImpl.java
@@ -855,15 +855,7 @@
     private void addToIdentityExtendList(YangIdentity baseIdentity, YangIdentity
             referredIdentity) {
         YangIdentity referredId = referredIdentity;
-        while (referredId != null) {
-            referredId.addToExtendList(baseIdentity);
-            YangBase base = referredId.getBaseNode();
-            if (base == null) {
-                return;
-            } else {
-                referredId = base.getReferredIdentity();
-            }
-        }
+        referredId.addToExtendList(baseIdentity);
     }
 
     /**
diff --git a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/IdentityTranslatorTest.java b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/IdentityTranslatorTest.java
index 789b208..9c2ed6f 100644
--- a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/IdentityTranslatorTest.java
+++ b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/IdentityTranslatorTest.java
@@ -18,7 +18,10 @@
 
 import org.apache.maven.plugin.MojoExecutionException;
 import org.junit.Test;
+import org.onosproject.yang.compiler.datamodel.YangContainer;
 import org.onosproject.yang.compiler.datamodel.YangIdentity;
+import org.onosproject.yang.compiler.datamodel.YangIdentityRef;
+import org.onosproject.yang.compiler.datamodel.YangLeaf;
 import org.onosproject.yang.compiler.datamodel.YangModule;
 import org.onosproject.yang.compiler.datamodel.YangNode;
 import org.onosproject.yang.compiler.linker.impl.YangLinkerManager;
@@ -31,8 +34,12 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Set;
 
+import static java.util.Arrays.asList;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
 import static org.onosproject.yang.compiler.datamodel.YangNodeType.MODULE_NODE;
@@ -47,36 +54,37 @@
  */
 public class IdentityTranslatorTest {
 
-    private final YangLinkerManager yangLinkerManager = new YangLinkerManager();
-    private final YangCompilerManager utilManager =
-            new YangCompilerManager();
     private static final String DIR = "target/identity/";
-    private static final String COMP = System.getProperty("user.dir") + File
-            .separator + DIR;
+    private static final String COMP = System.getProperty("user.dir")
+            + File.separator + DIR;
+    private static final String RSC = "src/test/resources/";
+    private final YangLinkerManager linkMgr = new YangLinkerManager();
+    private final YangCompilerManager util = new YangCompilerManager();
 
     /**
      * Checks translation should not result in any exception.
      *
-     * @throws MojoExecutionException
+     * @throws MojoExecutionException if mojo exception occur
      */
     @Test
     public void processTranslator() throws IOException,
             ParserException, MojoExecutionException {
         deleteDirectory(DIR);
-        String searchDir = "src/test/resources/identityTranslator";
+        String searchDir = RSC + "identityTranslator";
         Set<Path> paths = new HashSet<>();
         for (String file : getYangFiles(searchDir)) {
             paths.add(Paths.get(file));
         }
 
-        utilManager.createYangFileInfoSet(paths);
-        utilManager.parseYangFileInfoSet();
-        utilManager.createYangNodeSet();
-        utilManager.resolveDependenciesUsingLinker();
+        util.createYangFileInfoSet(paths);
+        util.parseYangFileInfoSet();
+        util.createYangNodeSet();
+        util.resolveDependenciesUsingLinker();
 
-        YangPluginConfig yangPluginConfig = new YangPluginConfig();
-        yangPluginConfig.setCodeGenDir(DIR);
-        utilManager.translateToJava(yangPluginConfig);
+        YangPluginConfig config = new YangPluginConfig();
+
+        config.setCodeGenDir(DIR);
+        util.translateToJava(config);
         compileCode(COMP);
         deleteDirectory(DIR);
     }
@@ -84,48 +92,39 @@
     /**
      * Checks translation should not result in any exception.
      *
-     * @throws MojoExecutionException
+     * @throws MojoExecutionException if mojo exception occur
      */
     @Test
     public void processMultipleLevelIdentity() throws IOException,
             ParserException, MojoExecutionException {
         deleteDirectory(DIR);
-        String searchDir = "src/test/resources/multipleIdentity";
+        String searchDir = RSC + "multipleIdentity";
         Set<Path> paths = new HashSet<>();
         for (String file : getYangFiles(searchDir)) {
             paths.add(Paths.get(file));
         }
 
-        utilManager.createYangFileInfoSet(paths);
-        utilManager.parseYangFileInfoSet();
-        utilManager.createYangNodeSet();
+        util.createYangFileInfoSet(paths);
+        util.parseYangFileInfoSet();
+        util.createYangNodeSet();
 
         YangNode selfNode = null;
 
-        // Create YANG node set
-        yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
+        linkMgr.createYangNodeSet(util.getYangNodeSet());
+        linkMgr.addRefToYangFilesImportList(util.getYangNodeSet());
+        updateFilePriority(util.getYangNodeSet());
 
-        // Add references to import list.
-        yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
+        linkMgr.processInterFileLinking(util.getYangNodeSet());
+        linkMgr.processIdentityExtendList(util.getYangNodeSet());
 
-        updateFilePriority(utilManager.getYangNodeSet());
-
-        // Carry out inter-file linking.
-        yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
-
-        for (YangNode rootNode : utilManager.getYangNodeSet()) {
+        for (YangNode rootNode : util.getYangNodeSet()) {
             if (rootNode.getName().equals("test")) {
                 selfNode = rootNode;
             }
         }
 
-        // Check whether the data model tree returned is of type module.
         assertThat(selfNode instanceof YangModule, is(true));
-
-        // Check whether the node type is set properly to module.
         assertThat(selfNode.getNodeType(), is(MODULE_NODE));
-
-        // Check whether the module name is set correctly.
         YangModule yangNode = (YangModule) selfNode;
         assertThat(yangNode.getName(), is("test"));
 
@@ -137,8 +136,404 @@
 
         YangPluginConfig yangPluginConfig = new YangPluginConfig();
         yangPluginConfig.setCodeGenDir(DIR);
-        utilManager.translateToJava(yangPluginConfig);
+        util.translateToJava(yangPluginConfig);
         compileCode(COMP);
         deleteDirectory(DIR);
     }
+
+    /**
+     * Processes the extend list of an identity in self-file linking.
+     *
+     * @throws MojoExecutionException if mojo exception occur
+     */
+    @Test
+    public void processSelfFileIdExtendList1() throws IOException,
+            ParserException, MojoExecutionException {
+        deleteDirectory(DIR);
+        String searchDir = RSC + "identityextend/self/test1";
+        Set<Path> paths = new HashSet<>();
+        for (String file : getYangFiles(searchDir)) {
+            paths.add(Paths.get(file));
+        }
+
+        util.createYangFileInfoSet(paths);
+        util.parseYangFileInfoSet();
+        util.createYangNodeSet();
+
+        YangNode selfNode = null;
+        linkMgr.createYangNodeSet(util.getYangNodeSet());
+        linkMgr.addRefToYangFilesImportList(util.getYangNodeSet());
+        updateFilePriority(util.getYangNodeSet());
+
+        linkMgr.processInterFileLinking(util.getYangNodeSet());
+        linkMgr.processIdentityExtendList(util.getYangNodeSet());
+
+        for (YangNode rootNode : util.getYangNodeSet()) {
+            if (rootNode.getName().equals("self-id1")) {
+                selfNode = rootNode;
+            }
+        }
+
+        YangModule node = (YangModule) selfNode;
+        YangIdentity id3 = (YangIdentity) node.getChild();
+        YangIdentity id8 = (YangIdentity) id3.getNextSibling();
+        YangIdentity id2 = (YangIdentity) id8.getNextSibling();
+        YangIdentity id1 = (YangIdentity) id2.getNextSibling();
+        YangIdentity id4 = (YangIdentity) id1.getNextSibling();
+        YangIdentity id5 = (YangIdentity) id4.getNextSibling();
+        YangIdentity id6 = (YangIdentity) id5.getNextSibling();
+        YangIdentity id7 = (YangIdentity) id6.getNextSibling();
+
+        validateExtendListContent(id3, new LinkedList<>(
+                asList(id4, id5, id6, id7)));
+        validateExtendListContent(id8, new LinkedList<>());
+        validateExtendListContent(id2, new LinkedList<>(
+                asList(id3, id4, id5, id6, id7, id8)));
+        validateExtendListContent(id1, new LinkedList<>(
+                asList(id2, id3, id4, id5, id6, id7, id8)));
+        validateExtendListContent(id4, new LinkedList<>(asList(id5, id6, id7)));
+        validateExtendListContent(id5, new LinkedList<>());
+        validateExtendListContent(id6, new LinkedList<>(asList(id7)));
+        validateExtendListContent(id7, new LinkedList<>());
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(DIR);
+        util.translateToJava(yangPluginConfig);
+        compileCode(COMP);
+        deleteDirectory(DIR);
+    }
+
+    /**
+     * Processes the extend list of an identity in self-file linking.
+     *
+     * @throws MojoExecutionException if mojo exception occur
+     */
+    @Test
+    public void processSelfFileIdExtendList2() throws IOException,
+            ParserException, MojoExecutionException {
+        deleteDirectory(DIR);
+        String searchDir = RSC + "identityextend/self/test2";
+        Set<Path> paths = new HashSet<>();
+        for (String file : getYangFiles(searchDir)) {
+            paths.add(Paths.get(file));
+        }
+
+        util.createYangFileInfoSet(paths);
+        util.parseYangFileInfoSet();
+        util.createYangNodeSet();
+
+        YangNode selfNode = null;
+        linkMgr.createYangNodeSet(util.getYangNodeSet());
+        linkMgr.addRefToYangFilesImportList(util.getYangNodeSet());
+        updateFilePriority(util.getYangNodeSet());
+
+        linkMgr.processInterFileLinking(util.getYangNodeSet());
+        linkMgr.processIdentityExtendList(util.getYangNodeSet());
+
+        for (YangNode rootNode : util.getYangNodeSet()) {
+            if (rootNode.getName().equals("self-id2")) {
+                selfNode = rootNode;
+            }
+        }
+
+        YangModule node = (YangModule) selfNode;
+        YangIdentity id1 = (YangIdentity) node.getChild();
+        YangIdentity id2 = (YangIdentity) id1.getNextSibling();
+        YangIdentity id5 = (YangIdentity) id2.getNextSibling();
+        YangIdentity id3 = (YangIdentity) id5.getNextSibling();
+        YangIdentity id6 = (YangIdentity) id3.getNextSibling();
+        YangIdentity id7 = (YangIdentity) id6.getNextSibling();
+        YangIdentity id8 = (YangIdentity) id7.getNextSibling();
+        YangIdentity id4 = (YangIdentity) id8.getNextSibling();
+        YangIdentity id9 = (YangIdentity) id4.getNextSibling();
+
+        validateExtendListContent(id1, new LinkedList<>(
+                asList(id2, id3, id4, id5, id6, id7, id8, id9)));
+        validateExtendListContent(id2, new LinkedList<>(
+                asList(id3, id4, id6, id9)));
+        validateExtendListContent(id5, new LinkedList<>(asList(id7, id8)));
+        validateExtendListContent(id3, new LinkedList<>(asList(id4, id9)));
+        validateExtendListContent(id6, new LinkedList<>());
+        validateExtendListContent(id7, new LinkedList<>());
+        validateExtendListContent(id8, new LinkedList<>());
+        validateExtendListContent(id4, new LinkedList<>());
+        validateExtendListContent(id9, new LinkedList<>());
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(DIR);
+        util.translateToJava(yangPluginConfig);
+        compileCode(COMP);
+        deleteDirectory(DIR);
+    }
+
+    /**
+     * Processes the extend list of an identity in inter-file linking.
+     *
+     * @throws MojoExecutionException if mojo exception occur
+     */
+    @Test
+    public void processInterFileIdExtendList1() throws IOException,
+            ParserException, MojoExecutionException {
+        deleteDirectory(DIR);
+        String searchDir = RSC + "identityextend/inter/test1";
+        Set<Path> paths = new HashSet<>();
+        for (String file : getYangFiles(searchDir)) {
+            paths.add(Paths.get(file));
+        }
+
+        util.createYangFileInfoSet(paths);
+        util.parseYangFileInfoSet();
+        util.createYangNodeSet();
+
+        YangNode selfNode = null;
+        linkMgr.createYangNodeSet(util.getYangNodeSet());
+        linkMgr.addRefToYangFilesImportList(util.getYangNodeSet());
+        updateFilePriority(util.getYangNodeSet());
+
+        linkMgr.processInterFileLinking(util.getYangNodeSet());
+        linkMgr.processIdentityExtendList(util.getYangNodeSet());
+        YangNode refNode1 = null;
+        YangNode refNode2 = null;
+
+        for (YangNode rootNode : util.getYangNodeSet()) {
+            if (rootNode.getName().equals("file-test1-a")) {
+                selfNode = rootNode;
+            } else if (rootNode.getName().equals("file-test1-b")) {
+                refNode1 = rootNode;
+            } else {
+                refNode2 = rootNode;
+            }
+        }
+
+        YangModule node = (YangModule) selfNode;
+        YangIdentity id1 = (YangIdentity) node.getChild();
+        YangIdentity id2 = (YangIdentity) id1.getNextSibling();
+        YangIdentity id3 = (YangIdentity) id2.getNextSibling();
+
+        YangModule nodeb = (YangModule) refNode1;
+        YangIdentity id4 = (YangIdentity) nodeb.getChild();
+        YangIdentity id5 = (YangIdentity) id4.getNextSibling();
+        YangIdentity id6 = (YangIdentity) id5.getNextSibling();
+        YangIdentity id7 = (YangIdentity) id6.getNextSibling();
+
+        YangModule nodec = (YangModule) refNode2;
+        YangIdentity id8 = (YangIdentity) nodec.getChild();
+        YangIdentity id9 = (YangIdentity) id8.getNextSibling();
+        YangIdentity id10 = (YangIdentity) id9.getNextSibling();
+        YangIdentity id11 = (YangIdentity) id10.getNextSibling();
+
+        validateExtendListContent(id1, new LinkedList<>(asList(
+                id2, id3, id4, id5, id6, id7, id8, id9, id10, id11)));
+        validateExtendListContent(id2, new LinkedList<>(
+                asList(id4, id5, id10, id11)));
+        validateExtendListContent(id3, new LinkedList<>());
+        validateExtendListContent(id4, new LinkedList<>(asList(id10, id11)));
+        validateExtendListContent(id5, new LinkedList<>());
+        validateExtendListContent(id6, new LinkedList<>());
+        validateExtendListContent(id7, new LinkedList<>());
+        validateExtendListContent(id8, new LinkedList<>());
+        validateExtendListContent(id9, new LinkedList<>());
+        validateExtendListContent(id10, new LinkedList<>());
+        validateExtendListContent(id11, new LinkedList<>());
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(DIR);
+        util.translateToJava(yangPluginConfig);
+        compileCode(COMP);
+        deleteDirectory(DIR);
+    }
+
+    /**
+     * Processes the extend list of an identity in inter-file linking.
+     *
+     * @throws MojoExecutionException if mojo exception occur
+     */
+    @Test
+    public void processInterFileIdExtendList2() throws IOException,
+            ParserException, MojoExecutionException {
+        deleteDirectory(DIR);
+        String searchDir = RSC + "identityextend/inter/test2";
+        Set<Path> paths = new HashSet<>();
+        for (String file : getYangFiles(searchDir)) {
+            paths.add(Paths.get(file));
+        }
+
+        util.createYangFileInfoSet(paths);
+        util.parseYangFileInfoSet();
+        util.createYangNodeSet();
+
+        YangNode selfNode = null;
+        linkMgr.createYangNodeSet(util.getYangNodeSet());
+        linkMgr.addRefToYangFilesImportList(util.getYangNodeSet());
+        updateFilePriority(util.getYangNodeSet());
+
+        linkMgr.processInterFileLinking(util.getYangNodeSet());
+        linkMgr.processIdentityExtendList(util.getYangNodeSet());
+        YangNode refNode1 = null;
+        YangNode refNode2 = null;
+
+        for (YangNode rootNode : util.getYangNodeSet()) {
+            if (rootNode.getName().equals("file-test2-a")) {
+                selfNode = rootNode;
+            } else if (rootNode.getName().equals("file-test2-b")) {
+                refNode1 = rootNode;
+            } else {
+                refNode2 = rootNode;
+            }
+        }
+
+        YangModule node = (YangModule) selfNode;
+        YangIdentity id2 = (YangIdentity) node.getChild();
+        YangIdentity id3 = (YangIdentity) id2.getNextSibling();
+        YangIdentity id4 = (YangIdentity) id3.getNextSibling();
+
+        YangModule nodeb = (YangModule) refNode1;
+        YangIdentity id1 = (YangIdentity) nodeb.getChild();
+        YangIdentity id5 = (YangIdentity) id1.getNextSibling();
+        YangIdentity id6 = (YangIdentity) id5.getNextSibling();
+
+        YangModule nodec = (YangModule) refNode2;
+        YangIdentity id7 = (YangIdentity) nodec.getChild();
+        YangIdentity id8 = (YangIdentity) id7.getNextSibling();
+        YangIdentity id9 = (YangIdentity) id8.getNextSibling();
+        YangIdentity id10 = (YangIdentity) id9.getNextSibling();
+        YangIdentity id11 = (YangIdentity) id10.getNextSibling();
+        YangIdentity id12 = (YangIdentity) id11.getNextSibling();
+        YangIdentity id13 = (YangIdentity) id12.getNextSibling();
+        YangIdentity id14 = (YangIdentity) id13.getNextSibling();
+        YangIdentity id15 = (YangIdentity) id14.getNextSibling();
+        YangIdentity id16 = (YangIdentity) id15.getNextSibling();
+        YangIdentity id17 = (YangIdentity) id16.getNextSibling();
+        YangIdentity id18 = (YangIdentity) id17.getNextSibling();
+
+        validateExtendListContent(id1, new LinkedList<>(asList(
+                id2, id3, id4, id5, id6, id7, id8, id9, id10, id11, id12,
+                id13, id14, id15, id16, id17, id18)));
+        validateExtendListContent(id2, new LinkedList<>(asList(id3, id4)));
+        validateExtendListContent(id3, new LinkedList<>());
+        validateExtendListContent(id4, new LinkedList<>());
+        validateExtendListContent(id5, new LinkedList<>());
+        validateExtendListContent(id6, new LinkedList<>(asList(
+                id7, id8, id9, id10, id11, id12, id13, id14, id15, id16, id17,
+                id18)));
+        validateExtendListContent(id7, new LinkedList<>(asList(
+                id11, id15, id16, id17, id18)));
+        validateExtendListContent(id8, new LinkedList<>(asList(id12)));
+        validateExtendListContent(id9, new LinkedList<>(asList(id13)));
+        validateExtendListContent(id10, new LinkedList<>(asList(id14)));
+        validateExtendListContent(id11, new LinkedList<>(asList(
+                id15, id16, id17, id18)));
+        validateExtendListContent(id12, new LinkedList<>());
+        validateExtendListContent(id13, new LinkedList<>());
+        validateExtendListContent(id14, new LinkedList<>());
+        validateExtendListContent(id15, new LinkedList<>());
+        validateExtendListContent(id16, new LinkedList<>());
+        validateExtendListContent(id17, new LinkedList<>());
+        validateExtendListContent(id18, new LinkedList<>());
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(DIR);
+        util.translateToJava(yangPluginConfig);
+        compileCode(COMP);
+        deleteDirectory(DIR);
+    }
+
+    /**
+     * Processes the extend list of an identity in inter-file linking.
+     *
+     * @throws MojoExecutionException if mojo exception occur
+     */
+    @Test
+    public void processInterFileIdExtendListIssue() throws IOException,
+            ParserException, MojoExecutionException {
+        deleteDirectory(DIR);
+        String searchDir = RSC + "identityextend/inter/issue";
+        Set<Path> paths = new HashSet<>();
+        for (String file : getYangFiles(searchDir)) {
+            paths.add(Paths.get(file));
+        }
+
+        util.createYangFileInfoSet(paths);
+        util.parseYangFileInfoSet();
+        util.createYangNodeSet();
+
+        YangNode selfNode = null;
+        linkMgr.createYangNodeSet(util.getYangNodeSet());
+        linkMgr.addRefToYangFilesImportList(util.getYangNodeSet());
+        updateFilePriority(util.getYangNodeSet());
+
+        linkMgr.processInterFileLinking(util.getYangNodeSet());
+        linkMgr.processIdentityExtendList(util.getYangNodeSet());
+        YangNode refNode2 = null;
+
+        for (YangNode rootNode : util.getYangNodeSet()) {
+            if (rootNode.getName().equals("filea")) {
+                selfNode = rootNode;
+            } else if (rootNode.getName().equals("filec")) {
+                refNode2 = rootNode;
+            }
+        }
+
+        YangModule node = (YangModule) selfNode;
+        YangContainer container = (YangContainer) node.getChild();
+        Iterator<YangLeaf> it = container.getListOfLeaf().iterator();
+        YangLeaf leaf = it.next();
+        YangIdentityRef ref = (YangIdentityRef) leaf.getDataType()
+                .getDataTypeExtendedInfo();
+
+        YangIdentity intType = ref.getReferredIdentity();
+
+        YangModule nodec = (YangModule) refNode2;
+        YangIdentity jaT = (YangIdentity) nodec.getChild();
+        YangIdentity gtp = (YangIdentity) jaT.getNextSibling();
+        YangIdentity pdnLoop1 = (YangIdentity) gtp.getNextSibling();
+        YangIdentity pdnLoop2 = (YangIdentity) pdnLoop1.getNextSibling();
+        YangIdentity opChGr = (YangIdentity) pdnLoop2.getNextSibling();
+        YangIdentity home = (YangIdentity) opChGr.getNextSibling();
+
+        validateExtendListContent(intType, new LinkedList<>(asList(
+                jaT, gtp, pdnLoop1, pdnLoop2, opChGr, home)));
+        validateExtendListContent(jaT, new LinkedList<>(asList(
+                gtp, pdnLoop1, pdnLoop2, opChGr, home)));
+        validateExtendListContent(gtp, new LinkedList<>());
+        validateExtendListContent(pdnLoop1, new LinkedList<>());
+        validateExtendListContent(pdnLoop2, new LinkedList<>());
+        validateExtendListContent(opChGr, new LinkedList<>());
+        validateExtendListContent(home, new LinkedList<>());
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(DIR);
+        util.translateToJava(yangPluginConfig);
+        compileCode(COMP);
+        deleteDirectory(DIR);
+    }
+
+    /**
+     * Validates the extend list content in an identity.
+     *
+     * @param id     YANG identity
+     * @param idList extend list to validate
+     */
+    private void validateExtendListContent(YangIdentity id,
+                                           List<YangIdentity> idList) {
+        List<YangIdentity> list = id.getExtendList();
+        assertThat(list.size(), is(idList.size()));
+        if (!idList.isEmpty()) {
+            for (YangIdentity ext : idList) {
+                assertThat(getErrMsg(ext, id), list.contains(ext), is(true));
+            }
+        }
+    }
+
+    /**
+     * Returns the error message for extend-list failure.
+     *
+     * @param ext extend list identity
+     * @param id  holder identity
+     * @return error message
+     */
+    private String getErrMsg(YangIdentity ext, YangIdentity id) {
+        return "Identity " + ext.getName() + " does not exist in the extend-" +
+                "list of " + id.getName();
+    }
 }
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/inter/issue/filea.yang b/compiler/plugin/maven/src/test/resources/identityextend/inter/issue/filea.yang
new file mode 100644
index 0000000..e69c86c
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/inter/issue/filea.yang
@@ -0,0 +1,23 @@
+module filea {
+    yang-version 1;
+    namespace
+      "http://netconfcentral.org/ns/file/a";
+    prefix fa;
+
+    import fileb {
+        prefix f2;
+    }
+
+    revision "2009-11-20" {
+      description
+        "sample module in progress.";
+    }
+
+    container cc1 {
+        leaf type  {
+            type identityref {
+                base f2:int-type;
+            }
+        }
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/inter/issue/fileb.yang b/compiler/plugin/maven/src/test/resources/identityextend/inter/issue/fileb.yang
new file mode 100644
index 0000000..cd45428
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/inter/issue/fileb.yang
@@ -0,0 +1,17 @@
+module fileb {
+    yang-version 1;
+    namespace
+      "http://netconfcentral.org/ns/file/b";
+    prefix fb;
+
+    revision "2009-11-20" {
+      description
+        "sample module in progress.";
+    }
+
+    identity int-type {
+    	description
+        "Base identity from which specific interface types are
+        derived.";
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/inter/issue/filec.yang b/compiler/plugin/maven/src/test/resources/identityextend/inter/issue/filec.yang
new file mode 100644
index 0000000..1c51fa1
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/inter/issue/filec.yang
@@ -0,0 +1,39 @@
+module filec {
+    yang-version 1;
+    namespace
+      "http://netconfcentral.org/ns/file/c";
+    prefix fc;
+
+    import fileb {
+        prefix f2;
+    }
+
+    revision "2009-11-20" {
+      description
+        "sample module in progress.";
+    }
+
+    identity ja-t {
+        base f2:int-type;
+    }
+
+    identity gtp {
+        base ja-t;
+    }
+
+    identity pdnEtherLoop1 {
+        base ja-t;
+    }
+
+    identity pdnEtherLoop2 {
+        base ja-t;
+    }
+
+    identity opticalChannelGroup {
+        base ja-t;
+    }
+
+    identity homepna {
+        base ja-t;
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/inter/test1/file-test1-a.yang b/compiler/plugin/maven/src/test/resources/identityextend/inter/test1/file-test1-a.yang
new file mode 100644
index 0000000..d1ba8c2
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/inter/test1/file-test1-a.yang
@@ -0,0 +1,21 @@
+module file-test1-a {
+    yang-version 1;
+    namespace
+      "http://test1.org/ns/file/a";
+    prefix t1fa;
+
+    revision "2009-11-21" {
+      description
+        "sample module in progress.";
+    }
+
+    identity id1;
+
+    identity id2 {
+       base "id1";
+    }
+
+    identity id3 {
+       base "id1";
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/inter/test1/file-test1-b.yang b/compiler/plugin/maven/src/test/resources/identityextend/inter/test1/file-test1-b.yang
new file mode 100644
index 0000000..31e085e
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/inter/test1/file-test1-b.yang
@@ -0,0 +1,31 @@
+module file-test1-b {
+    yang-version 1;
+    namespace
+      "http://test1.org/ns/file/b";
+    prefix t1fb;
+
+    import file-test1-a {
+        prefix t1fa;
+    }
+
+    revision "2009-11-21" {
+      description
+        "sample module in progress.";
+    }
+
+    identity id4 {
+       base t1fa:id2;
+    }
+
+    identity id5 {
+       base t1fa:id2;
+    }
+
+    identity id6 {
+       base t1fa:id1;
+    }
+
+    identity id7 {
+       base t1fa:id1;
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/inter/test1/file-test1-c.yang b/compiler/plugin/maven/src/test/resources/identityextend/inter/test1/file-test1-c.yang
new file mode 100644
index 0000000..74e31a6
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/inter/test1/file-test1-c.yang
@@ -0,0 +1,35 @@
+module file-test1-c {
+    yang-version 1;
+    namespace
+      "http://test1.org/ns/file/c";
+    prefix t1fc;
+
+    import file-test1-a {
+        prefix t1fa;
+    }
+
+    import file-test1-b {
+        prefix t1fb;
+    }
+
+    revision "2009-11-21" {
+      description
+        "sample module in progress.";
+    }
+
+    identity id8 {
+       base t1fa:id1;
+    }
+
+    identity id9 {
+       base t1fa:id1;
+    }
+
+    identity id10 {
+       base t1fb:id4;
+    }
+
+    identity id11 {
+       base t1fb:id4;
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/inter/test2/file-test2-a.yang b/compiler/plugin/maven/src/test/resources/identityextend/inter/test2/file-test2-a.yang
new file mode 100644
index 0000000..5ffa0d3
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/inter/test2/file-test2-a.yang
@@ -0,0 +1,27 @@
+module file-test2-a {
+    yang-version 1;
+    namespace
+      "http://test2.org/ns/file/a";
+    prefix t2fa;
+
+    import file-test2-b {
+        prefix t2fb;
+    }
+
+    revision "2009-11-21" {
+      description
+        "sample module in progress.";
+    }
+
+    identity id2 {
+       base "t2fb:id1";
+    }
+
+    identity id3 {
+       base "id2";
+    }
+
+    identity id4 {
+       base "id2";
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/inter/test2/file-test2-b.yang b/compiler/plugin/maven/src/test/resources/identityextend/inter/test2/file-test2-b.yang
new file mode 100644
index 0000000..3f17e24
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/inter/test2/file-test2-b.yang
@@ -0,0 +1,21 @@
+module file-test2-b {
+    yang-version 1;
+    namespace
+      "http://test2.org/ns/file/b";
+    prefix t2fb;
+
+    revision "2009-11-21" {
+      description
+        "sample module in progress.";
+    }
+
+    identity id1;
+
+    identity id5 {
+       base id1;
+    }
+
+    identity id6 {
+       base id1;
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/inter/test2/file-test2-c.yang b/compiler/plugin/maven/src/test/resources/identityextend/inter/test2/file-test2-c.yang
new file mode 100644
index 0000000..616d5e3
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/inter/test2/file-test2-c.yang
@@ -0,0 +1,63 @@
+module file-test2-c {
+    yang-version 1;
+    namespace
+      "http://test2.org/ns/file/c";
+    prefix t2fc;
+
+    import file-test2-b {
+        prefix t2fb;
+    }
+
+    revision "2009-11-21" {
+      description
+        "sample module in progress.";
+    }
+
+    identity id7 {
+       base t2fb:id6;
+    }
+
+    identity id8 {
+       base t2fb:id6;
+    }
+
+    identity id9 {
+       base t2fb:id6;
+    }
+
+    identity id10 {
+       base t2fb:id6;
+    }
+
+    identity id11 {
+       base id7;
+    }
+
+    identity id12 {
+       base id8;
+    }
+
+    identity id13 {
+       base id9;
+    }
+
+    identity id14 {
+       base id10;
+    }
+
+    identity id15 {
+       base id11;
+    }
+
+    identity id16 {
+       base id11;
+    }
+
+    identity id17 {
+       base id11;
+    }
+
+    identity id18 {
+       base id11;
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/self/test1/self-id1.yang b/compiler/plugin/maven/src/test/resources/identityextend/self/test1/self-id1.yang
new file mode 100644
index 0000000..82dd7b7
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/self/test1/self-id1.yang
@@ -0,0 +1,37 @@
+module self-id1 {
+
+    namespace "self-id1";
+
+    prefix self-id1;
+
+    identity id3 {
+       base "id2";
+    }
+
+    identity id8 {
+       base "id2";
+    }
+
+    identity id2 {
+        base "id1";
+    }
+
+    identity id1;
+
+    identity id4 {
+       base "id3";
+    }
+
+    identity id5 {
+       base "id4";
+    }
+
+    identity id6 {
+       base "id4";
+    }
+
+    identity id7 {
+       base "id6";
+    }
+
+}
\ No newline at end of file
diff --git a/compiler/plugin/maven/src/test/resources/identityextend/self/test2/self-id2.yang b/compiler/plugin/maven/src/test/resources/identityextend/self/test2/self-id2.yang
new file mode 100644
index 0000000..50a9d30
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/identityextend/self/test2/self-id2.yang
@@ -0,0 +1,41 @@
+module self-id2 {
+
+    namespace "self-id2";
+
+    prefix self-id2;
+
+    identity id1;
+
+    identity id2 {
+        base "id1";
+    }
+
+    identity id5 {
+       base "id1";
+    }
+
+    identity id3 {
+       base "id2";
+    }
+
+    identity id6 {
+       base "id2";
+    }
+
+    identity id7 {
+       base "id5";
+    }
+
+    identity id8 {
+       base "id5";
+    }
+
+    identity id4 {
+       base "id3";
+    }
+
+    identity id9 {
+       base "id3";
+    }
+
+}
\ No newline at end of file