diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/YtbContextSwitchTest.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/YtbContextSwitchTest.java
new file mode 100644
index 0000000..ef48954
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/YtbContextSwitchTest.java
@@ -0,0 +1,1237 @@
+/*
+ * 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.yms.app.ytb;
+
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev20130715.ymsietfinettypes.Uri;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.YmsIetfNetwork;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.YmsIetfNetworkOpParam;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ymsietfnetwork.DefaultNetworks;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ymsietfnetwork.Networks;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ymsietfnetwork.NodeId;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ymsietfnetwork.networks.DefaultNetwork;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ymsietfnetwork.networks.Network;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ymsietfnetwork.networks.network.DefaultNode;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ymsietfnetwork.networks.network.Node;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ymsietfnetwork.networks.network.node.DefaultSupportingNode;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ymsietfnetwork.networks.network.node.SupportingNode;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.from.another.file.rev20160826.ytbaugmentfromanotherfile.networks.network.node.AugmentedNdNode;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.from.another.file.rev20160826.ytbaugmentfromanotherfile.networks.network.node.DefaultAugmentedNdNode;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.from.another.file.rev20160826.ytbaugmentfromanotherfile.networks.network.node.augmentedndnode.DefaultTerminationPoint;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.from.another.file.rev20160826.ytbaugmentfromanotherfile.networks.network.node.augmentedndnode.TerminationPoint;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.from.another.file.rev20160826.ytbaugmentfromanotherfile.networks.network.node.augmentedndnode.terminationpoint.DefaultSupportingTerminationPoint;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.from.another.file.rev20160826.ytbaugmentfromanotherfile.networks.network.node.augmentedndnode.terminationpoint.SupportingTerminationPoint;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput.activatesoftwareimage.output.AugmentedRpcOutput;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput.activatesoftwareimage.output.DefaultAugmentedRpcOutput;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput.activatesoftwareimage.output.augmentedrpcoutput.Selection;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput.activatesoftwareimage.output.augmentedrpcoutput.selection.DefaultValueIn;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput.activatesoftwareimage.output.augmentedrpcoutput.selection.valuein.ValueIn;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput2.activatesoftwareimage.output.AugmentedInputOutput;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput2.activatesoftwareimage.output.DefaultAugmentedInputOutput;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput2.activatesoftwareimage.output.augmentedinputoutput.DefaultFriction;
+import org.onosproject.yang.gen.v1.yms.test.ytb.augment.yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput2.activatesoftwareimage.output.augmentedinputoutput.Friction;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.YtbChoiceWithContainerAndLeafList;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.YtbChoiceWithContainerAndLeafListOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.ytbchoicewithcontainerandleaflist.ContentTest;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.ytbchoicewithcontainerandleaflist.CurrentValue;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.DefaultChoiceContainer;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.ChoiceContainer;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.choicecontainer.DefaultPredict;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.choicecontainer.Predict;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.choicecontainer.predict.DefaultReproduce;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.choicecontainer.predict.Reproduce;
+import org.onosproject.yang.gen.v1.yms.test.ytb.choice.with.container.and.leaf.list.rev20160826.ytbchoicewithcontainerandleaflist.currentvalue.DefaultYtbAbsent;
+import org.onosproject.yang.gen.v1.yms.test.ytb.rpc.response.with.advanced.input.and.output.rev20160826.ytbrpcresponsewithadvancedinputandoutput.activatesoftwareimage.ActivateSoftwareImageOutput;
+import org.onosproject.yang.gen.v1.yms.test.ytb.rpc.response.with.advanced.input.and.output.rev20160826.ytbrpcresponsewithadvancedinputandoutput.activatesoftwareimage.DefaultActivateSoftwareImageOutput;
+import org.onosproject.yang.gen.v1.yms.test.ytb.rpc.response.with.advanced.input.and.output.rev20160826.ytbrpcresponsewithadvancedinputandoutput.activatesoftwareimage.activatesoftwareimageoutput.DefaultOutputList;
+import org.onosproject.yang.gen.v1.yms.test.ytb.rpc.response.with.advanced.input.and.output.rev20160826.ytbrpcresponsewithadvancedinputandoutput.activatesoftwareimage.activatesoftwareimageoutput.OutputList;
+import org.onosproject.yang.gen.v1.yms.test.ytb.rpc.response.with.advanced.input.and.output.rev20160826.ytbrpcresponsewithadvancedinputandoutput.activatesoftwareimage.activatesoftwareimageoutput.outputlist.ContentInside;
+import org.onosproject.yang.gen.v1.yms.test.ytb.rpc.response.with.advanced.input.and.output.rev20160826.ytbrpcresponsewithadvancedinputandoutput.activatesoftwareimage.activatesoftwareimageoutput.outputlist.DefaultContentInside;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.augment.rev20160826.YtbSimpleAugment;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.augment.rev20160826.YtbSimpleAugmentOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.augment.rev20160826.ytbsimpleaugment.Cont1;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.augment.rev20160826.ytbsimpleaugment.DefaultCont1;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.augment.rev20160826.ytbsimpleaugment.cont1.DefaultCont2;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.augment.rev20160826.ytbsimpleaugment.cont1.cont2.AugmentedCont2;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.augment.rev20160826.ytbsimpleaugment.cont1.cont2.DefaultAugmentedCont2;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.augment.rev20160826.ytbsimpleaugment.cont1.cont2.augmentedcont2.Cont1s;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.augment.rev20160826.ytbsimpleaugment.cont1.cont2.augmentedcont2.DefaultCont1s;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.choice.yangautoprefixcase.rev20160826.YtbSimpleChoiceCase;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.choice.yangautoprefixcase.rev20160826.YtbSimpleChoiceCaseOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.choice.yangautoprefixcase.rev20160826.ytbsimplechoicecase.DefaultYtbFood;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.choice.yangautoprefixcase.rev20160826.ytbsimplechoicecase.YtbFood;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.choice.yangautoprefixcase.rev20160826.ytbsimplechoicecase.ytbfood.YtbSnack;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.choice.yangautoprefixcase.rev20160826.ytbsimplechoicecase.ytbfood.ytbsnack.DefaultYtbLateNight;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.rpc.response.rev20160826.ytbsimplerpcresponse.rpc.DefaultRpcOutput;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.rpc.response.rev20160826.ytbsimplerpcresponse.rpc.RpcOutput;
+import org.onosproject.yms.app.ydt.YangRequestWorkBench;
+import org.onosproject.yms.app.ydt.YdtExtendedBuilder;
+import org.onosproject.yms.app.ysr.DefaultYangSchemaRegistry;
+import org.onosproject.yms.ydt.YdtContext;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.onosproject.yms.ydt.YdtContextOperationType.NONE;
+import static org.onosproject.yms.ydt.YmsOperationType.EDIT_CONFIG_REPLY;
+import static org.onosproject.yms.ydt.YmsOperationType.EDIT_CONFIG_REQUEST;
+import static org.onosproject.yms.ydt.YmsOperationType.QUERY_CONFIG_REPLY;
+import static org.onosproject.yms.ydt.YmsOperationType.RPC_REQUEST;
+
+/**
+ * Unit test cases for YANG tree builder for context switch for augment, RPC
+ * and case.
+ */
+public class YtbContextSwitchTest extends YtbErrMsgAndConstants {
+
+    private static final String RPC_ADV_NAME = "RPCAdvanced";
+    private static final String RPC_ADV_NAMESPACE = "RPCAdvancedSpace";
+    private static final String RPC_ADV_IO =
+            "YtbRpcResponseWithAdvancedInputAndOutput";
+    private static final String ACT_IMG = "activate-software-image";
+    private static final String INPUT = "input";
+    private static final String FINAL = "final";
+    private static final String AUG_NW_REF_1 = "network-ref-aug1";
+    private static final String AUG_NODE_REF_1 = "node-ref-aug1";
+    private static final String AUG_TP_REF_1 = "tp-ref-aug-1";
+    private static final String AUG_TP_ID_1 = "tp-id-aug-1";
+    private static final String AUG_NW_REF_B1 = "network-ref-augb1";
+    private static final String AUG_NODE_REF_B1 = "node-ref-augb1";
+    private static final String AUG_TP_REF_B1 = "tp-ref-aug-b1";
+    private static final String AUG_TP_ID_B1 = "tp-id-aug-1b";
+    private static final String NW_REF = "network-ref";
+    private static final String NODE_REF = "node-ref";
+    private static final String NW_REF_2 = "network-ref2";
+    private static final String NODE_REF_3 = "node-ref3";
+    private static final String NW_REF_B = "network-ref-b";
+    private static final String NODE_REF_B = "node-ref-b";
+    private static final String NW_REF_2B = "network-ref2-b";
+    private static final String NODE_REF_2B = "node-ref2-b";
+    private static final String NODE_REF_3B = "node-ref3-b";
+    private static final String CHOC = "choc";
+    private static final String CHOICE_CASE = "YtbSimpleChoiceCase";
+    private static final String FOOD = "YtbFood";
+    private static final String CHOCOLATE = "chocolate";
+    private static final String VAL = "val";
+    private static final String IND = "ind";
+    private static final String CHOICE_ROOT_NAME = "choiceContainerRootName";
+    private static final String CHOICE_ROOT_NAMESPACE =
+            "choiceContainerRootNamespace";
+    private static final String ROOT = "root";
+    private static final String CHOICE_CONT =
+            "YtbChoiceWithContainerAndLeafList";
+    private static final String CONT_CHOICE = "choice-container";
+    private static final String REPRODUCE = "reproduce";
+    private static final String NINETY = "90";
+    private static final String HUNDRED = "100";
+    private static final String RPC_RT_NAME = "rpcRootName";
+    private static final String RPC_RT_NAMESPACE = "rpcRootNameSpace";
+    private static final String OUTPUT_LEAF = "output-leaf";
+    private static final String FIVE_HUNDRED = "500";
+    private static final String OUTPUT_LIST = "output-list";
+    private static final String LIST_KEY = "list-key";
+    private static final String BIN_VAL_1 = "AAE=";
+    private static final String CONT_INSIDE = "content_inside";
+    private static final String BIN_VAL_2 = "CAk=";
+    private static final String AVAILABLE = "available";
+    private static final String EIGHTY_NINE = "89";
+    private static final String NINETY_EIGHT = "98";
+    private static final String BIN_VAL_3 = "AAA=";
+    private static final String SIM_AUG = "simpleAugment";
+    private static final String SIM_AUG_NAMESPACE = "simpleAugmentSpace";
+    private static final String SIMPLE_AUG = "YtbSimpleAugment";
+    private static final String CONT1 = "cont1";
+    private static final String CONT2 = "cont2";
+    private static final String LEAF4 = "leaf4";
+    private static final String CONT1S = "cont1s";
+    private static final String INTER_AUG = "inter-file-augment";
+    private static final String INTER_AUG_NAMESPACE =
+            "inter-file-augment-space";
+    private static final String IETF_NW = "yms-ietf-network";
+    private static final String NWS = "networks";
+    private static final String NW = "network";
+    private static final String NODE = "node";
+    private static final String NODE_ID = "node-id";
+    private static final String TERM_POINT = "termination-point";
+    private static final String TP_ID = "tp-id";
+    private static final String SUP_TERM_POINT = "supporting-termination-point";
+    private static final String TP_REF = "tp-ref";
+    private static final String SUP_NODE = "supporting-node";
+    private static final String KIN1 = "kin1";
+    private static final String KIN2 = "kin2";
+    private static final String VAL_IN = "value-in";
+    private static final String KINETIC = "kinetic";
+    private static final String FRICTION = "friction";
+    private static final String SPEED = "speed";
+    private static final String THOUSAND = "1000";
+
+    /**
+     * Creates object as like an application for RPC with list.
+     *
+     * @return object of RPC
+     */
+    private List<OutputList> createApplicationBuiltObjectForRpc() {
+
+        // Creates a empty container inside without leaf for list1.
+        ContentInside inside1 = new DefaultContentInside.ContentInsideBuilder()
+                .build();
+
+        // Creates a leaf list-key which is a leaf ref.
+        byte[] listKey1 = new byte[]{0, 1};
+
+        // Creates the list content 1.
+        OutputList output1 = new DefaultOutputList.OutputListBuilder()
+                .listKey(listKey1).contentInside(inside1).build();
+
+        // Creates a list of leaf for available.
+        List<Short> avail = new ArrayList<>();
+        avail.add((short) 89);
+        avail.add((short) 98);
+
+        // Adds the leaf list in the inside container.
+        ContentInside inside2 = new DefaultContentInside.ContentInsideBuilder()
+                .available(avail).build();
+
+        // Creates a leaf, list-key which is a leaf ref.
+        byte[] listKey2 = new byte[]{8, 9};
+
+        // Creates the list content 2.
+        OutputList outputList2 = new DefaultOutputList.OutputListBuilder()
+                .listKey(listKey2).contentInside(inside2).build();
+
+        // Creates only leaf, list-key which is a leaf ref.
+        byte[] arr3 = new byte[]{0, 0};
+
+        // Creates the list content 3.
+        OutputList outputList3 = new DefaultOutputList.OutputListBuilder()
+                .listKey(arr3).build();
+
+        // Adds all the list contents in array list and gives returns it.
+        List<OutputList> outputLists = new ArrayList<>();
+        outputLists.add(output1);
+        outputLists.add(outputList2);
+        outputLists.add(outputList3);
+        return outputLists;
+    }
+
+    /**
+     * Builds YANG request work bench for RPC with container input.
+     *
+     * @param registry schema registry
+     * @return YANG request work bench
+     */
+    private YangRequestWorkBench buildYangRequestWorkBenchForRpc(
+            DefaultYangSchemaRegistry registry) {
+
+        // Creates a request work bench and adds the input child into it.
+        YangRequestWorkBench workBench = new YangRequestWorkBench(
+                RPC_ADV_NAME, RPC_ADV_NAMESPACE, RPC_REQUEST,
+                registry, true);
+        Set<String> valueList = new HashSet<>();
+        valueList.add("800");
+        valueList.add("900");
+        workBench.addChild(RPC_ADV_IO, null, NONE);
+        workBench.addChild(ACT_IMG, null, NONE);
+        workBench.addChild(INPUT, null, NONE);
+        workBench.addChild(FINAL, null, NONE);
+        workBench.addLeaf("value", null, valueList);
+        return workBench;
+    }
+
+    /**
+     * Creates an application object for inter file augment.
+     *
+     * @return application object
+     */
+    private Object createObjectForInterFileAugment() {
+
+        // Creates leaf value for network-ref.
+        Uri nwkRef = new Uri(AUG_NW_REF_1);
+        Uri nwkRef2 = new Uri("network-ref-aug2");
+
+        // Creates leaf value for node-ref
+        Uri nodeRef = new Uri(AUG_NODE_REF_1);
+        NodeId nodeId = new NodeId(nodeRef);
+
+        Uri nodeRef2 = new Uri("node-ref-aug2");
+        NodeId nodeId2 = new NodeId(nodeRef2);
+
+        // Creates support termination list with the above two contents.
+        SupportingTerminationPoint point1 =
+                new DefaultSupportingTerminationPoint
+                        .SupportingTerminationPointBuilder()
+                        .networkRef(nwkRef).nodeRef(nodeId)
+                        .tpRef(AUG_TP_REF_1).build();
+        SupportingTerminationPoint point2 =
+                new DefaultSupportingTerminationPoint
+                        .SupportingTerminationPointBuilder()
+                        .networkRef(nwkRef2).nodeRef(nodeId2)
+                        .tpRef("tp-ref-aug-2").build();
+
+        List<SupportingTerminationPoint> pointList = new ArrayList<>();
+        pointList.add(point1);
+        pointList.add(point2);
+
+        // Adds the list created to the termination point content1.
+        TerminationPoint tPoint1 = new DefaultTerminationPoint
+                .TerminationPointBuilder()
+                .supportingTerminationPoint(pointList)
+                .tpId(AUG_TP_ID_1).build();
+
+        // Creates leaf value for network-ref.
+        Uri nwkRef3 = new Uri(AUG_NW_REF_B1);
+        Uri nwkRef4 = new Uri("network-ref-augb2");
+
+        // Creates leaf value for node-ref
+        Uri nodeRef3 = new Uri(AUG_NODE_REF_B1);
+        NodeId nodeId3 = new NodeId(nodeRef3);
+
+        Uri nodeRef4 = new Uri("node-ref-augb2");
+        NodeId nodeId4 = new NodeId(nodeRef4);
+
+        // Creates support termination list with the above two contents.
+        SupportingTerminationPoint point3 =
+                new DefaultSupportingTerminationPoint
+                        .SupportingTerminationPointBuilder()
+                        .networkRef(nwkRef3).nodeRef(nodeId3)
+                        .tpRef(AUG_TP_REF_B1).build();
+        SupportingTerminationPoint point4 =
+                new DefaultSupportingTerminationPoint
+                        .SupportingTerminationPointBuilder()
+                        .networkRef(nwkRef4).nodeRef(nodeId4)
+                        .tpRef("tp-ref-aug-b2").build();
+
+        List<SupportingTerminationPoint> pointList2 = new ArrayList<>();
+        pointList2.add(point3);
+        pointList2.add(point4);
+
+        // Adds the list created to the termination point content2.
+        TerminationPoint tPoint2 = new DefaultTerminationPoint
+                .TerminationPointBuilder()
+                .supportingTerminationPoint(pointList2)
+                .tpId(AUG_TP_ID_B1).build();
+
+        List<TerminationPoint> terminationPointList = new ArrayList<>();
+        terminationPointList.add(tPoint1);
+        terminationPointList.add(tPoint2);
+
+        // Adds all the above contents to the augment.
+        AugmentedNdNode augment = new DefaultAugmentedNdNode
+                .AugmentedNdNodeBuilder()
+                .terminationPoint(terminationPointList)
+                .build();
+
+        // Creates leaf value for network-ref in augmented node(ietf-network).
+        Uri nwRef5 = new Uri(NW_REF);
+
+        //Creates leaf value for node-ref in augmented node(ietf-network).
+        Uri nodeRef5 = new Uri(NODE_REF);
+        NodeId nodeId5 = new NodeId(nodeRef5);
+
+        // Creates supporting node list content 1 with above contents.
+        SupportingNode supNode1 = new DefaultSupportingNode
+                .SupportingNodeBuilder().nodeRef(nodeId5)
+                .networkRef(nwRef5).build();
+
+        // Creates leaf value for network-ref in augmented node(ietf-network).
+        Uri nwRef6 = new Uri(NW_REF_2);
+
+        //Creates leaf value for node-ref in augmented node(ietf-network).
+        Uri nodeRef6 = new Uri("node-ref2");
+        NodeId nodeId6 = new NodeId(nodeRef6);
+
+        // Creates supporting node list content 2 with above contents.
+        SupportingNode supNode2 = new DefaultSupportingNode
+                .SupportingNodeBuilder()
+                .nodeRef(nodeId6)
+                .networkRef(nwRef6).build();
+
+        List<SupportingNode> supNodeList = new ArrayList<>();
+        supNodeList.add(supNode1);
+        supNodeList.add(supNode2);
+
+        // Creates leaf value for node-id in augmented node(ietf-network).
+        Uri nodeId1 = new Uri(NODE_REF_3);
+        NodeId nodeIdForId = new NodeId(nodeId1);
+
+        // Creates node list with content 1 by adding augment also.
+        DefaultNode.NodeBuilder nodeBuilder = new DefaultNode.NodeBuilder();
+        nodeBuilder.addYangAugmentedInfo(
+                augment, AugmentedNdNode.class);
+        nodeBuilder.supportingNode(supNodeList);
+        nodeBuilder.nodeId(nodeIdForId);
+        Node node1 = nodeBuilder.build();
+
+        // Creates an augment node without any values set to it.
+        AugmentedNdNode augmentedNdNode2 = new DefaultAugmentedNdNode
+                .AugmentedNdNodeBuilder().build();
+
+        // Creates leaf value for network-ref in augmented node(ietf-network).
+        Uri nwRef7 = new Uri(NW_REF_B);
+
+        //Creates leaf value for node-ref in augmented node(ietf-network).
+        Uri nodeRef7 = new Uri(NODE_REF_B);
+        NodeId nodeId7 = new NodeId(nodeRef7);
+
+        // Creates supporting node list content 1 with above contents.
+        SupportingNode supNode3 = new DefaultSupportingNode
+                .SupportingNodeBuilder().nodeRef(nodeId7)
+                .networkRef(nwRef7).build();
+
+        // Creates leaf value for network-ref in augmented node(ietf-network).
+        Uri nwRef8 = new Uri(NW_REF_2B);
+
+        //Creates leaf value for node-ref in augmented node(ietf-network).
+        Uri nodeRef8 = new Uri(NODE_REF_2B);
+        NodeId nodeId8 = new NodeId(nodeRef8);
+
+        // Creates supporting node list content 1 with above contents.
+        SupportingNode supNode4 = new DefaultSupportingNode
+                .SupportingNodeBuilder()
+                .nodeRef(nodeId8)
+                .networkRef(nwRef8).build();
+
+        List<SupportingNode> supNodeList2 = new ArrayList<>();
+        supNodeList2.add(supNode3);
+        supNodeList2.add(supNode4);
+
+        // Creates leaf value for node-id in augmented node(ietf-network).
+        Uri nodeIdLeaf = new Uri(NODE_REF_3B);
+        NodeId nodeIdForId2 = new NodeId(nodeIdLeaf);
+
+        // Creates node list with content 2 by adding empty augment also.
+        DefaultNode.NodeBuilder nodeBuilder2 = new DefaultNode.NodeBuilder();
+        nodeBuilder2.addYangAugmentedInfo(
+                augmentedNdNode2, AugmentedNdNode.class);
+        nodeBuilder2.supportingNode(supNodeList2);
+        nodeBuilder2.nodeId(nodeIdForId2);
+        Node node2 = nodeBuilder2.build();
+
+        // Adds both nodes into the list.
+        List<Node> nodeList = new LinkedList<>();
+        nodeList.add(node1);
+        nodeList.add(node2);
+
+        // Adds the list into the network list.
+        Network nwkList = new DefaultNetwork.NetworkBuilder()
+                .node(nodeList).build();
+
+        List<Network> networkList = new ArrayList<>();
+        networkList.add(nwkList);
+
+        // Adds the network list into networks container.
+        Networks contNetworks = new DefaultNetworks.NetworksBuilder()
+                .network(networkList).build();
+
+        // Adds the container into the module.
+        YmsIetfNetwork opParam = new YmsIetfNetworkOpParam
+                .YmsIetfNetworkBuilder()
+                .networks(contNetworks).build();
+        return opParam;
+    }
+
+    /**
+     * Processes a simple choice case and builds the YDT.
+     */
+    @Test
+    public void processSimpleChoiceCase() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates a choice snack with the case late night.
+        YtbSnack lateNight = new DefaultYtbLateNight.YtbLateNightBuilder()
+                .chocolate(CHOC).build();
+
+        // Creates container food with the created case.
+        YtbFood food = new DefaultYtbFood.YtbFoodBuilder()
+                .ytbSnack(lateNight).build();
+
+        // Creates module with the container food.
+        YtbSimpleChoiceCase choiceCase = new YtbSimpleChoiceCaseOpParam
+                .YtbSimpleChoiceCaseBuilder().ytbFood(food).build();
+
+        // As YSB or YAB protocol, sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(choiceCase);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, ROOT_NAME, ROOT_NAME_SPACE,
+                EDIT_CONFIG_REPLY, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext rootNode = ydtBuilder.getRootNode();
+
+        // Gets the first module from logical root node.
+        YdtContext module = rootNode.getFirstChild();
+        assertThat(getInCrtName(MODULE, CHOICE_CASE), module.getName(),
+                   is(CHOICE_CASE));
+
+        // Gets the container food from module.
+        YdtContext container = module.getFirstChild();
+        assertThat(getInCrtName(CONTAINER, FOOD), container.getName(),
+                   is(FOOD));
+
+        // Gets the case-leaf from container
+        YdtContext caseNode = container.getFirstChild();
+        assertThat(getInCrtName(LEAF, CHOCOLATE), caseNode.getName(),
+                   is(CHOCOLATE));
+        assertThat(getInCrtLeafValue(CHOCOLATE, CHOC), caseNode.getValue(),
+                   is(CHOC));
+    }
+
+    /**
+     * Processes module with two choices and a choice having node and a
+     * leaf-list.
+     */
+    @Test
+    public void processChoiceWithNodeAndLeafList() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates reproduce container for list predict-1.
+        Reproduce reproduce1 = new DefaultReproduce.ReproduceBuilder()
+                .yangAutoPrefixCatch((short) 90).build();
+
+        // Assigns predict-1 with the container.
+        Predict predict1 = new DefaultPredict.PredictBuilder()
+                .reproduce(reproduce1).build();
+
+        // Creates reproduce container for list predict-2.
+        Reproduce reproduce2 = new DefaultReproduce.ReproduceBuilder()
+                .yangAutoPrefixCatch((short) 100).build();
+
+        // Assigns predict-2 with the container.
+        Predict predict2 = new DefaultPredict.PredictBuilder()
+                .reproduce(reproduce2).build();
+
+        List<Predict> predictList = new ArrayList<>();
+        predictList.add(predict1);
+        predictList.add(predict2);
+
+        // Case container is added to the choice content-test.
+        ChoiceContainer containerCase = new org.onosproject.yang.gen.v1.yms
+                .test.ytb.choice.with.container.and.leaf.list.rev20160826
+                .ytbchoicewithcontainerandleaflist.contenttest.choicecontainer
+                .DefaultChoiceContainer.ChoiceContainerBuilder()
+                .predict(predictList).build();
+
+        // Case container is added to the choice content-test.
+        ContentTest contentTest = new DefaultChoiceContainer
+                .ChoiceContainerBuilder().choiceContainer(containerCase).build();
+
+        // Creates string list for leaf-list final.
+        List<String> stringList = new ArrayList<>();
+        stringList.add(VAL);
+        stringList.add(IND);
+
+        // For choice current value, the leaf list gets added as case.
+        CurrentValue currentValue = new DefaultYtbAbsent.YtbAbsentBuilder()
+                .yangAutoPrefixFinal(stringList).build();
+
+        // Adds choice as child to the module.
+        YtbChoiceWithContainerAndLeafList choiceWithContainerAndLeafList =
+                new YtbChoiceWithContainerAndLeafListOpParam
+                        .YtbChoiceWithContainerAndLeafListBuilder()
+                        .contentTest(contentTest).currentValue(currentValue)
+                        .build();
+
+        // As YSB or YAB protocol, sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(choiceWithContainerAndLeafList);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, CHOICE_ROOT_NAME, CHOICE_ROOT_NAMESPACE,
+                QUERY_CONFIG_REPLY, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+        assertThat(getInCrtName(ROOT, CHOICE_ROOT_NAME), context.getName(),
+                   is(CHOICE_ROOT_NAME));
+        assertThat(getInCrtName(ROOT, CHOICE_ROOT_NAMESPACE), context.getNamespace(),
+                   is(CHOICE_ROOT_NAMESPACE));
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        assertThat(getInCrtName(MODULE, CHOICE_CONT), module.getName(),
+                   is(CHOICE_CONT));
+
+        // Gets the first choice content under the module, as container.
+        YdtContext choice1 = module.getFirstChild();
+        assertThat(getInCrtName(CONTAINER, CONT_CHOICE), choice1.getName(),
+                   is(CONT_CHOICE));
+
+        // Gets the first content in the list predict.
+        YdtContext list1 = choice1.getFirstChild();
+        assertThat(getInCrtName(LIST, PREDICT), list1.getName(), is(PREDICT));
+
+        // Gets the container and its child leaf in the list predict.
+        YdtContext container1 = list1.getFirstChild();
+        assertThat(getInCrtName(CONTAINER, REPRODUCE), container1.getName(),
+                   is(REPRODUCE));
+        YdtContext leaf1 = container1.getFirstChild();
+        assertThat(getInCrtName(LEAF, CATCH), leaf1.getName(), is(CATCH));
+        assertThat(getInCrtLeafValue(CATCH, NINETY), leaf1.getValue(),
+                   is(NINETY));
+
+        // Gets the second content in the list predict.
+        YdtContext list2 = list1.getNextSibling();
+        assertThat(getInCrtName(LIST, PREDICT), list2.getName(), is(PREDICT));
+
+        // Gets the container and its child leaf in the list predict.
+        YdtContext container2 = list2.getFirstChild();
+        assertThat(getInCrtName(CONTAINER, REPRODUCE), container2.getName(),
+                   is(REPRODUCE));
+        YdtContext leaf2 = container2.getFirstChild();
+        assertThat(getInCrtName(LEAF, CATCH), leaf2.getName(), is(CATCH));
+        assertThat(getInCrtLeafValue(CATCH, HUNDRED), leaf2.getValue(),
+                   is(HUNDRED));
+
+        // Gets the second choice content under the module, as leaf-list.
+        YdtContext choice2 = choice1.getNextSibling();
+        assertThat(getInCrtName(LEAF_LIST, FINAL), choice2.getName(),
+                   is(FINAL));
+        Set value2 = choice2.getValueSet();
+        assertThat(getInCrtLeafListValue(FINAL, VAL), value2.contains(VAL),
+                   is(true));
+        assertThat(getInCrtLeafListValue(FINAL, IND), value2.contains(IND),
+                   is(true));
+    }
+
+    /**
+     * Processes RPC response of a simple output with only a leaf content
+     * inside.
+     */
+    @Test
+    public void processSimpleRpcResponse() {
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+        RpcOutput output = new DefaultRpcOutput.RpcOutputBuilder()
+                .outputLeaf(500).build();
+
+        // Creates request work bench of rpc.
+        YangRequestWorkBench workBench = new YangRequestWorkBench(
+                RPC_RT_NAME, RPC_RT_NAMESPACE, RPC_REQUEST, registry, true);
+        workBench.addChild(RPC_NAME, null, NONE);
+        workBench.addChild(RPC, null, NONE);
+        workBench.addChild(INPUT, null, NONE);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtForRpcResponse(
+                output, workBench);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+        assertThat(getInCrtName(ROOT, RPC_RT_NAME), context.getName(),
+                   is(RPC_RT_NAME));
+        assertThat(getInCrtName(ROOT, RPC_RT_NAMESPACE), context.getNamespace(),
+                   is(RPC_RT_NAMESPACE));
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        assertThat(getInCrtName(MODULE, RPC_NAME), module.getName(),
+                   is(RPC_NAME));
+
+        // Gets the rpc node from the module.
+        YdtContext rpc = module.getFirstChild();
+        assertThat(getInCrtName(RPC, RPC), rpc.getName(), is(RPC));
+
+        // Gets the output node from the module.
+        // TODO: Change assert after YANG utils is merged.
+        YdtContext rpcOutput = rpc.getFirstChild();
+        //assertThat(rpcOutputNode.getName(), is("output"));
+
+        YdtContext outputLeaf = rpcOutput.getFirstChild();
+        assertThat(getInCrtName(LEAF, OUTPUT_LEAF), outputLeaf.getName(),
+                   is(OUTPUT_LEAF));
+        assertThat(getInCrtLeafValue(OUTPUT_LEAF, FIVE_HUNDRED),
+                   outputLeaf.getValue(), is(FIVE_HUNDRED));
+    }
+
+    /**
+     * Processes RPC response of an output defined with list.
+     */
+    @Test
+    public void processRpcResponseForAdvInputOutput() {
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+        List<OutputList> list = createApplicationBuiltObjectForRpc();
+        ActivateSoftwareImageOutput output =
+                new DefaultActivateSoftwareImageOutput
+                        .ActivateSoftwareImageOutputBuilder()
+                        .outputList(list).build();
+
+        // Creates request work bench of rpc.
+        YangRequestWorkBench workBench = buildYangRequestWorkBenchForRpc(
+                registry);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtForRpcResponse(
+                output, workBench);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+        assertThat(getInCrtName(ROOT, RPC_ADV_NAME), context.getName(),
+                   is(RPC_ADV_NAME));
+        assertThat(getInCrtName(ROOT, RPC_ADV_NAMESPACE), context.getNamespace(),
+                   is(RPC_ADV_NAMESPACE));
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        assertThat(getInCrtName(MODULE, RPC_ADV_IO), module.getName(),
+                   is(RPC_ADV_IO));
+
+        // Gets the rpc node from module.
+        YdtContext rpc = module.getFirstChild();
+        assertThat(getInCrtName(RPC, ACT_IMG), rpc.getName(), is(ACT_IMG));
+
+        // Gets the output node from the module.
+        // TODO: Change assert after YANG utils is merged.
+        YdtContext rpcOutput = rpc.getFirstChild();
+        //assertThat(rpcOutputNode.getName(), is("output"));
+
+        // Gets the list content 1 as the node from output.
+        YdtContext outputList1 = rpcOutput.getFirstChild();
+        assertThat(getInCrtName(LIST, OUTPUT_LIST), outputList1.getName(),
+                   is(OUTPUT_LIST));
+
+        // Gets the leaf key-list from list content1.
+        YdtContext keyList1 = outputList1.getFirstChild();
+        assertThat(getInCrtName(LEAF, LIST_KEY), keyList1.getName(),
+                   is(LIST_KEY));
+        assertThat(getInCrtLeafValue(LIST_KEY, BIN_VAL_1), keyList1.getValue(),
+                   is(BIN_VAL_1));
+
+        // Gets the content inside container from list content 1.
+        YdtContext cont1 = keyList1.getNextSibling();
+        assertThat(getInCrtName(CONTAINER, CONT_INSIDE), cont1.getName(),
+                   is(CONT_INSIDE));
+
+        // Gets the list content 2 as the node from output.
+        YdtContext outputList2 = outputList1.getNextSibling();
+        assertThat(getInCrtName(LIST, OUTPUT_LIST), outputList2.getName(),
+                   is(OUTPUT_LIST));
+
+        // Gets the leaf-list key-list from list content2.
+        YdtContext keyList2 = outputList2.getFirstChild();
+        assertThat(getInCrtName(LEAF, LIST_KEY), keyList2.getName(),
+                   is(LIST_KEY));
+        assertThat(getInCrtLeafValue(LIST_KEY, BIN_VAL_2), keyList2.getValue(),
+                   is(BIN_VAL_2));
+
+        // Gets the content inside container from list content 2.
+        YdtContext cont2 = keyList2.getNextSibling();
+        assertThat(getInCrtName(CONTAINER, CONT_INSIDE), cont2.getName(),
+                   is(CONT_INSIDE));
+
+        // Gets the leaf-list available inside container.
+        YdtContext availLeafList = cont2.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, AVAILABLE), availLeafList.getName(),
+                   is(AVAILABLE));
+        Set value1 = availLeafList.getValueSet();
+        assertThat(getInCrtLeafListValue(AVAILABLE, EIGHTY_NINE),
+                   value1.contains(EIGHTY_NINE), is(true));
+        assertThat(getInCrtLeafListValue(AVAILABLE, NINETY_EIGHT),
+                   value1.contains(NINETY_EIGHT), is(true));
+
+        // Gets the list content 3.
+        YdtContext outputList3 = outputList2.getNextSibling();
+        assertThat(getInCrtName(LIST, OUTPUT_LIST), outputList3.getName(),
+                   is(OUTPUT_LIST));
+
+        // Gets the leaf list-key in content 3 of list.
+        YdtContext keyList3 = outputList3.getFirstChild();
+        assertThat(getInCrtName(LEAF, LIST_KEY), keyList3.getName(),
+                   is(LIST_KEY));
+        assertThat(getInCrtLeafValue(LIST_KEY, BIN_VAL_3), keyList3.getValue(),
+                   is(BIN_VAL_3));
+    }
+
+    /**
+     * Processes simple self augment file with leaf and container inside
+     * augment.
+     */
+    @Test
+    public void processSimpleAugment() {
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates container cont1s with the leaf.
+        org.onosproject.yang.gen.v1.yms.test.ytb.simple.augment.rev20160826
+                .ytbsimpleaugment.cont1.cont2.augmentedcont2.cont1s
+                .Cont1s cont1s1 = new org.onosproject.yang.gen.v1.yms.test
+                .ytb.simple.augment.rev20160826.ytbsimpleaugment.cont1.cont2
+                .augmentedcont2.cont1s.DefaultCont1s.Cont1sBuilder().build();
+
+        // Appends the created container into another container.
+        Cont1s cont1s = new DefaultCont1s.Cont1sBuilder()
+                .cont1s(cont1s1).build();
+
+        // Creates augment with the container and leaf.
+        AugmentedCont2 augment = new DefaultAugmentedCont2
+                .AugmentedCont2Builder().cont1s(cont1s).leaf4(500).build();
+
+        // Creates for the node which will be getting augmented.
+        // Creates cont2 where content will be augmented into.
+        DefaultCont2.Cont2Builder augCont2 = new DefaultCont2
+                .Cont2Builder();
+        augCont2.addYangAugmentedInfo(augment, AugmentedCont2.class);
+
+        // Creates cont1 where cont2 is added.
+        Cont1 cont1 = new DefaultCont1.Cont1Builder()
+                .cont2(augCont2.build()).build();
+
+        // Creates module with the nodes inside.
+        YtbSimpleAugment simpleAugment = new YtbSimpleAugmentOpParam
+                .YtbSimpleAugmentBuilder().cont1(cont1).build();
+
+        // As YSB or YAB protocol, sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(simpleAugment);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, SIM_AUG, SIM_AUG_NAMESPACE,
+                EDIT_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+        assertThat(getInCrtName(ROOT, SIM_AUG), context.getName(), is(SIM_AUG));
+        assertThat(getInCrtName(ROOT, SIM_AUG_NAMESPACE),
+                   context.getNamespace(), is(SIM_AUG_NAMESPACE));
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        assertThat(getInCrtName(MODULE, SIMPLE_AUG), module.getName(),
+                   is(SIMPLE_AUG));
+
+        // Gets the cont1 under module.
+        YdtContext container1 = module.getFirstChild();
+        assertThat(getInCrtName(CONTAINER, CONT1), container1.getName(),
+                   is(CONT1));
+
+        // Gets the cont2 under cont1.
+        YdtContext container2 = container1.getFirstChild();
+        assertThat(getInCrtName(CONTAINER, CONT2), container2.getName(),
+                   is(CONT2));
+
+        // Gets the leaf4 which was augmented under cont2.
+        YdtContext leaf4 = container2.getFirstChild();
+        assertThat(getInCrtName(LEAF, LEAF4), leaf4.getName(), is(LEAF4));
+        assertThat(getInCrtLeafValue(LEAF4, FIVE_HUNDRED), leaf4.getValue(),
+                   is(FIVE_HUNDRED));
+
+        // Gets the cont1s which was augmented under cont2.
+        YdtContext container1s = leaf4.getNextSibling();
+        assertThat(getInCrtName(CONTAINER, CONT1S), container1s.getName(),
+                   is(CONT1S));
+
+        // Gets the cont2s which was augmented under cont1s.
+        YdtContext container2s = container1s.getFirstChild();
+        assertThat(getInCrtName(CONTAINER, CONT1S), container2s.getName(),
+                   is(CONT1S));
+    }
+
+    /**
+     * Processes inter file augment with augmented node as list and the
+     * augment having list.
+     */
+    @Test
+    public void processInterFileAugment() {
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+        Object opParam = createObjectForInterFileAugment();
+
+        // As YSB or YAB protocol, sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(opParam);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, INTER_AUG, INTER_AUG_NAMESPACE,
+                EDIT_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+        assertThat(getInCrtName(ROOT, INTER_AUG), context.getName(),
+                   is(INTER_AUG));
+        assertThat(getInCrtName(ROOT, INTER_AUG_NAMESPACE), context.getNamespace(),
+                   is(INTER_AUG_NAMESPACE));
+
+        // Checks the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        assertThat(getInCrtName(MODULE, IETF_NW), module.getName(),
+                   is(IETF_NW));
+
+        // Checks the container networks from module.
+        YdtContext nwksCont = module.getFirstChild();
+        assertThat(getInCrtName(CONTAINER, NWS), nwksCont.getName(), is(NWS));
+
+        // Checks the list network from container networks.
+        YdtContext nwrkList = nwksCont.getFirstChild();
+        assertThat(getInCrtName(LIST, NW), nwrkList.getName(), is(NW));
+
+        // Checks the node list content 1 under network list.
+        YdtContext node1 = nwrkList.getFirstChild();
+        assertThat(getInCrtName(LIST, NODE), node1.getName(), is(NODE));
+
+        // Checks the node-id leaf for list content 1.
+        YdtContext nodeId1 = node1.getFirstChild();
+        assertThat(getInCrtName(LEAF, NODE_ID), nodeId1.getName(), is(NODE_ID));
+        assertThat(getInCrtLeafValue(NODE_ID, NODE_REF_3), nodeId1.getValue(),
+                   is(NODE_REF_3));
+
+        // Checks termination list 1 under node 1, from augment.
+        YdtContext terList1 = nodeId1.getNextSibling();
+        assertThat(getInCrtName(LIST, TERM_POINT), terList1.getName(),
+                   is(TERM_POINT));
+
+        // Checks tp-id leaf from termination list content 1.
+        YdtContext tpId1 = terList1.getFirstChild();
+        assertThat(getInCrtName(LEAF, TP_ID), tpId1.getName(), is(TP_ID));
+        assertThat(getInCrtLeafValue(TP_ID, AUG_TP_ID_1), tpId1.getValue(),
+                   is(AUG_TP_ID_1));
+
+        // Checks supporting term point list content1 from term list content 1.
+        YdtContext supTerm1 = tpId1.getNextSibling();
+        assertThat(getInCrtName(LIST, SUP_TERM_POINT), supTerm1.getName(),
+                   is(SUP_TERM_POINT));
+
+        YdtContext nwkRefSupTerm1 = supTerm1.getFirstChild();
+        assertThat(getInCrtName(LEAF, NW_REF), nwkRefSupTerm1.getName(),
+                   is(NW_REF));
+        assertThat(getInCrtLeafValue(NW_REF, AUG_NW_REF_1),
+                   nwkRefSupTerm1.getValue(), is(AUG_NW_REF_1));
+
+        YdtContext nodeRefSupTerm1 = nwkRefSupTerm1.getNextSibling();
+        assertThat(getInCrtName(LEAF, NODE_REF), nodeRefSupTerm1.getName(),
+                   is(NODE_REF));
+        assertThat(getInCrtLeafValue(NODE_REF, AUG_NODE_REF_1),
+                   nodeRefSupTerm1.getValue(), is(AUG_NODE_REF_1));
+
+        YdtContext tpRefSupTerm1 = nodeRefSupTerm1.getNextSibling();
+        assertThat(getInCrtName(LEAF, TP_REF), tpRefSupTerm1.getName(),
+                   is(TP_REF));
+        assertThat(getInCrtLeafValue(TP_REF, AUG_TP_REF_1),
+                   tpRefSupTerm1.getValue(), is(AUG_TP_REF_1));
+
+        // Checks termination list 2 under node 1, from augment.
+        YdtContext terminationList2 = terList1.getNextSibling();
+        assertThat(getInCrtName(LIST, TERM_POINT), terminationList2.getName(),
+                   is(TERM_POINT));
+
+        YdtContext terList2 = terminationList2.getFirstChild();
+        assertThat(getInCrtName(LEAF, TP_ID), terList2.getName(), is(TP_ID));
+        assertThat(getInCrtLeafValue(TP_ID, AUG_TP_ID_B1), terList2.getValue(),
+                   is(AUG_TP_ID_B1));
+
+        // Checks supporting term point list content1 from term list content 2.
+        YdtContext supTerm2 = terList2.getNextSibling();
+        assertThat(getInCrtName(LIST, SUP_TERM_POINT), supTerm2.getName(),
+                   is(SUP_TERM_POINT));
+
+        YdtContext nwkRefSupTerm2 = supTerm2.getFirstChild();
+        assertThat(getInCrtName(LEAF, NW_REF), nwkRefSupTerm2.getName(),
+                   is(NW_REF));
+        assertThat(getInCrtLeafValue(NW_REF, AUG_NW_REF_B1),
+                   nwkRefSupTerm2.getValue(), is(AUG_NW_REF_B1));
+
+        YdtContext nodeRefSupTerm2 = nwkRefSupTerm2.getNextSibling();
+        assertThat(getInCrtName(LEAF, NODE_REF), nodeRefSupTerm2.getName(),
+                   is(NODE_REF));
+        assertThat(getInCrtLeafValue(NODE_REF, AUG_NODE_REF_B1),
+                   nodeRefSupTerm2.getValue(), is(AUG_NODE_REF_B1));
+
+        YdtContext tpRefSupTerm2 = nodeRefSupTerm2.getNextSibling();
+        assertThat(getInCrtName(LEAF, TP_REF), tpRefSupTerm2.getName(),
+                   is(TP_REF));
+        assertThat(getInCrtLeafValue(TP_REF, AUG_TP_REF_B1),
+                   tpRefSupTerm2.getValue(), is(AUG_TP_REF_B1));
+
+        // Checks the content of the supporting node list content 1 in node 1.
+        YdtContext supNode1 = terminationList2.getNextSibling();
+        assertThat(getInCrtName(LIST, SUP_NODE), supNode1.getName(),
+                   is(SUP_NODE));
+
+        YdtContext nwkRefSupNode1 = supNode1.getFirstChild();
+        assertThat(getInCrtName(LEAF, NW_REF), nwkRefSupNode1.getName(),
+                   is(NW_REF));
+        assertThat(getInCrtLeafValue(NW_REF, NW_REF), nwkRefSupNode1.getValue(),
+                   is(NW_REF));
+
+        YdtContext nodeRefSupNode1 = nwkRefSupNode1.getNextSibling();
+        assertThat(getInCrtName(LEAF, NODE_REF), nodeRefSupNode1.getName(),
+                   is(NODE_REF));
+        assertThat(getInCrtLeafValue(NODE_REF, NW_REF),
+                   nwkRefSupNode1.getValue(), is(NW_REF));
+
+        // Checks the content of the supporting node list content 2 in node 1.
+        YdtContext supNode2 = supNode1.getNextSibling();
+        assertThat(getInCrtName(LIST, SUP_NODE), supNode2.getName(),
+                   is(SUP_NODE));
+
+        YdtContext nwkRefSupNode2 = supNode2.getFirstChild();
+        assertThat(getInCrtName(LEAF, NW_REF), nwkRefSupNode2.getName(),
+                   is(NW_REF));
+        assertThat(getInCrtLeafValue(NW_REF, NW_REF_2),
+                   nwkRefSupNode2.getValue(), is(NW_REF_2));
+
+        YdtContext nodeRefSupNode2 = nwkRefSupNode2.getNextSibling();
+        assertThat(getInCrtName(LEAF, NODE_REF), nodeRefSupNode2.getName(),
+                   is(NODE_REF));
+        assertThat(getInCrtLeafValue(NODE_REF, NW_REF_2),
+                   nwkRefSupNode2.getValue(), is(NW_REF_2));
+
+        // Checks the node list content 2 under network list.
+        YdtContext node2 = node1.getNextSibling();
+        assertThat(getInCrtName(LIST, NODE), node2.getName(), is(NODE));
+
+        // Checks the node-id leaf for list content 2.
+        YdtContext nodeId2 = node2.getFirstChild();
+        assertThat(getInCrtName(LEAF, NODE_ID), nodeId2.getName(), is(NODE_ID));
+        assertThat(getInCrtLeafValue(NODE_ID, NODE_REF_3B), nodeId2.getValue(),
+                   is(NODE_REF_3B));
+
+        // Checks supporting term point list content1 from term list content 2.
+        YdtContext supNode3 = nodeId2.getNextSibling();
+        assertThat(getInCrtName(LIST, SUP_NODE), supNode3.getName(),
+                   is(SUP_NODE));
+
+        YdtContext nwkRefSupNode3 = supNode3.getFirstChild();
+        assertThat(getInCrtName(LEAF, NW_REF), nwkRefSupNode3.getName(),
+                   is(NW_REF));
+        assertThat(getInCrtLeafValue(NW_REF, NW_REF_B),
+                   nwkRefSupNode3.getValue(), is(NW_REF_B));
+
+        YdtContext nodeRefSupNode3 = nwkRefSupNode3.getNextSibling();
+        assertThat(getInCrtName(LEAF, NODE_REF), nodeRefSupNode3.getName(),
+                   is(NODE_REF));
+        assertThat(getInCrtLeafValue(NODE_REF, NODE_REF_B),
+                   nodeRefSupNode3.getValue(), is(NODE_REF_B));
+
+        // Checks supporting term point list content2 from term list content 2.
+        YdtContext supNode4 = supNode3.getNextSibling();
+        assertThat(getInCrtName(LIST, SUP_NODE), supNode4.getName(),
+                   is(SUP_NODE));
+
+        YdtContext nwkRefSupNode4 = supNode4.getFirstChild();
+        assertThat(getInCrtName(LEAF, NW_REF), nwkRefSupNode4.getName(),
+                   is(NW_REF));
+        assertThat(getInCrtLeafValue(NW_REF, NW_REF_2B),
+                   nwkRefSupNode4.getValue(), is(NW_REF_2B));
+
+        YdtContext nodeRefSupNode4 = nwkRefSupNode4.getNextSibling();
+        assertThat(getInCrtName(LEAF, NODE_REF), nodeRefSupNode4.getName(),
+                   is(NODE_REF));
+        assertThat(getInCrtLeafValue(NODE_REF, NODE_REF_2B),
+                   nodeRefSupNode4.getValue(), is(NODE_REF_2B));
+    }
+
+    /**
+     * Processes inter file augment with rpc output as its target node.
+     */
+    @Test
+    public void processInterFileAugmentWithRpcInputAsTarget() {
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // Builds RPC request tree in YDT.
+        YangRequestWorkBench workBench =
+                buildYangRequestWorkBenchForRpc(registry);
+
+        // Creates augment code object.
+
+        // Creates the list of value in, case value in.
+        ValueIn valuein1 = new org.onosproject.yang.gen.v1.yms.test.ytb.augment
+                .yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput
+                .activatesoftwareimage.output.augmentedrpcoutput.selection
+                .valuein.DefaultValueIn.ValueInBuilder().kinetic(KIN1)
+                .build();
+        ValueIn valuein2 = new org.onosproject.yang.gen.v1.yms.test.ytb.augment
+                .yangautoprefixfor.rpc.input.rev20160826.ytbaugmentforrpcinput
+                .activatesoftwareimage.output.augmentedrpcoutput.selection
+                .valuein.DefaultValueIn.ValueInBuilder().kinetic(KIN2)
+                .build();
+
+        List<ValueIn> valueInList = new ArrayList<>();
+        valueInList.add(valuein1);
+        valueInList.add(valuein2);
+
+        // Adds the case value into the choice interface.
+        Selection selection = new DefaultValueIn.ValueInBuilder()
+                .valueIn(valueInList).build();
+
+        // Augment is created for the object.
+        AugmentedRpcOutput augmentRpcOutput = new DefaultAugmentedRpcOutput
+                .AugmentedRpcOutputBuilder().selection(selection).build();
+
+        // Create two list object of friction.
+        Friction friction1 = new DefaultFriction.FrictionBuilder()
+                .speed(BigInteger.valueOf(500)).build();
+        Friction friction2 = new DefaultFriction.FrictionBuilder()
+                .speed(BigInteger.valueOf(1000)).build();
+
+        List<Friction> fricList = new ArrayList<>();
+        fricList.add(friction1);
+        fricList.add(friction2);
+
+        // Create augment with the friction object created.
+        AugmentedInputOutput augmentedIO = new DefaultAugmentedInputOutput
+                .AugmentedInputOutputBuilder().friction(fricList).build();
+
+        // Creates RPC object.
+        List<OutputList> outputLists = createApplicationBuiltObjectForRpc();
+
+        // Adds the augment and the rps output values into the output.
+        DefaultActivateSoftwareImageOutput
+                .ActivateSoftwareImageOutputBuilder output =
+                new DefaultActivateSoftwareImageOutput
+                        .ActivateSoftwareImageOutputBuilder();
+        output.addYangAugmentedInfo(augmentRpcOutput, AugmentedRpcOutput.class);
+        output.addYangAugmentedInfo(augmentedIO, AugmentedInputOutput.class);
+        output.outputList(outputLists);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtForRpcResponse(
+                output, workBench);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+        assertThat(getInCrtName(ROOT, RPC_ADV_NAME), context.getName(),
+                   is(RPC_ADV_NAME));
+        assertThat(getInCrtName(ROOT, RPC_ADV_NAMESPACE),
+                   context.getNamespace(), is(RPC_ADV_NAMESPACE));
+
+        // Checks the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        assertThat(getInCrtName(MODULE, RPC_ADV_IO), module.getName(),
+                   is(RPC_ADV_IO));
+
+        // Gets the rpc under module.
+        YdtContext rpc = module.getFirstChild();
+        assertThat(getInCrtName(RPC, ACT_IMG), rpc.getName(), is(ACT_IMG));
+
+        // Gets the output value under rpc.
+        // TODO: Change assert after YANG utils is merged.
+        YdtContext rpcOutputNode = rpc.getFirstChild();
+        //assertThat(rpcOutputNode.getName(), is("output"));
+
+        YdtContext firstNode = rpcOutputNode.getFirstChild();
+        assertThat(firstNode, notNullValue());
+
+        YdtContext secondNode = firstNode.getNextSibling();
+        assertThat(secondNode, notNullValue());
+
+        YdtContext thirdNode = secondNode.getNextSibling();
+        assertThat(thirdNode, notNullValue());
+
+        YdtContext fourthNode = thirdNode.getNextSibling();
+        assertThat(fourthNode, notNullValue());
+
+        // Gets the list content 1 as the node from output.
+        YdtContext outputList1 = fourthNode.getNextSibling();
+        assertThat(getInCrtName(LIST, OUTPUT_LIST), outputList1.getName(),
+                   is(OUTPUT_LIST));
+
+        // Gets the leaf key-list from list content1.
+        YdtContext keyList1 = outputList1.getFirstChild();
+        assertThat(getInCrtName(LEAF, LIST_KEY), keyList1.getName(),
+                   is(LIST_KEY));
+        assertThat(getInCrtLeafValue(LIST_KEY, BIN_VAL_1), keyList1.getValue(),
+                   is(BIN_VAL_1));
+
+        // Gets the content inside container from list content 1.
+        YdtContext cont1 = keyList1.getNextSibling();
+        assertThat(getInCrtName(CONTAINER, CONT_INSIDE), cont1.getName(),
+                   is(CONT_INSIDE));
+
+        // Gets the list content 2 as the node from output.
+        YdtContext outputList2 = outputList1.getNextSibling();
+        assertThat(getInCrtName(LIST, OUTPUT_LIST), outputList2.getName(),
+                   is(OUTPUT_LIST));
+
+        // Gets the leaf-list key-list from list content2.
+        YdtContext keyList2 = outputList2.getFirstChild();
+        assertThat(getInCrtName(LEAF, LIST_KEY), keyList2.getName(),
+                   is(LIST_KEY));
+        assertThat(getInCrtLeafValue(LIST_KEY, BIN_VAL_2), keyList2.getValue(),
+                   is(BIN_VAL_2));
+
+        // Gets the content inside container from list content 2.
+        YdtContext cont2 = keyList2.getNextSibling();
+        assertThat(getInCrtName(CONTAINER, CONT_INSIDE), cont2.getName(),
+                   is(CONT_INSIDE));
+
+        // Gets the leaf-list available inside container.
+        YdtContext availLeafList = cont2.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, AVAILABLE), availLeafList.getName(),
+                   is(AVAILABLE));
+        Set value1 = availLeafList.getValueSet();
+        assertThat(getInCrtLeafListValue(AVAILABLE, EIGHTY_NINE),
+                   value1.contains(EIGHTY_NINE), is(true));
+        assertThat(getInCrtLeafListValue(AVAILABLE, NINETY_EIGHT),
+                   value1.contains(NINETY_EIGHT), is(true));
+
+        // Gets the list content 3.
+        YdtContext outputList3 = outputList2.getNextSibling();
+        assertThat(getInCrtName(LIST, OUTPUT_LIST), outputList3.getName(),
+                   is(OUTPUT_LIST));
+
+        // Gets the leaf list-key in content 3 of list.
+        YdtContext keyList3 = outputList3.getFirstChild();
+        assertThat(getInCrtName(LEAF, LIST_KEY), keyList3.getName(),
+                   is(LIST_KEY));
+        assertThat(getInCrtLeafValue(LIST_KEY, BIN_VAL_3), keyList3.getValue(),
+                   is(BIN_VAL_3));
+    }
+}
