[ONOS-6694] Multi augment with same name.

Change-Id: Ib319944816679c5c9a703ff771bdfbd0d6af67ab
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java
index 934a869..c7a2422 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java
@@ -158,6 +158,11 @@
     private String setterMethodName;
 
     /**
+     * Logical node of YANG augment.
+     */
+    private YangAugment logicalNode;
+
+    /**
      * Create a YANG augment node.
      */
     public YangAugment() {
@@ -569,4 +574,22 @@
     public void setSetterMethodName(String name) {
         setterMethodName = name;
     }
+
+    /**
+     * Returns the logical YANG augment node.
+     *
+     * @return logical YANG augment
+     */
+    public YangAugment getLogicalNode() {
+        return logicalNode;
+    }
+
+    /**
+     * Sets the logical YANG augment node.
+     *
+     * @param logicalNode logical YANG augment
+     */
+    public void setLogicalNode(YangAugment logicalNode) {
+        this.logicalNode = logicalNode;
+    }
 }
diff --git a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java
index 4f77d69..dbe46a8 100644
--- a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java
+++ b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.yang.compiler.parser.impl.listeners;
 
+import org.antlr.v4.runtime.Token;
 import org.onosproject.yang.compiler.datamodel.YangAtomicPath;
 import org.onosproject.yang.compiler.datamodel.YangAugment;
 import org.onosproject.yang.compiler.datamodel.YangModule;
@@ -49,9 +50,12 @@
 import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
 import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
 import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.checkAugNameCollision;
 import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.getPrefixRemovedName;
 import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.getValidAbsoluteSchemaNodeId;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.isDuplicateNode;
 import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.parseUsesAugment;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.removeAugment;
 import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
 import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
 import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerValidation.validateCardinalityEitherOne;
@@ -141,6 +145,7 @@
         augment.setName(removeQuotesAndHandleConcat(ctx.augment().getText()));
         augment.setPrefixRemovedName(name);
 
+        checkAugNameCollision(root, augment);
         try {
             root.addChild(augment);
         } catch (DataModelException e) {
@@ -149,11 +154,6 @@
                     ctx.augment().getText(), ENTRY, e.getMessage()));
         }
         listener.getParsedDataStack().push(augment);
