diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilderTest.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilderTest.java
new file mode 100644
index 0000000..b7bec31
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilderTest.java
@@ -0,0 +1,1127 @@
+/*
+ * 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.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onosproject.yang.gen.v1.yms.test.ytb.derived.type.with.bits.and.binary.rev20160826.YtbDerivedTypeWithBitsAndBinary;
+import org.onosproject.yang.gen.v1.yms.test.ytb.derived.type.with.bits.and.binary.rev20160826.YtbDerivedTypeWithBitsAndBinaryOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.derived.type.with.bits.and.binary.rev20160826.ytbderivedtypewithbitsandbinary.Derivedbinarya;
+import org.onosproject.yang.gen.v1.yms.test.ytb.derived.type.with.bits.and.binary.rev20160826.ytbderivedtypewithbitsandbinary.Derivedbinaryb;
+import org.onosproject.yang.gen.v1.yms.test.ytb.derived.type.with.bits.and.binary.rev20160826.ytbderivedtypewithbitsandbinary.Derivedbitsa;
+import org.onosproject.yang.gen.v1.yms.test.ytb.derived.type.with.bits.and.binary.rev20160826.ytbderivedtypewithbitsandbinary.Derivedbitsb;
+import org.onosproject.yang.gen.v1.yms.test.ytb.derived.type.with.bits.and.binary.rev20160826.ytbderivedtypewithbitsandbinary.ForunionUnion;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.container.rev20160826.YtbModuleWithContainer;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.container.rev20160826.YtbModuleWithContainerOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.container.rev20160826.ytbmodulewithcontainer.DefaultSched;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.container.rev20160826.ytbmodulewithcontainer.Sched;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.leaf.ietfschedule.rev20160826.YtbIetfSchedule;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.leaf.ietfschedule.rev20160826.YtbIetfScheduleOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.leaf.ietfschedule.rev20160826.ytbietfschedule.Enum1Enum;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.leaf.ietfschedule.rev20160826.ytbietfschedule.Enum2Enum;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.leaflist.rev20160826.YtbModuleWithLeafList;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.leaflist.rev20160826.YtbModuleWithLeafListOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.list.rev20160826.YtbModuleWithList;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.list.rev20160826.YtbModuleWithListOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.list.rev20160826.ytbmodulewithlist.DefaultYtblistlist;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.list.rev20160826.ytbmodulewithlist.Find;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.list.rev20160826.ytbmodulewithlist.Ytblistlist;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.module.a.rev20160826.YtbMultiModulea;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.module.a.rev20160826.YtbMultiModuleaOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.module.a.rev20160826.ytbmultimodulea.DefaultYtbmultilist;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.module.a.rev20160826.ytbmultimodulea.Ytbmultilist;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.module.b.rev20160826.YtbMultiModuleb;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.module.b.rev20160826.YtbMultiModulebOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.module.b.rev20160826.ytbmultimoduleb.DefaultYtbmultilistb;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.module.b.rev20160826.ytbmultimoduleb.Ytbmultilistb;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.notification.with.container.rev20160826.ytbmultinotificationwithcontainer.DefaultFortesta;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.notification.with.container.rev20160826.ytbmultinotificationwithcontainer.Fortesta;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.notification.with.container.rev20160826.ytbmultinotificationwithcontainer.YtbMultiNotificationWithContainerEvent;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.notification.with.container.rev20160826.ytbmultinotificationwithcontainer.YtbMultiNotificationWithContainerEventSubject;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.notification.with.container.rev20160826.ytbmultinotificationwithcontainer.fortesta.DefaultYtbnot;
+import org.onosproject.yang.gen.v1.yms.test.ytb.multi.notification.with.container.rev20160826.ytbmultinotificationwithcontainer.fortesta.Ytbnot;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.list.having.list.rev20160826.YtbTreeBuilderForListHavingList;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.list.having.list.rev20160826.YtbTreeBuilderForListHavingListOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.list.having.list.rev20160826.ytbtreebuilderforlisthavinglist.Carrier;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.list.having.list.rev20160826.ytbtreebuilderforlisthavinglist.DefaultCarrier;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.list.having.list.rev20160826.ytbtreebuilderforlisthavinglist.carrier.DefaultMultiplexes;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.list.having.list.rev20160826.ytbtreebuilderforlisthavinglist.carrier.Multiplexes;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.list.having.list.rev20160826.ytbtreebuilderforlisthavinglist.carrier.multiplexes.ApplicationAreas;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.list.having.list.rev20160826.ytbtreebuilderforlisthavinglist.carrier.multiplexes.DefaultApplicationAreas;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.list.having.list.rev20160826.ytbtreebuilderforlisthavinglist.carrier.multiplexes.TypesEnum;
+import org.onosproject.yms.app.ydt.YdtExtendedBuilder;
+import org.onosproject.yms.app.ydt.YdtNode;
+import org.onosproject.yms.app.ysr.DefaultYangSchemaRegistry;
+import org.onosproject.yms.ydt.YdtBuilder;
+import org.onosproject.yms.ydt.YdtContext;
+import org.onosproject.yms.ydt.YdtContextOperationType;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yang.gen.v1.yms.test.ytb.module.with.leaf.ietfschedule.rev20160826.YtbIetfScheduleOpParam.OnosYangNodeOperationType;
+import static org.onosproject.yms.ydt.YdtContextOperationType.CREATE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.MERGE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.NONE;
+import static org.onosproject.yms.ydt.YmsOperationType.EDIT_CONFIG_REQUEST;
+import static org.onosproject.yms.ydt.YmsOperationType.QUERY_CONFIG_REQUEST;
+import static org.onosproject.yms.ydt.YmsOperationType.QUERY_REQUEST;
+
+/**
+ * Unit test cases for YANG tree builder with different YANG object
+ * configuration.
+ */
+public class DefaultYangTreeBuilderTest extends YtbErrMsgAndConstants {
+
+
+    private static final String ONE = "1";
+    private static final String TWO = "2";
+    private static final String THREE = "3";
+    private static final String FOUR = "4";
+    private static final String FIVE = "5";
+    private static final String SIX = "6";
+    private static final String NINE = "9";
+    private static final String IETF_SCHEDULE = "YtbIetfSchedule";
+    private static final String TIME = "time";
+    private static final String MOD_LEAF_LIST = "YtbModuleWithLeafList";
+    private static final String ENUM_1 = "enum1";
+    private static final String ENUM_2 = "enum2";
+    private static final String HUNDRED = "hundred";
+    private static final String HUNDRED_100 = "hundred-100";
+    private static final String TEN_10 = "ten-10";
+    private static final String THOUSAND_1000 = "thousand-1000";
+    private static final String MOD_CONT = "YtbModuleWithContainer";
+    private static final String SCHED = "sched";
+    private static final String PREDICT_VAL = "98989";
+    private static final String MOD_LIST = "YtbModuleWithList";
+    private static final String LIST_LIST = "ytblistlist";
+    private static final String PREDICTION = "prediction";
+    private static final String TRUE = "true";
+    private static final String FALSE = "false";
+    private static final String MUL_NOTIFY =
+            "YtbMultiNotificationWithContainer";
+    private static final String NOTIFICATION = "notification";
+    private static final String NOTIFY = "fortesta";
+    private static final String YTB_NOTIFY_CONT = "ytbnot";
+    private static final String NOTIFY_LEAF = "notileaf";
+    private static final String ANT = "ant";
+    private static final String ANIMAL = "animal";
+    private static final String BIRD = "bird";
+    private static final String BALL = "ball";
+    private static final String BAT = "bat";
+    private static final String MUL_MOD_A = "YtbMultiModulea";
+    private static final String MUL_LIST_A = "ytbmultilist";
+    private static final String CHECK = "check";
+    private static final String MUL_MOD_B = "YtbMultiModuleb";
+    private static final String MUL_LIST_B = "ytbmultilistb";
+    private static final String CHECKIN = "checkin";
+    private static final String LIST_WITH_LIST =
+            "YtbTreeBuilderForListHavingList";
+    private static final String CONT_CARRIER = "carrier";
+    private static final String LIST_MULTIPLEXES = "multiplexes";
+    private static final String TYPES = "types";
+    private static final String TIME_DIVISION = "time-division";
+    private static final String APP_AREA_LIST = "application-areas";
+    private static final String DEST_AREA = "destination-areas";
+    private static final String FREQUENCY_DIV = "frequency-division";
+    private static final String MOD_BIT_BIN = "YtbDerivedTypeWithBitsAndBinary";
+    private static final String FOR_BINARY = "forbinary";
+    private static final String BIN_VAL_1 = "BQUF";
+    private static final String FOR_BITS = "forbits";
+    private static final String FOR_BINARY_LIST = "forbinarylist";
+    private static final String BIN_VAL_2 = "CQkA";
+    private static final String BIN_VAL_3 = "DAYA";
+    private static final String BIN_VAL_4 = "EB0Z";
+    private static final String FOR_BITS_LIST = "forbitslist";
+    private static final String FOR_UNION = "forunion";
+    private static final String ZERO = "0";
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    private static String emptyObjErrMsg(String objName) {
+        return "The " + objName + " given for tree creation cannot be null";
+    }
+
+    private static BigDecimal getBigDeci(int bigDecimal) {
+        return BigDecimal.valueOf(bigDecimal);
+    }
+
+    /**
+     * Processes an empty object list to the YTB and checks that the
+     * exception is thrown.
+     */
+    @Test
+    public void processInvalidListInput() {
+        thrown.expect(YtbException.class);
+        thrown.expectMessage(emptyObjErrMsg("object list"));
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        treeBuilder.getYdtBuilderForYo(null, ROOT_NAME, ROOT_NAME_SPACE,
+                                       EDIT_CONFIG_REQUEST, null);
+    }
+
+    /**
+     * Processes an empty notification object to the YTB and checks that the
+     * exception is thrown.
+     */
+    @Test
+    public void processInvalidInputForNotification() {
+        thrown.expect(YtbException.class);
+        thrown.expectMessage(emptyObjErrMsg("event object"));
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        treeBuilder.getYdtForNotification(null, ROOT_NAME, null);
+    }
+
+    /**
+     * Processes an empty rpc output object to the YTB and checks that the
+     * exception is thrown.
+     */
+    @Test
+    public void processInvalidInputForRpc() {
+        thrown.expect(YtbException.class);
+        thrown.expectMessage(emptyObjErrMsg("output object"));
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        treeBuilder.getYdtForRpcResponse(null, null);
+    }
+
+    /**
+     * Processes a YAB/YSB request to YTB with a leaf value being filled in
+     * the app object. Checks the constructed YDT tree for module and leaf
+     * and its value.
+     */
+    @Test
+    public void processModuleAndLeaf() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+        YtbIetfSchedule schedule = new YtbIetfScheduleOpParam
+                .YtbIetfScheduleBuilder()
+                .time((byte) 9)
+                .onosYangNodeOperationType(OnosYangNodeOperationType.MERGE)
+                .build();
+
+        // As YSB or YAB protocol sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(schedule);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, ROOT_NAME, ROOT_NAME_SPACE,
+                EDIT_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and checks the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        YdtContextOperationType opType = ((YdtNode) module)
+                .getYdtContextOperationType();
+        assertThat(getInCrtName(MODULE, IETF_SCHEDULE),
+                   module.getName(), is(IETF_SCHEDULE));
+        assertThat(getInCrtOpType(MODULE, IETF_SCHEDULE),
+                   opType, is(MERGE));
+
+        // Gets the first leaf from module IetfSchedule.
+        YdtContext leafContext = module.getFirstChild();
+        assertThat(getInCrtName(LEAF, TIME),
+                   leafContext.getName(), is(TIME));
+        assertThat(getInCrtLeafValue(TIME, NINE),
+                   leafContext.getValue(), is(NINE));
+    }
+
+    /**
+     * Processes a YAB/YSB request to YTB with a leaf-list value being filled
+     * in the app object. Checks the constructed YDT tree for module and
+     * leaf-list and its value.
+     */
+    @Test
+    public void processModuleAndLeafList() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates list of type long for setting the leaf-list.
+        List<Long> longList = new ArrayList<>();
+        longList.add((long) 1);
+        longList.add((long) 2);
+        longList.add((long) 3);
+
+        YtbModuleWithLeafList leafListModule = new YtbModuleWithLeafListOpParam
+                .YtbModuleWithLeafListBuilder().time(longList).build();
+
+        // As YSB or YAB protocol sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(leafListModule);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, ROOT_NAME, ROOT_NAME_SPACE, QUERY_REQUEST, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        YdtContextOperationType opType = ((YdtNode) module)
+                .getYdtContextOperationType();
+        assertThat(getInCrtName(MODULE, MOD_LEAF_LIST),
+                   module.getName(), is(MOD_LEAF_LIST));
+        assertThat(getInCrtOpType(MODULE, MOD_LEAF_LIST), opType, is(NONE));
+
+        // Gets the first leaf-list from module.
+        YdtContext leafList = module.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, TIME), leafList.getName(),
+                   is(TIME));
+        Set<String> value = leafList.getValueSet();
+        assertThat(getInCrtLeafListValue(TIME, ONE),
+                   value.contains(ONE), is(true));
+        assertThat(getInCrtLeafListValue(TIME, TWO),
+                   value.contains(TWO), is(true));
+        assertThat(getInCrtLeafListValue(TIME, THREE),
+                   value.contains(THREE), is(true));
+    }
+
+    /**
+     * Processes leaf and leaf-list with type enum under module. Checks the
+     * constructed YDT tree has YANG enum value.
+     */
+    @Test
+    public void processWithTypeEnum() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates enum list for setting the leaf-list.
+        List<Enum2Enum> enumList = new ArrayList<>();
+        enumList.add(Enum2Enum.HUNDRED_100);
+        enumList.add(Enum2Enum.TEN_10);
+        enumList.add(Enum2Enum.THOUSAND_1000);
+
+        YtbIetfSchedule schedule = new YtbIetfScheduleOpParam
+                .YtbIetfScheduleBuilder()
+                .time((byte) 9)
+                .onosYangNodeOperationType(OnosYangNodeOperationType.MERGE)
+                .enum1(Enum1Enum.HUNDRED)
+                .enum2(enumList)
+                .build();
+
+
+        // As YSB or YAB protocol sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(schedule);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, ROOT_NAME, ROOT_NAME_SPACE,
+                EDIT_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        YdtContextOperationType opType =
+                ((YdtNode) module).getYdtContextOperationType();
+        assertThat(getInCrtName(MODULE, IETF_SCHEDULE),
+                   module.getName(), is(IETF_SCHEDULE));
+        assertThat(getInCrtOpType(MODULE, IETF_SCHEDULE), opType, is(MERGE));
+
+        // Checks the leaf and leaf-list values.
+        YdtContext timeLeaf = module.getFirstChild();
+        assertThat(getInCrtName(LEAF, TIME), timeLeaf.getName(), is(TIME));
+        assertThat(getInCrtLeafValue(TIME, NINE),
+                   timeLeaf.getValue(), is(NINE));
+
+        YdtContext enum1Leaf = timeLeaf.getNextSibling();
+        assertThat(getInCrtName(LEAF, ENUM_1), enum1Leaf.getName(), is(ENUM_1));
+        assertThat(getInCrtLeafValue(ENUM_1, HUNDRED),
+                   enum1Leaf.getValue(), is(HUNDRED));
+
+        YdtContext enum2LeafList = enum1Leaf.getNextSibling();
+        assertThat(getInCrtName(LEAF_LIST, ENUM_2),
+                   enum2LeafList.getName(), is(ENUM_2));
+        Set<String> valueSet = enum2LeafList.getValueSet();
+        assertThat(getInCrtLeafListValue(ENUM_2, HUNDRED_100),
+                   valueSet.contains(HUNDRED_100), is(true));
+        assertThat(getInCrtLeafListValue(ENUM_2, TEN_10),
+                   valueSet.contains(TEN_10), is(true));
+        assertThat(getInCrtLeafListValue(ENUM_2, THOUSAND_1000),
+                   valueSet.contains(THOUSAND_1000), is(true));
+    }
+
+    /**
+     * Processes a YAB/YSB request to YTB with a container having leaf value
+     * being filled in the app object. Checks the constructed YDT tree for
+     * module and container and leaf.
+     */
+    @Test
+    public void processModuleWithContainer() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates container object with leaf of decimal type.
+        Sched sched = new DefaultSched.SchedBuilder()
+                .predict(getBigDeci(98989))
+                .onosYangNodeOperationType(
+                        DefaultSched.OnosYangNodeOperationType.DELETE)
+                .build();
+        // Creates module object with the container.
+        YtbModuleWithContainer contModule = new YtbModuleWithContainerOpParam
+                .YtbModuleWithContainerBuilder()
+                .sched(sched)
+                .onosYangNodeOperationType(
+                        YtbModuleWithContainerOpParam
+                                .OnosYangNodeOperationType.CREATE)
+                .build();
+
+        // As YSB or YAB protocol sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(contModule);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, ROOT_NAME, ROOT_NAME_SPACE,
+                QUERY_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        YdtContextOperationType opType = ((YdtNode) module)
+                .getYdtContextOperationType();
+
+        assertThat(getInCrtName(MODULE, MOD_CONT),
+                   module.getName(), is(MOD_CONT));
+        assertThat(getInCrtOpType(MODULE, MOD_CONT), opType, is(CREATE));
+
+        // Get the container from module.
+        YdtContext container = module.getFirstChild();
+        YdtContextOperationType opTypeOfCont = ((YdtNode) container)
+                .getYdtContextOperationType();
+
+        assertThat(getInCrtName(CONTAINER, SCHED),
+                   container.getName(), is("sched"));
+        assertThat(getInCrtOpType(CONTAINER, SCHED), opTypeOfCont, is(DELETE));
+
+        // Gets leaf from container.
+        YdtContext leafContext = container.getFirstChild();
+        assertThat(getInCrtName(LEAF, PREDICT),
+                   leafContext.getName(), is(PREDICT));
+        assertThat(getInCrtLeafValue(PREDICT, PREDICT_VAL),
+                   leafContext.getValue(), is(PREDICT_VAL));
+    }
+
+    /**
+     * Processes a YAB/YSB request to YTB with a list having leaf-list value
+     * being filled in the app object. Checks the constructed YDT tree for
+     * module and list and leaf-list.
+     */
+    @Test
+    public void processModuleWithList() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates multi typedef values.
+        Find find1 = new Find(true);
+        Find find2 = new Find(false);
+        Find find3 = new Find(true);
+        Find find4 = new Find(false);
+
+        // Creates two lists, with the typedef values added.
+        List<Find> findList1 = new ArrayList<>();
+        List<Find> findList2 = new ArrayList<>();
+        findList1.add(find1);
+        findList1.add(find2);
+        findList2.add(find3);
+        findList2.add(find4);
+
+        // Creates two list contents.
+        Ytblistlist list1 = new DefaultYtblistlist
+                .YtblistlistBuilder().prediction(findList1).build();
+        Ytblistlist list2 = new DefaultYtblistlist
+                .YtblistlistBuilder().prediction(findList2).build();
+
+        List<Ytblistlist> ytbList = new ArrayList<>();
+        ytbList.add(list1);
+        ytbList.add(list2);
+
+        // Creates module having list.
+        YtbModuleWithList listModule = new YtbModuleWithListOpParam
+                .YtbModuleWithListBuilder().ytblistlist(ytbList).build();
+
+        // As YSB or YAB protocol sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(listModule);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, ROOT_NAME, ROOT_NAME_SPACE,
+                EDIT_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        YdtContextOperationType opType = ((YdtNode) module)
+                .getYdtContextOperationType();
+
+        assertThat(getInCrtName(MODULE, MOD_LIST),
+                   module.getName(), is(MOD_LIST));
+        assertThat(getInCrtOpType(MODULE, MOD_LIST), opType, is(NONE));
+
+        // Gets the first list from module YtbModuleWithList.
+        YdtContext firstList = module.getFirstChild();
+        YdtContextOperationType listOpType = ((YdtNode) firstList)
+                .getYdtContextOperationType();
+        // Checks the contents in the list.
+        assertThat(getInCrtName(LIST, LIST_LIST),
+                   firstList.getName(), is(LIST_LIST));
+        assertThat(getInCrtOpType(LIST, LIST_LIST), listOpType, is(NONE));
+
+        // Gets the contents of the leaf-list in the first list content.
+        YdtContext leafListInList1 = firstList.getFirstChild();
+
+        // Evaluates the leaf-list values.
+        Set leafListValue1 = leafListInList1.getValueSet();
+        assertThat(getInCrtName(LEAF_LIST, PREDICTION),
+                   leafListInList1.getName(), is(PREDICTION));
+        assertThat(getInCrtLeafListValue(PREDICTION, TRUE),
+                   leafListValue1.contains(TRUE), is(true));
+        assertThat(getInCrtLeafListValue(PREDICTION, FALSE),
+                   leafListValue1.contains(FALSE), is(true));
+
+        // Gets the second list from module YtbModuleWithList.
+        YdtContext secondList = firstList.getNextSibling();
+
+        // Gets the contents of the leaf-list in the second list content.
+        YdtContext leafListInList2 = secondList.getFirstChild();
+        // Evaluates the leaf-list values.
+        Set leafListValue2 = leafListInList2.getValueSet();
+        assertThat(getInCrtName(LEAF_LIST, PREDICTION),
+                   leafListInList2.getName(), is(PREDICTION));
+        assertThat(getInCrtLeafListValue(PREDICTION, TRUE),
+                   leafListValue2.contains(TRUE), is(true));
+        assertThat(getInCrtLeafListValue(PREDICTION, FALSE),
+                   leafListValue2.contains(FALSE), is(true));
+    }
+
+    /**
+     * Processes multi notification under module when request comes for one
+     * notification event in module.
+     */
+    @Test
+    public void processMultiNotificationWithContainer() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Sets the bit value.
+        BitSet bitleaf = new BitSet();
+        bitleaf.set(5);
+        bitleaf.set(7);
+
+        // Creates container with the leaf.
+        Ytbnot ytbnot = new DefaultYtbnot.YtbnotBuilder().notileaf(bitleaf)
+                .build();
+        // Creates notification with container.
+        Fortesta testa = new DefaultFortesta.FortestaBuilder()
+                .ytbnot(ytbnot).build();
+        // Invokes event subject class with notification.
+        YtbMultiNotificationWithContainerEventSubject eventSubject = new
+                YtbMultiNotificationWithContainerEventSubject();
+        eventSubject.fortesta(testa);
+        // Invokes event class with the event type and the event subject obj.
+        YtbMultiNotificationWithContainerEvent event =
+                new YtbMultiNotificationWithContainerEvent(
+                        YtbMultiNotificationWithContainerEvent.Type.FORTESTA,
+                        eventSubject);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtContext ydtContext = treeBuilder.getYdtForNotification(
+                event, ROOT_NAME, registry);
+
+        // Gets the first module from logical root node.
+        YdtContext context = ydtContext.getFirstChild();
+        YdtContextOperationType opType = ((YdtNode) context)
+                .getYdtContextOperationType();
+
+        assertThat(getInCrtName(MODULE, MUL_NOTIFY), context.getName(),
+                   is(MUL_NOTIFY));
+        assertThat(getInCrtOpType(MODULE, MUL_NOTIFY), opType, is(NONE));
+
+        // Gets the notification under module.
+        YdtContext notify = context.getFirstChild();
+        YdtContextOperationType notifyOpType = ((YdtNode) notify)
+                .getYdtContextOperationType();
+
+        // Checks the contents in the first notification.
+        assertThat(getInCrtName(NOTIFICATION, NOTIFY), notify.getName(),
+                   is(NOTIFY));
+        assertThat(getInCrtOpType(NOTIFICATION, NOTIFY), notifyOpType,
+                   is(NONE));
+
+        // Gets the container in notification
+        YdtContext container = notify.getFirstChild();
+        assertThat(getInCrtName(CONTAINER, YTB_NOTIFY_CONT),
+                   container.getName(), is(YTB_NOTIFY_CONT));
+
+        // Evaluates the leaf values.
+        YdtContext leafInCont = container.getFirstChild();
+        assertThat(getInCrtName(LEAF, NOTIFY_LEAF), leafInCont.getName(),
+                   is(NOTIFY_LEAF));
+        // TODO: check the bits to string.
+    }
+
+    /**
+     * Processes multi module with list in both the modules and checks the
+     * YANG data tree building.
+     */
+    @Test
+    public void processMultiModule() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates list of big integer for leaf-list under list1.
+        List<BigInteger> bigIntegerList = new ArrayList<>();
+        bigIntegerList.add(BigInteger.valueOf(1));
+        bigIntegerList.add(BigInteger.valueOf(2));
+        bigIntegerList.add(BigInteger.valueOf(3));
+        // Creates list of big integer for leaf-list under list2.
+        List<BigInteger> bigIntegerList1 = new ArrayList<>();
+        bigIntegerList1.add(BigInteger.valueOf(4));
+        bigIntegerList1.add(BigInteger.valueOf(5));
+        bigIntegerList1.add(BigInteger.valueOf(6));
+
+        // Creates two list contents.
+        Ytbmultilist listContent1 = new DefaultYtbmultilist
+                .YtbmultilistBuilder().check(bigIntegerList).build();
+        Ytbmultilist listContent2 = new DefaultYtbmultilist
+                .YtbmultilistBuilder().check(bigIntegerList1).build();
+
+        List<Ytbmultilist> ytbmultilists = new ArrayList<>();
+        ytbmultilists.add(listContent1);
+        ytbmultilists.add(listContent2);
+
+        // Creates module-a with two list contents created.
+        YtbMultiModulea modulea = new YtbMultiModuleaOpParam
+                .YtbMultiModuleaBuilder().ytbmultilist(ytbmultilists).build();
+
+        // Creates list of string for leaf-list under list1.
+        List<String> stringList = new ArrayList<>();
+        stringList.add(ANT);
+        stringList.add(ANIMAL);
+        stringList.add(BIRD);
+
+        // Creates list of string for leaf-list under list2.
+        List<String> stringList1 = new ArrayList<>();
+        stringList1.add(CATCH);
+        stringList1.add(BALL);
+        stringList1.add(BAT);
+
+        // Creates two list contents.
+        Ytbmultilistb listContent3 = new DefaultYtbmultilistb
+                .YtbmultilistbBuilder().checkin(stringList).build();
+        Ytbmultilistb listContent4 = new DefaultYtbmultilistb
+                .YtbmultilistbBuilder().checkin(stringList1).build();
+
+        List<Ytbmultilistb> ytbMultiListb = new ArrayList<>();
+        ytbMultiListb.add(listContent3);
+        ytbMultiListb.add(listContent4);
+
+        // Creates module-b with two list contents created.
+        YtbMultiModuleb moduleb = new YtbMultiModulebOpParam
+                .YtbMultiModulebBuilder().ytbmultilistb(ytbMultiListb).build();
+
+        // As YSB or YAB protocol sets the value for YTB.
+        List<Object> listOfModules = new ArrayList<>();
+        listOfModules.add(modulea);
+        listOfModules.add(moduleb);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                listOfModules, ROOT_NAME, ROOT_NAME_SPACE,
+                EDIT_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+
+        // Checks module-a under root node.
+        YdtContext moduleA = context.getFirstChild();
+        assertThat(getInCrtName(MODULE, MUL_MOD_A), moduleA.getName(),
+                   is(MUL_MOD_A));
+
+        // Checks list-a in module-a and its respective leaf-list.
+        YdtContext list1InModuleA = moduleA.getFirstChild();
+        assertThat(getInCrtName(LIST, MUL_LIST_A), list1InModuleA.getName(),
+                   is(MUL_LIST_A));
+
+        YdtContext leafListA = list1InModuleA.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, CHECK), leafListA.getName(),
+                   is(CHECK));
+
+        Set<String> valueA = leafListA.getValueSet();
+        assertThat(getInCrtLeafListValue(CHECK, ONE), valueA.contains(ONE),
+                   is(true));
+        assertThat(getInCrtLeafListValue(CHECK, TWO), valueA.contains(TWO),
+                   is(true));
+        assertThat(getInCrtLeafListValue(CHECK, THREE), valueA.contains(THREE),
+                   is(true));
+
+        // Checks list-b in module-a and its respective leaf-list.
+        YdtContext list2InModuleA = list1InModuleA.getNextSibling();
+        assertThat(getInCrtName(LIST, MUL_LIST_A), list2InModuleA.getName(),
+                   is(MUL_LIST_A));
+
+        YdtContext leafListB = list2InModuleA.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, CHECK), leafListB.getName(),
+                   is(CHECK));
+
+        Set<String> valueB = leafListB.getValueSet();
+        assertThat(getInCrtLeafListValue(CHECK, FOUR), valueB.contains(FOUR),
+                   is(true));
+        assertThat(getInCrtLeafListValue(CHECK, FIVE), valueB.contains(FIVE),
+                   is(true));
+        assertThat(getInCrtLeafListValue(CHECK, SIX), valueB.contains(SIX),
+                   is(true));
+
+        // Checks module-b under root node.
+        YdtContext moduleB = moduleA.getNextSibling();
+        assertThat(getInCrtName(MODULE, MUL_MOD_B), moduleB.getName(),
+                   is(MUL_MOD_B));
+
+        // Checks list-a in module-b and its respective leaf-list.
+        YdtContext list1InModuleB = moduleB.getFirstChild();
+        assertThat(getInCrtName(LIST, MUL_LIST_B), list1InModuleB.getName(),
+                   is(MUL_LIST_B));
+
+        YdtContext leafListC = list1InModuleB.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, CHECKIN), leafListC.getName(),
+                   is(CHECKIN));
+
+        Set<String> valueC = leafListC.getValueSet();
+        assertThat(getInCrtLeafListValue(CHECKIN, ANT), valueC.contains(ANT),
+                   is(true));
+        assertThat(getInCrtLeafListValue(CHECKIN, ANIMAL),
+                   valueC.contains(ANIMAL), is(true));
+        assertThat(getInCrtLeafListValue(CHECKIN, BIRD),
+                   valueC.contains(BIRD), is(true));
+
+        // Checks list-b in module-b and its respective leaf-list.
+        YdtContext list2InModuleB = list1InModuleB.getNextSibling();
+        assertThat(getInCrtName(LIST, MUL_LIST_B), list2InModuleB.getName(),
+                   is(MUL_LIST_B));
+
+        YdtContext leafListD = list2InModuleB.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, CHECKIN), leafListD.getName(),
+                   is(CHECKIN));
+
+        Set<String> valueD = leafListD.getValueSet();
+        assertThat(getInCrtLeafListValue(CHECKIN, CATCH),
+                   valueD.contains(CATCH), is(true));
+        assertThat(getInCrtLeafListValue(CHECKIN, BALL),
+                   valueD.contains(BALL), is(true));
+        assertThat(getInCrtLeafListValue(CHECKIN, BAT),
+                   valueD.contains(BAT), is(true));
+    }
+
+    /**
+     * Processes tree building when a list node is having list inside it.
+     */
+    @Test
+    public void processTreeBuilderForListHavingList() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates two binary leaf-lists for two list app areas.
+        List<byte[]> destArea1 = new ArrayList<>();
+        byte[] arr = new byte[]{1, 6, 3};
+        byte[] arr1 = new byte[]{2, 7, 4};
+        destArea1.add(arr);
+        destArea1.add(arr1);
+
+        List<byte[]> destArea2 = new ArrayList<>();
+        byte[] arr2 = new byte[]{3, 8, 4};
+        byte[] arr3 = new byte[]{5, 6, 1};
+        destArea2.add(arr2);
+        destArea2.add(arr3);
+
+        // Creates two app areas list.
+        ApplicationAreas appArea1 = new DefaultApplicationAreas
+                .ApplicationAreasBuilder().destinationAreas(destArea1).build();
+        ApplicationAreas appArea2 = new DefaultApplicationAreas
+                .ApplicationAreasBuilder().destinationAreas(destArea2).build();
+
+        List<ApplicationAreas> applicationAreasList = new ArrayList<>();
+        applicationAreasList.add(appArea1);
+        applicationAreasList.add(appArea2);
+
+        // Adds two lists under the multiplex list for content 1.
+        Multiplexes mpx1 = new DefaultMultiplexes.MultiplexesBuilder()
+                .types(TypesEnum.TIME_DIVISION)
+                .applicationAreas(applicationAreasList).build();
+
+        // Creates two binary leaf-lists for two list app areas.
+        List<byte[]> destArea3 = new ArrayList<>();
+        byte[] arrB = new byte[]{0, 0, 1};
+        byte[] arr1B = new byte[]{1, 0, 0};
+        destArea3.add(arrB);
+        destArea3.add(arr1B);
+
+        List<byte[]> destArea4 = new ArrayList<>();
+        byte[] arr2B = new byte[]{7, 7, 7};
+        byte[] arr3B = new byte[]{0, 1};
+        destArea4.add(arr2B);
+        destArea4.add(arr3B);
+
+        // Creates two app areas list.
+        ApplicationAreas appArea3 = new DefaultApplicationAreas
+                .ApplicationAreasBuilder().destinationAreas(destArea3).build();
+        ApplicationAreas appArea4 = new DefaultApplicationAreas
+                .ApplicationAreasBuilder().destinationAreas(destArea4).build();
+
+        List<ApplicationAreas> applicationAreasListB = new ArrayList<>();
+        applicationAreasListB.add(appArea3);
+        applicationAreasListB.add(appArea4);
+
+        // Adds two lists under the multiplex list for content 2.
+        Multiplexes mpx2 = new DefaultMultiplexes.MultiplexesBuilder()
+                .types(TypesEnum.FREQUENCY_DIVISION)
+                .applicationAreas(applicationAreasListB).build();
+
+        List<Multiplexes> multiplexList = new ArrayList<>();
+        multiplexList.add(mpx1);
+        multiplexList.add(mpx2);
+
+        // Sets it in the container carrier.
+        Carrier carrier = new DefaultCarrier.CarrierBuilder()
+                .multiplexes(multiplexList).build();
+
+        YtbTreeBuilderForListHavingList listWithList = new
+                YtbTreeBuilderForListHavingListOpParam
+                        .YtbTreeBuilderForListHavingListBuilder()
+                .carrier(carrier).build();
+
+        // As YSB or YAB protocol sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(listWithList);
+
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, ROOT_NAME, ROOT_NAME_SPACE,
+                QUERY_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        assertThat(getInCrtName(LIST, LIST_WITH_LIST), module.getName(),
+                   is(LIST_WITH_LIST));
+
+        // Checks the container node under module node.
+        YdtContext container = module.getFirstChild();
+        assertThat(getInCrtName(CONTAINER, CONT_CARRIER), container.getName(),
+                   is(CONT_CARRIER));
+
+        // Checks the list node with content 1 of multiplex.
+        YdtContext mtx1 = container.getFirstChild();
+        assertThat(getInCrtName(LIST, LIST_MULTIPLEXES), mtx1.getName(),
+                   is(LIST_MULTIPLEXES));
+
+        // Checks enum leaf under multiplex of content1.
+        YdtContext enumLeaf1 = mtx1.getFirstChild();
+        assertThat(getInCrtName(LEAF, TYPES), enumLeaf1.getName(), is(TYPES));
+        assertThat(getInCrtLeafValue(TYPES, TIME_DIVISION),
+                   enumLeaf1.getValue(), is(TIME_DIVISION));
+
+        // Checks list app area content 1 under multiplex content 1.
+        YdtContext appAreaList1 = enumLeaf1.getNextSibling();
+        assertThat(getInCrtName(LIST, APP_AREA_LIST), appAreaList1.getName(),
+                   is(APP_AREA_LIST));
+
+        YdtContext leafList1 = appAreaList1.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, DEST_AREA), leafList1.getName(),
+                   is(DEST_AREA));
+        Set value1 = leafList1.getValueSet();
+        // TODO: check the leaf-list value.
+
+        // Checks list app area content 2 under multiplex content 1.
+        YdtContext appAreaList2 = appAreaList1.getNextSibling();
+        assertThat(getInCrtName(LIST, APP_AREA_LIST), appAreaList2.getName(),
+                   is(APP_AREA_LIST));
+
+        YdtContext leafList2 = appAreaList2.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, DEST_AREA), leafList2.getName(),
+                   is(DEST_AREA));
+        Set value2 = leafList1.getValueSet();
+        // TODO: check the leaf-list value.
+
+        // Checks the list node with content 2 of multiplex.
+        YdtContext mtx2 = mtx1.getNextSibling();
+        assertThat(getInCrtName(LIST, LIST_MULTIPLEXES), mtx2.getName(),
+                   is(LIST_MULTIPLEXES));
+
+        // Checks enum leaf under multiplex of content2.
+        YdtContext enumLeaf2 = mtx2.getFirstChild();
+        assertThat(getInCrtName(LEAF, TYPES), enumLeaf2.getName(), is(TYPES));
+        assertThat(getInCrtLeafValue(TYPES, FREQUENCY_DIV),
+                   enumLeaf2.getValue(), is(FREQUENCY_DIV));
+
+        // Checks list app area content 1 under multiplex content 2.
+        YdtContext appAreaList3 = enumLeaf2.getNextSibling();
+        assertThat(getInCrtName(LIST, APP_AREA_LIST), appAreaList3.getName(),
+                   is(APP_AREA_LIST));
+
+        YdtContext leafList3 = appAreaList3.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, DEST_AREA), leafList3.getName(),
+                   is(DEST_AREA));
+        Set value3 = leafList3.getValueSet();
+        // TODO: check the leaf-list value.
+
+        // Checks list app area content 2 under multiplex content 2.
+        YdtContext appAreaList4 = appAreaList3.getNextSibling();
+        assertThat(getInCrtName(LIST, APP_AREA_LIST), appAreaList4.getName(),
+                   is(APP_AREA_LIST));
+
+        YdtContext leafList4 = appAreaList4.getFirstChild();
+        assertThat(getInCrtName(LEAF_LIST, DEST_AREA), leafList4.getName(),
+                   is(DEST_AREA));
+        Set value4 = leafList4.getValueSet();
+        // TODO: check the leaf-list value.
+    }
+
+    /**
+     * Processes tree building from the derived type of leaf and leaf-list
+     * having binary and bits .
+     */
+    @Test
+    public void processTreeBuilderForBinaryAndBits() {
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates a byte array for binary leaf.
+        byte[] binLeaf = new byte[]{5, 5, 5};
+
+        // Assigns the value in the chained loop of typedef.
+        Derivedbinaryb derBinb = new Derivedbinaryb(binLeaf);
+        Derivedbinarya derBina = new Derivedbinarya(derBinb);
+
+        // Creates bit set for bit leaf.
+        BitSet bitLeaf = new BitSet();
+        bitLeaf.set(1);
+        bitLeaf.set(100);
+
+        // Assigns the value in the chained loop of typedef.
+        Derivedbitsb derBitb = new Derivedbitsb(bitLeaf);
+        Derivedbitsa derBita = new Derivedbitsa(derBitb);
+
+        // Creates a byte array list for binary leaf-list.
+        byte[] binList1 = new byte[]{9, 9, 0};
+        byte[] binList2 = new byte[]{12, 6, 0};
+        byte[] binList3 = new byte[]{16, 29, 25};
+
+        // Assigns the value in the chained loop of typedef.
+        Derivedbinaryb derBinBList1 = new Derivedbinaryb(binList1);
+        Derivedbinaryb derBinBList2 = new Derivedbinaryb(binList2);
+        Derivedbinaryb derBinBList3 = new Derivedbinaryb(binList3);
+
+        Derivedbinarya derBinAList1 = new Derivedbinarya(derBinBList1);
+        Derivedbinarya derBinAList2 = new Derivedbinarya(derBinBList2);
+        Derivedbinarya derBinAList3 = new Derivedbinarya(derBinBList3);
+
+        List<Derivedbinarya> binAlist = new ArrayList<>();
+        binAlist.add(derBinAList1);
+        binAlist.add(derBinAList2);
+        binAlist.add(derBinAList3);
+
+        // Creates a bit set list for bit leaf-list.
+        BitSet bitList1 = new BitSet();
+        bitList1.set(1);
+        BitSet bitList2 = new BitSet();
+        bitList2.set(1);
+        bitList2.set(10);
+        BitSet bitList3 = new BitSet();
+        bitList3.set(1);
+        bitList3.set(10);
+        bitList3.set(100);
+
+        // Assigns the value in the chained loop of typedef.
+        Derivedbitsb bitBlist1 = new Derivedbitsb(bitList1);
+        Derivedbitsb bitBlist2 = new Derivedbitsb(bitList2);
+        Derivedbitsb bitBlist3 = new Derivedbitsb(bitList3);
+
+        Derivedbitsa bitAlist1 = new Derivedbitsa(bitBlist1);
+        Derivedbitsa bitAlist2 = new Derivedbitsa(bitBlist2);
+        Derivedbitsa bitAlist3 = new Derivedbitsa(bitBlist3);
+
+        List<Derivedbitsa> bitAlist = new ArrayList<>();
+        bitAlist.add(bitAlist1);
+        bitAlist.add(bitAlist2);
+        bitAlist.add(bitAlist3);
+
+        // Creates a module by assigning all the leaf and leaf-list.
+        YtbDerivedTypeWithBitsAndBinary bitsAndBinary = new
+                YtbDerivedTypeWithBitsAndBinaryOpParam
+                        .YtbDerivedTypeWithBitsAndBinaryBuilder()
+                .forbinary(derBina).forbits(derBita)
+                .forbinarylist(binAlist)
+                .forbitslist(bitAlist).build();
+
+        // As YSB or YAB protocol, sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(bitsAndBinary);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, ROOT_NAME, ROOT_NAME_SPACE,
+                EDIT_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        assertThat(getInCrtName(MODULE, MOD_BIT_BIN), module.getName(),
+                   is(MOD_BIT_BIN));
+
+        // Checks the leaf for binary.
+        YdtContext binaryLeaf = module.getFirstChild();
+        assertThat(getInCrtName(LEAF, FOR_BINARY), binaryLeaf.getName(),
+                   is(FOR_BINARY));
+        assertThat(getInCrtLeafValue(FOR_BINARY, BIN_VAL_1),
+                   binaryLeaf.getValue(), is(BIN_VAL_1));
+
+        // Checks the leaf for bits.
+        YdtContext bitsLeaf = binaryLeaf.getNextSibling();
+        assertThat(getInCrtName(LEAF, FOR_BITS), bitsLeaf.getName(),
+                   is(FOR_BITS));
+        // TODO: The bits is not done.
+        String value1 = bitsLeaf.getValue();
+
+        // Checks the leaf-list for binary.
+        YdtContext binaryLeafList = bitsLeaf.getNextSibling();
+        assertThat(getInCrtName(LEAF_LIST, FOR_BINARY_LIST),
+                   binaryLeafList.getName(), is(FOR_BINARY_LIST));
+
+        Set value2 = binaryLeafList.getValueSet();
+        assertThat(getInCrtLeafListValue(FOR_BINARY_LIST, BIN_VAL_2),
+                   value2.contains(BIN_VAL_2), is(true));
+        assertThat(getInCrtLeafListValue(FOR_BINARY_LIST, BIN_VAL_3),
+                   value2.contains(BIN_VAL_3), is(true));
+        assertThat(getInCrtLeafListValue(FOR_BINARY_LIST, BIN_VAL_4),
+                   value2.contains(BIN_VAL_4), is(true));
+
+        // Checks the leaf-list for bits.
+        YdtContext bitsLeafList = binaryLeafList.getNextSibling();
+        assertThat(getInCrtName(LEAF_LIST, FOR_BITS_LIST),
+                   bitsLeafList.getName(), is(FOR_BITS_LIST));
+        // TODO: The value of bits should be mapped text string.
+        Set value3 = bitsLeafList.getValueSet();
+    }
+
+    /**
+     * Processes tree building for the union type.
+     */
+    @Test
+    public void processYtbUnionType() {
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+
+        // Creates union with binary type.
+        byte[] binary = new byte[]{0, 0, 0};
+        ForunionUnion union = new ForunionUnion(binary);
+
+        // Creates module with union.
+        YtbDerivedTypeWithBitsAndBinary unionType = new
+                YtbDerivedTypeWithBitsAndBinaryOpParam
+                        .YtbDerivedTypeWithBitsAndBinaryBuilder()
+                .forunion(union)
+                .build();
+
+        // As YSB or YAB protocol, sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(unionType);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, ROOT_NAME, ROOT_NAME_SPACE,
+                EDIT_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and check the tree that is built.
+        YdtContext rootNode = ydtBuilder.getRootNode();
+        YdtContext module = rootNode.getFirstChild();
+        YdtContext unionChild = module.getFirstChild();
+        assertThat(getInCrtName(LEAF, FOR_UNION), unionChild.getName(),
+                   is(FOR_UNION));
+        //TODO: Correct it once union generated code is fixed.
+        assertThat(getInCrtLeafValue(FOR_UNION, ZERO), unionChild.getValue(),
+                   is(ZERO));
+    }
+}
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));
+    }
+}
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/YtbErrMsgAndConstants.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/YtbErrMsgAndConstants.java
new file mode 100644
index 0000000..572a4be
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/YtbErrMsgAndConstants.java
@@ -0,0 +1,150 @@
+/*
+ * 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.onosproject.yms.app.ysr.TestYangSchemaNodeProvider;
+
+/**
+ * Represents the abstract class for ytb test classes having common methods
+ * and the constants.
+ */
+public abstract class YtbErrMsgAndConstants {
+
+    /**
+     * Static attribute of root name.
+     */
+    public static final String ROOT_NAME = "rootName";
+
+    /**
+     * Static attribute of root name space.
+     */
+    public static final String ROOT_NAME_SPACE = "rootNameSpace";
+
+    /**
+     * Static attribute of module which is YANG name.
+     */
+    public static final String MODULE = "module";
+
+    /**
+     * Static attribute of list which is YANG name.
+     */
+    public static final String LIST = "list";
+
+    /**
+     * Static attribute of leaf which is YANG name.
+     */
+    public static final String LEAF = "leaf";
+
+    /**
+     * Static attribute of leaf-list which is YANG name.
+     */
+    public static final String LEAF_LIST = "leaf-list";
+
+    /**
+     * Static attribute of container which is YANG name.
+     */
+    public static final String CONTAINER = "container";
+
+    /**
+     * Static attribute of name predict.
+     */
+    public static final String PREDICT = "predict";
+
+    /**
+     * Static attribute of name catch.
+     */
+    public static final String CATCH = "catch";
+
+    /**
+     * Static attribute of YANG file name.
+     */
+    public static final String RPC_NAME = "YtbSimpleRpcResponse";
+
+    /**
+     * Static attribute of name rpc.
+     */
+    public static final String RPC = "rpc";
+
+    /**
+     * Created a schema node provider, which will register the app.
+     */
+    public TestYangSchemaNodeProvider schemaProvider =
+            new TestYangSchemaNodeProvider();
+
+    /**
+     * Returns the error message for when leaf value doesn't match with the
+     * expected value. It takes name of leaf and expected value as its
+     * parameter, to throw the message.
+     *
+     * @param name  leaf name
+     * @param value expected value of leaf
+     * @return error message of leaf value as incorrect
+     */
+    public static String getInCrtLeafValue(String name, String value) {
+        return "The value of leaf " + name + " is not " + value;
+    }
+
+    /**
+     * Returns the error message, when node name doesn't match with the
+     * expected value. It takes YANG name of the node and the node name as
+     * parameter, to throw the message.
+     *
+     * @param node     YANG node name
+     * @param nodeName node name
+     * @return error message as the node name is incorrect
+     */
+    public static String getInCrtName(String node, String nodeName) {
+        return getCapitalCase(node) + "'s name " + nodeName + " is incorrect.";
+    }
+
+    /**
+     * Returns the error message, when operation type doesn't match with the
+     * expected value. It takes YANG name of the node and the node name as
+     * parameter, to throw the message.
+     *
+     * @param node     YANG node name
+     * @param nodeName node name
+     * @return error message as the operation type is incorrect
+     */
+    public static String getInCrtOpType(String node, String nodeName) {
+        return "The operation type of " + node + " " + nodeName + " is " +
+                "incorrect";
+    }
+
+    /**
+     * Returns the error message for when leaf-list value doesn't match with the
+     * expected value. It takes name of leaf-list and expected value as its
+     * parameter, to throw the message.
+     *
+     * @param name  leaf-list name
+     * @param value value in leaf-list
+     * @return error message as the value in the leaf-list is incorrect
+     */
+    public static String getInCrtLeafListValue(String name, String value) {
+        return "The leaf-list " + name + " does not have " + value + " in it.";
+    }
+
+    /**
+     * Returns the capital cased first letter of the given string.
+     *
+     * @param name string to be capital cased
+     * @return capital cased string
+     */
+    private static String getCapitalCase(String name) {
+        return name.substring(0, 1).toUpperCase() + name.substring(1);
+    }
+}
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/YtbInvalidNodeSkipTest.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/YtbInvalidNodeSkipTest.java
new file mode 100644
index 0000000..019d958
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/ytb/YtbInvalidNodeSkipTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.yms.test.ytb.simple.rpc.response.rev20160826.YtbSimpleRpcResponse;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.rpc.response.rev20160826.YtbSimpleRpcResponseOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.rpc.response.rev20160826.ytbsimplerpcresponse.Cumulative;
+import org.onosproject.yang.gen.v1.yms.test.ytb.simple.rpc.response.rev20160826.ytbsimplerpcresponse.DefaultCumulative;
+import org.onosproject.yms.app.ydt.YdtExtendedBuilder;
+import org.onosproject.yms.app.ysr.DefaultYangSchemaRegistry;
+import org.onosproject.yms.ydt.YdtContext;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yms.ydt.YmsOperationType.EDIT_CONFIG_REQUEST;
+
+/**
+ * Unit test cases for invalid node skip in YANG tree builder.
+ */
+public class YtbInvalidNodeSkipTest extends YtbErrMsgAndConstants {
+
+    private static final String CUMULATIVE = "cumulative";
+    private static final String SUM = "sum";
+    private static final String FIVE = "5";
+    private static final String TEN = "10";
+
+    /**
+     * Processes RPC node which is the sibling to the empty current node.
+     */
+    @Test
+    public void processRpcSiblingWhenNodeIsEmpty() {
+
+        schemaProvider.processSchemaRegistry(null);
+        DefaultYangSchemaRegistry registry = schemaProvider
+                .getDefaultYangSchemaRegistry();
+
+        // As an application, creates the object.
+        Cumulative cumulative1 = new DefaultCumulative.CumulativeBuilder()
+                .sum((byte) 5).build();
+        Cumulative cumulative2 = new DefaultCumulative.CumulativeBuilder()
+                .sum((byte) 10).build();
+        List<Cumulative> list = new ArrayList<>();
+        list.add(cumulative1);
+        list.add(cumulative2);
+        YtbSimpleRpcResponse rpc = new YtbSimpleRpcResponseOpParam
+                .YtbSimpleRpcResponseBuilder().cumulative(list).build();
+
+        // As YSB or YAB protocol sets the value for YTB.
+        List<Object> objectList = new ArrayList<>();
+        objectList.add(rpc);
+
+        // Builds YANG tree in YTB.
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        YdtExtendedBuilder ydtBuilder = treeBuilder.getYdtBuilderForYo(
+                objectList, ROOT_NAME, ROOT_NAME_SPACE,
+                EDIT_CONFIG_REQUEST, registry);
+
+        // Receives YDT context and checks the tree that is built.
+        YdtContext context = ydtBuilder.getRootNode();
+
+        // Gets the first module from logical root node.
+        YdtContext module = context.getFirstChild();
+        assertThat(getInCrtName(MODULE, RPC_NAME), module.getName(),
+                   is(RPC_NAME));
+
+        // Gets the first list content of cumulative.
+        YdtContext list1 = module.getFirstChild();
+        assertThat(getInCrtName(LIST, CUMULATIVE), list1.getName(),
+                   is(CUMULATIVE));
+
+        YdtContext sum1 = list1.getFirstChild();
+        assertThat(getInCrtName(LEAF, SUM), sum1.getName(), is(SUM));
+        assertThat(getInCrtLeafValue(SUM, FIVE), sum1.getValue(), is(FIVE));
+
+        // Gets the second list content of cumulative.
+        YdtContext list2 = list1.getNextSibling();
+        assertThat(getInCrtName(LIST, CUMULATIVE), list2.getName(),
+                   is(CUMULATIVE));
+
+        YdtContext sum2 = list2.getFirstChild();
+        assertThat(getInCrtName(LEAF, SUM), sum2.getName(), is(SUM));
+        assertThat(getInCrtLeafValue(SUM, TEN), sum2.getValue(), is(TEN));
+    }
+
+
+}