-
-        // Adds resolution info to the list
-        YangResolutionInfoImpl<YangAugment> info =
-                new YangResolutionInfoImpl<>(augment, root, line, pos);
-        addToResolution(info, ctx);
     }
 
     /**
@@ -175,7 +175,19 @@
                     MISSING_CURRENT_HOLDER, AUGMENT_DATA,
                     ctx.augment().getText(), EXIT));
         }
-        listener.getParsedDataStack().pop();
+        YangAugment augment = (YangAugment) listener.getParsedDataStack().pop();
+
+        boolean isDup = isDuplicateNode(augment);
+        if (isDup) {
+            removeAugment(augment);
+        } else {
+            Token txt = ctx.getStart();
+            YangResolutionInfoImpl<YangAugment> info =
+                    new YangResolutionInfoImpl<>(augment, augment.getParent(),
+                                                 txt.getLine(),
+                                                 txt.getCharPositionInLine());
+            addToResolution(info, ctx);
+        }
     }
 
     /**
diff --git a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java
index aaadaf2..25ec87b 100644
--- a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java
+++ b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java
@@ -18,7 +18,10 @@
 
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.onosproject.yang.compiler.datamodel.YangAtomicPath;
+import org.onosproject.yang.compiler.datamodel.YangAugment;
 import org.onosproject.yang.compiler.datamodel.YangImport;
+import org.onosproject.yang.compiler.datamodel.YangLeaf;
+import org.onosproject.yang.compiler.datamodel.YangLeafList;
 import org.onosproject.yang.compiler.datamodel.YangLeafRef;
 import org.onosproject.yang.compiler.datamodel.YangModule;
 import org.onosproject.yang.compiler.datamodel.YangNode;
@@ -29,9 +32,11 @@
 import org.onosproject.yang.compiler.datamodel.YangRelativePath;
 import org.onosproject.yang.compiler.datamodel.YangSubModule;
 import org.onosproject.yang.compiler.datamodel.YangUniqueHolder;
+import org.onosproject.yang.compiler.datamodel.exceptions.DataModelException;
 import org.onosproject.yang.compiler.datamodel.utils.YangConstructType;
 import org.onosproject.yang.compiler.parser.antlrgencode.GeneratedYangParser.AugmentStatementContext;
 import org.onosproject.yang.compiler.parser.exceptions.ParserException;
+import org.onosproject.yang.compiler.translator.tojava.javamodel.YangJavaAugmentTranslator;
 import org.slf4j.Logger;
 
 import java.text.ParseException;
@@ -51,6 +56,9 @@
 import static org.onosproject.yang.compiler.datamodel.utils.YangConstructType.getYangConstructType;
 import static org.onosproject.yang.compiler.parser.antlrgencode.GeneratedYangParser.PathStatementContext;
 import static org.onosproject.yang.compiler.parser.antlrgencode.GeneratedYangParser.YangVersionStatementContext;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
 import static org.onosproject.yang.compiler.utils.UtilConstants.ADD;
 import static org.onosproject.yang.compiler.utils.UtilConstants.ANCESTOR;
 import static org.onosproject.yang.compiler.utils.UtilConstants.AT;
@@ -1030,4 +1038,145 @@
         }
         return builder.toString();
     }
+
+    /**
+     * Checks if the augment node is a duplicate node. If the augment is
+     * duplicate, then it adds all its children to the logical node.
+     *
+     * @param augment YANG augment
+     * @return true if it is a duplicate node; false otherwise
+     */
+    public static boolean isDuplicateNode(YangAugment augment) {
+        YangAugment logical = augment.getLogicalNode();
+        if (logical == null) {
+            return false;
+        }
+        YangNode lastChild = logical;
+
+        YangNode child = logical.getChild();
+        while (child != null) {
+            lastChild = child;
+            child = child.getNextSibling();
+        }
+        addChildToLogicalNode(logical, augment, lastChild);
+        addLeafAndLeafList(logical, augment);
+        return true;
+    }
+
+    /**
+     * Adds the child and its sibling in duplicate augment to the logical
+     * augment node.
+     *
+     * @param logical   logical augment node
+     * @param augment   YANG augment
+     * @param lastChild logical node's last node
+     */
+    private static void addChildToLogicalNode(YangAugment logical,
+                                              YangAugment augment,
+                                              YangNode lastChild) {
+        YangNode augChild = augment.getChild();
+        while (augChild != null) {
+            if (lastChild == logical) {
+                augChild.setParent(lastChild);
+                try {
+                    lastChild.addChild(augChild);
+                } catch (DataModelException e) {
+                    throw new ParserException(
+                            constructExtendedListenerErrorMessage(
+                                    UNHANDLED_PARSED_DATA, AUGMENT_DATA,
+                                    augment.getName(), ENTRY, e.getMessage()));
+                }
+            } else {
+                augChild.setParent(lastChild.getParent());
+                augChild.setPreviousSibling(lastChild);
+                lastChild.setNextSibling(augChild);
+            }
+            lastChild = augChild;
+            augChild = augChild.getNextSibling();
+        }
+    }
+
+    /**
+     * Adds leaf and leaf-list from the YANG augment to the logical augment
+     * node.
+     *
+     * @param logical logical YANG augment
+     * @param augment duplicate YANG augment
+     */
+    private static void addLeafAndLeafList(YangAugment logical,
+                                           YangAugment augment) {
+
+        List<YangLeaf> logLeaves = logical.getListOfLeaf();
+        List<YangLeafList> logLl = logical.getListOfLeafList();
+        List<YangLeaf> augLeaves = augment.getListOfLeaf();
+        List<YangLeafList> augLl = augment.getListOfLeafList();
+
+        if (augLeaves != null && !augLeaves.isEmpty()) {
+            for (YangLeaf leaf : augLeaves) {
+                leaf.setContainedIn(logical);
+                if (logLeaves == null) {
+                    logLeaves = new LinkedList<>();
+                }
+                logLeaves.add(leaf);
+            }
+        }
+        if (augLl != null && !augLl.isEmpty()) {
+            for (YangLeafList ll : augLl) {
+                ll.setContainedIn(logical);
+                if (logLl == null) {
+                    logLl = new LinkedList<>();
+                }
+                logLl.add(ll);
+            }
+        }
+    }
+
+    /**
+     * Checks for the augment name name collision. If there are augments with
+     * the same name present, then the new augment will be set with a logical
+     * node.
+     *
+     * @param root augment parent node
+     * @param aug  YANG augment node
+     */
+    public static void checkAugNameCollision(YangNode root, YangAugment aug) {
+        YangNode child = root.getChild();
+        while (child != null) {
+            if (child instanceof YangAugment) {
+                if (child.getName().equals(aug.getName())) {
+                    aug.setLogicalNode((YangAugment) child);
+                }
+            }
+            child = child.getNextSibling();
+        }
+    }
+
+    /**
+     * Removes the duplicate YANG augment from the data tree by detaching it
+     * from its parent and from its sibling.
+     *
+     * @param augment duplicate YANG augment
+     */
+    public static void removeAugment(YangAugment augment) {
+        YangNode root = augment.getParent();
+        YangNode child = root.getChild();
+        YangNode pSib = null;
+        if (child == null) {
+            throw new ParserException("The root node of augment " + augment
+                    .getName() + " must have atleast one child");
+        }
+        while (child != null) {
+            if (child == augment) {
+                if (pSib == null) {
+                    root.setChild(null);
+                } else {
+                    pSib.setNextSibling(null);
+                }
+            }
+            pSib = child;
+            child = child.getNextSibling();
+        }
+        augment = new YangJavaAugmentTranslator();
+        augment = null;
+    }
 }
diff --git a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java
index 156194e..97e2a86 100644
--- a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java
+++ b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java
@@ -435,4 +435,67 @@
         YangPluginConfig.compileCode(COMP);
         deleteDirectory(DIR);
     }
+
+    /**
+     * Checks multiple augment handling which has the same name for open
+     * config YANG files.
+     *
+     * @throws IOException            if any error occurs during IO on files
+     * @throws ParserException        if any error occurs during parsing
+     * @throws MojoExecutionException if any mojo operation fails
+     */
+    @Test
+    public void processOpenConfigAugment() throws IOException,
+            ParserException, MojoExecutionException {
+
+        deleteDirectory(DIR);
+        String dir = "src/test/resources/augwithsamename/oc/";
+
+        Set<Path> paths = new HashSet<>();
+        for (String file : getYangFiles(dir)) {
+            paths.add(Paths.get(file));
+        }
+
+        utilManager.createYangFileInfoSet(paths);
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+        utilManager.resolveDependenciesUsingLinker();
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(DIR);
+        utilManager.translateToJava(yangPluginConfig);
+        YangPluginConfig.compileCode(COMP);
+        deleteDirectory(DIR);
+    }
+
+    /**
+     * Checks multiple augment handling which has the same name.
+     *
+     * @throws IOException            if any error occurs during IO on files
+     * @throws ParserException        if any error occurs during parsing
+     * @throws MojoExecutionException if any mojo operation fail
+     */
+    @Test
+    public void processSameAugName() throws IOException,
+            ParserException, MojoExecutionException {
+
+        deleteDirectory(DIR);
+        String dir = "src/test/resources/augwithsamename/multiaugwithsamename/";
+
+        Set<Path> paths = new HashSet<>();
+        for (String file : getYangFiles(dir)) {
+            paths.add(Paths.get(file));
+        }
+
+        utilManager.createYangFileInfoSet(paths);
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+        utilManager.resolveDependenciesUsingLinker();
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(DIR);
+        utilManager.translateToJava(yangPluginConfig);
+        YangPluginConfig.compileCode(COMP);
+        deleteDirectory(DIR);
+    }
 }
diff --git a/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module1.yang b/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module1.yang
new file mode 100644
index 0000000..fedf735
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module1.yang
@@ -0,0 +1,14 @@
+module module1 {
+
+    namespace "urn:ietf:params:xml:ns:aug:module:1";
+
+    prefix mod-a;
+
+    container cont{
+        container val {
+            leaf-list create {
+                type string;
+            }
+        }
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module2.yang b/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module2.yang
new file mode 100644
index 0000000..7ec09aa
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module2.yang
@@ -0,0 +1,39 @@
+module module2 {
+
+    namespace "urn:ietf:params:xml:ns:aug:module:2";
+
+    prefix mod-b;
+
+    import module1 {
+        prefix mod-a;
+    }
+
+    augment "/mod-a:cont/mod-a:val" {
+        leaf arg {
+            type string;
+        }
+    }
+
+    augment "/mod-a:cont/mod-a:val" {
+        leaf-list arg-lis {
+            type string;
+        }
+    }
+
+    augment "/mod-a:cont/mod-a:val" {
+        container cont {
+            leaf ll {
+                type binary;
+            }
+        }
+    }
+
+    augment "/mod-a:cont/mod-a:val" {
+        list contlist {
+            key true;
+            leaf true {
+                type boolean;
+            }
+        }
+    }
+}
diff --git a/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-if-ip.yang b/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-if-ip.yang
new file mode 100644
index 0000000..1c7a8ce
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-if-ip.yang
@@ -0,0 +1,69 @@
+module openconfig-if-ip {
+
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/interfaces/ip";
+
+  prefix "oc-ip";
+
+  import openconfig-interfaces {
+   prefix oc-if;
+  }
+
+  grouping ip-vrrp-top {
+    container vrrp {
+      list vrrp-group {
+        key "virtual-router-id";
+        leaf virtual-router-id {
+          type string;
+        }
+      }
+    }
+  }
+
+  grouping ipv4-top {
+    container ipv4 {
+      container addresses {
+        list address {
+          key "ip";
+          leaf ip {
+            type string;
+          }
+        }
+      }
+    }
+  }
+
+  grouping ipv6-top {
+    container ipv6 {
+      container addresses {
+        list address {
+          key "ip";
+          leaf ip {
+            type string;
+          }
+        }
+      }
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface" {
+    uses ipv4-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface" {
+    uses ipv6-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address" {
+    uses ip-vrrp-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address" {
+    uses ip-vrrp-top;
+  }
+}
diff --git a/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-interfaces.yang b/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-interfaces.yang
new file mode 100644
index 0000000..2804dc6
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-interfaces.yang
@@ -0,0 +1,42 @@
+module openconfig-interfaces {
+
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/interfaces";
+
+  prefix "oc-if";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  grouping subinterfaces-top {
+    container subinterfaces {
+      list subinterface {
+        key "index";
+        leaf index {
+          type int8;
+        }
+      }
+    }
+  }
+
+  grouping interfaces-top {
+    description
+      "Top-level grouping for interface configuration and
+      operational state data";
+
+    container interfaces {
+      list interface {
+        key "name";
+
+        leaf name {
+          type string;
+        }
+        uses subinterfaces-top;
+      }
+    }
+  }
+
+  uses interfaces-top;
+}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/DataTreeContextSwitchTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/DataTreeContextSwitchTest.java
index 3277212..69fb3f6 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/DataTreeContextSwitchTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/DataTreeContextSwitchTest.java
@@ -18,6 +18,15 @@
 
 
 import org.junit.Test;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.PrivateIp;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.AugmentedSchValid;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.DefaultAugmentedSchValid;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.AugCaseModKey;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.DefaultAugCaseModKey;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.DefaultTestedCont;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.DefaultUnlistedVal;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.TestedCont;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.UnlistedVal;
 import org.onosproject.yang.gen.v1.modeldatatoresourcedata.rev20160826.modeldatatoresourcedata.BinaryTypedef;
 import org.onosproject.yang.gen.v1.modeldatatoresourcedata.rev20160826.modeldatatoresourcedata.DefaultFirstLevel;
 import org.onosproject.yang.gen.v1.modeldatatoresourcedata.rev20160826.modeldatatoresourcedata.UnionTypedef;
@@ -43,6 +52,8 @@
 import org.onosproject.yang.gen.v1.modulelistandkeyaugment.rev20160826.modulelistandkeyaugment.modkey.DefaultAugmentedSchModKey;
 import org.onosproject.yang.gen.v1.modulelistandkeyaugment.rev20160826.modulelistandkeyaugment.modkey.augmentedschmodkey.AugListModKey;
 import org.onosproject.yang.gen.v1.modulelistandkeyaugment.rev20160826.modulelistandkeyaugment.modkey.augmentedschmodkey.DefaultAugListModKey;
+import org.onosproject.yang.gen.v1.ytbchoicewithcontainerandleaflist.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.DefaultValid;
+import org.onosproject.yang.gen.v1.ytbchoicewithcontainerandleaflist.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.Valid;
 import org.onosproject.yang.gen.v1.ytbchoicewithcontainerandleaflist.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.ChoiceContainer;
 import org.onosproject.yang.gen.v1.ytbchoicewithcontainerandleaflist.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.DefaultChoiceContainer;
 import org.onosproject.yang.gen.v1.ytbchoicewithcontainerandleaflist.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.choicecontainer.DefaultPredict;
@@ -59,6 +70,7 @@
 import org.onosproject.yang.gen.v1.ytbsimplechoicecase.rev20160826.ytbsimplechoicecase.ytbfood.ytbsnack.DefaultYtbLateNight;
 import org.onosproject.yang.model.DataNode;
 import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.InnerModelObject;
 import org.onosproject.yang.model.InnerNode;
 import org.onosproject.yang.model.KeyLeaf;
 import org.onosproject.yang.model.ListKey;
@@ -80,9 +92,9 @@
 import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_NODE;
 import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_LEAF_VALUE_NODE;
 import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_NODE;
-import static org.onosproject.yang.runtime.impl.TestUtils.validateDataNode;
 import static org.onosproject.yang.runtime.impl.MockYangSchemaNodeProvider.processSchemaRegistry;
 import static org.onosproject.yang.runtime.impl.MockYangSchemaNodeProvider.registry;
+import static org.onosproject.yang.runtime.impl.TestUtils.validateDataNode;
 
 /**
  * Unit test cases for YANG tree builder for context switch for augment, RPC
@@ -1379,6 +1391,97 @@
                          true, "namespace");
     }
 
+    /**
+     * Unit test case for multi augments with the same augment name.
+     */
+    @Test
+    public void processMultiAugWithSameName() {
+        setUp();
+
+        AugmentedSchValid valid = new DefaultAugmentedSchValid();
+        valid.chTest(PrivateIp.class);
+        byte b1 = 8;
+        byte b2 = 110;
+        valid.addToTest(b1);
+        valid.addToTest(b2);
+        TestedCont cont = new DefaultTestedCont();
+        cont.presence("true");
+        valid.testedCont(cont);
+        UnlistedVal val = new DefaultUnlistedVal();
+        val.presence("false");
+        valid.addToUnlistedVal(val);
+        AugCaseModKey modKey = new DefaultAugCaseModKey();
+        modKey.types(12);
+        valid.addToAugCaseModKey(modKey);
+        Valid valid1 = new DefaultValid();
+        valid1.addAugmentation((InnerModelObject) valid);
+
+        data = new DefaultModelObjectData.Builder();
+        data.addModelObject((InnerModelObject) valid1);
+
+        rscData = treeBuilder.getResourceData(data.build());
+
+        nameSpace = "yms:test:ytb:choice:with:container:and:leaf:list";
+
+        id = rscData.resourceId();
+        keys = id.nodeKeys();
+        assertThat(1, is(keys.size()));
+
+        sid = keys.get(0).schemaId();
+        assertThat("/", is(sid.name()));
+        assertThat(null, is(sid.namespace()));
+
+        dataNodes = rscData.dataNodes();
+        assertThat(6, is(dataNodes.size()));
+
+        node = dataNodes.get(0);
+        validateDataNode(node, "ch-test", nameSpace,
+                         SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "private-ip");
+
+        node = dataNodes.get(1);
+        validateDataNode(node, "test", nameSpace,
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, true, "8");
+
+        node = dataNodes.get(2);
+        validateDataNode(node, "test", nameSpace,
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, true, "110");
+
+        node = dataNodes.get(3);
+        validateDataNode(node, "unlisted-val", nameSpace, MULTI_INSTANCE_NODE,
+                         true, null);
+
+        Map<NodeKey, DataNode> child = ((InnerNode) node).childNodes();
+        assertThat(1, is(child.size()));
+
+        Iterator<Map.Entry<NodeKey, DataNode>> it = child.entrySet().iterator();
+        Map.Entry<NodeKey, DataNode> n = it.next();
+        validateDataNode(n.getValue(), "presence", nameSpace,
+                         SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "false");
+
+        node = dataNodes.get(4);
+        validateDataNode(node, "aug-case-modKey", nameSpace,
+                         MULTI_INSTANCE_NODE, true, null);
+
+        child = ((InnerNode) node).childNodes();
+        assertThat(1, is(child.size()));
+
+        it = child.entrySet().iterator();
+        n = it.next();
+        validateDataNode(n.getValue(), "types", nameSpace,
+                         SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "12");
+
+        node = dataNodes.get(5);
+        validateDataNode(node, "tested-cont", nameSpace, SINGLE_INSTANCE_NODE,
+                         true, null);
+
+        child = ((InnerNode) node).childNodes();
+        assertThat(1, is(child.size()));
+
+        it = child.entrySet().iterator();
+        n = it.next();
+        validateDataNode(n.getValue(), "presence", nameSpace,
+                         SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "true");
+    }
 
     /**
      * Unit test for inter file augment. Model object is null so resource id
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
index 6afb987..d1bf76a 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
@@ -97,6 +97,35 @@
         value = "str2";
         dBlr = addDataNode(dBlr, "router-ip", IP_TOPO_NAME_SPACE, value, null);
         dBlr = exitDataNode(dBlr);
+
+        value = "r1tor2";
+        dBlr = addDataNode(dBlr, "router-path", IP_TOPO_NAME_SPACE, value, null);
+        dBlr = exitDataNode(dBlr);
+
+        value = null;
+        dBlr = addDataNode(dBlr, "aug-route", IP_TOPO_NAME_SPACE, value, null);
+        value = "r2tor1";
+        dBlr = addDataNode(dBlr, "router-path", IP_TOPO_NAME_SPACE, value, null);
+
+        dBlr = exitDataNode(dBlr);
+        dBlr = exitDataNode(dBlr);
+
+        value = "17";
+        dBlr = addDataNode(dBlr, "value", IP_TOPO_NAME_SPACE, value, null);
+        dBlr = exitDataNode(dBlr);
+
+        value = "18";
+        dBlr = addDataNode(dBlr, "value", IP_TOPO_NAME_SPACE, value, null);
+        dBlr = exitDataNode(dBlr);
+
+        value = null;
+        dBlr = addDataNode(dBlr, "aug-route-c", IP_TOPO_NAME_SPACE, value, null);
+
+        value = "valid";
+        dBlr = addDataNode(dBlr, "val", IP_TOPO_NAME_SPACE, value, null);
+        dBlr = exitDataNode(dBlr);
+
+        dBlr = exitDataNode(dBlr);
         return dBlr.build();
     }
 
@@ -197,6 +226,11 @@
                 .augmentation(DefaultAugmentedTopoNode.class);
         assertThat(obj.routerId(), is("str1"));
         assertThat(obj.routerIp(), is("str2"));
+        assertThat(obj.routerPath(), is("r1tor2"));
+        assertThat(obj.augRoute().routerPath(), is("r2tor1"));
+        assertThat(obj.value().get(0).toString(), is("17"));
+        assertThat(obj.value().get(1).toString(), is("18"));
+        assertThat(obj.augRoutec().get(0).val(), is("valid"));
     }
 
     @Test
diff --git a/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang b/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang
index cb56c41..cd24d2e 100644
--- a/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang
+++ b/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang
@@ -20,6 +20,32 @@
         }
     }
 
+    augment /topo:node{
+        leaf router-path {
+            type string;
+        }
+        container aug-route {
+            leaf router-path {
+                type string;
+            }
+        }
+    }
+
+    augment /topo:node{
+        leaf-list value {
+            type uint8;
+        }
+    }
+
+    augment /topo:node{
+        list aug-route-c {
+            key val;
+            leaf val {
+                type string;
+            }
+        }
+    }
+
     augment /topo:node/topo:termination-points/topo:termination-point {
         leaf ip-address {
             type string;
diff --git a/runtime/src/test/resources/ytbTestYangFiles/AugmentChoice.yang b/runtime/src/test/resources/ytbTestYangFiles/AugmentChoice.yang
index cc68691..637fa45 100644
--- a/runtime/src/test/resources/ytbTestYangFiles/AugmentChoice.yang
+++ b/runtime/src/test/resources/ytbTestYangFiles/AugmentChoice.yang
@@ -2,14 +2,26 @@
     yang-version 1;
     namespace yms:test:ytb:choice:with:container:and:leaf:list";
     prefix "sch1";
-        import YtbChoiceWithContainerAndLeafList {
-            prefix sch;
-        }
+
+    import YtbChoiceWithContainerAndLeafList {
+        prefix sch;
+    }
     revision "2016-08-26";
 
+    identity ip {
+    }
+
+    identity private-ip {
+        base ip;
+    }
+
+    identity public-ip {
+        base ip;
+    }
+
     augment /sch:content-test/ {
         list aug-choice-modKey {
-        key "types";
+            key "types";
             leaf types {
                 type int32;
             }
@@ -17,11 +29,36 @@
     }
 
     augment /sch:content-test/sch:valid {
+        leaf ch-test {
+            type identityref {
+                base ip;
+            }
+        }
+
+        leaf-list test {
+            type int8;
+        }
+
+        container tested-cont {
+            leaf presence {
+                type string;
+            }
+        }
+
+        list unlisted-val {
+            key "presence";
+            leaf presence {
+                type string;
+            }
+        }
+    }
+
+    augment /sch:content-test/sch:valid {
         list aug-case-modKey {
             key "types";
             leaf types {
                 type int32;
             }
         }
-     }
+    }
 }
\ No newline at end of file