diff --git a/apps/yms/ut/src/test/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilderTest.java b/apps/yms/ut/src/test/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilderTest.java
new file mode 100644
index 0000000..2f3cada
--- /dev/null
+++ b/apps/yms/ut/src/test/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilderTest.java
@@ -0,0 +1,1155 @@
+/*
+ * 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.YtbIetfSchedule.OnosYangOpType;
+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.yangautoprefixlist.rev20160826.YtbModuleWithList;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.yangautoprefixlist.rev20160826.YtbModuleWithListOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.yangautoprefixlist.rev20160826.ytbmodulewithlist.DefaultYtblistlist;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.yangautoprefixlist.rev20160826.ytbmodulewithlist.Find;
+import org.onosproject.yang.gen.v1.yms.test.ytb.module.with.yangautoprefixlist.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.yangautoprefixlist.having.yangautoprefixlist.rev20160826.YtbTreeBuilderForListHavingList;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.rev20160826.YtbTreeBuilderForListHavingListOpParam;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.rev20160826.ytbtreebuilderforlisthavinglist.Carrier;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.rev20160826.ytbtreebuilderforlisthavinglist.DefaultCarrier;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.rev20160826.ytbtreebuilderforlisthavinglist.carrier.DefaultMultiplexes;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.rev20160826.ytbtreebuilderforlisthavinglist.carrier.Multiplexes;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.rev20160826.ytbtreebuilderforlisthavinglist.carrier.multiplexes.ApplicationAreas;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.rev20160826.ytbtreebuilderforlisthavinglist.carrier.multiplexes.DefaultApplicationAreas;
+import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.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.hamcrest.core.IsNull.nullValue;
+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_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 BIN_VAL_5 = "AAAA";
+    private static final String BIT_VAL_1 = "leaf1 leaf2";
+    private static final String BIN_VAL_6 = "AQYD";
+    private static final String BIN_VAL_7 = "AgcE";
+    private static final String BIN_VAL_8 = "BQYB";
+    private static final String BIN_VAL_9 = "AwgE";
+    private static final String BIN_VAL_10 = "AQAA";
+    private static final String BIN_VAL_11 = "AAAB";
+    private static final String BIN_VAL_12 = "BwcH";
+    private static final String BIN_VAL_13 = "AAE=";
+    private static final String BIT_VAL_2 = "index signature";
+    private static final String BIT_VAL_3 = "index";
+    private static final String BIT_VAL_4 = "index name";
+    private static final String BIT_VAL_5 = "index name signature";
+
+    @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)
+                .yangYtbIetfScheduleOpType(OnosYangOpType.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, nullValue());
+
+        // 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)
+                .yangYtbIetfScheduleOpType(OnosYangOpType.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))
+                .yangSchedOpType(
+                        YtbModuleWithContainerOpParam.OnosYangOpType.DELETE)
+                .build();
+        // Creates module object with the container.
+        YtbModuleWithContainer contModule = new YtbModuleWithContainerOpParam
+                .YtbModuleWithContainerBuilder()
+                .sched(sched)
+                .yangYtbModuleWithContainerOpType(
+                        YtbModuleWithContainerOpParam.OnosYangOpType.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, nullValue());
+
+        // 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, nullValue());
+
+        // 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(0);
+        bitleaf.set(1);
+
+        // 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));
+        assertThat(getInCrtLeafValue(NOTIFY_LEAF, BIT_VAL_1),
+                   leafInCont.getValue(), is(BIT_VAL_1));
+    }
+
+    /**
+     * 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();
+        assertThat(getInCrtLeafListValue(DEST_AREA, BIN_VAL_6),
+                   value1.contains(BIN_VAL_6), is(true));
+        assertThat(getInCrtLeafListValue(DEST_AREA, BIN_VAL_7),
+                   value1.contains(BIN_VAL_7), is(true));
+
+        // 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 = leafList2.getValueSet();
+        assertThat(getInCrtLeafListValue(DEST_AREA, BIN_VAL_8),
+                   value2.contains(BIN_VAL_8), is(true));
+        assertThat(getInCrtLeafListValue(DEST_AREA, BIN_VAL_9),
+                   value2.contains(BIN_VAL_9), is(true));
+
+        // 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();
+        assertThat(getInCrtLeafListValue(DEST_AREA, BIN_VAL_10),
+                   value3.contains(BIN_VAL_10), is(true));
+        assertThat(getInCrtLeafListValue(DEST_AREA, BIN_VAL_11),
+                   value3.contains(BIN_VAL_11), is(true));
+
+        // 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();
+        assertThat(getInCrtLeafListValue(DEST_AREA, BIN_VAL_12),
+                   value4.contains(BIN_VAL_12), is(true));
+        assertThat(getInCrtLeafListValue(DEST_AREA, BIN_VAL_13),
+                   value4.contains(BIN_VAL_13), is(true));
+    }
+
+    /**
+     * 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));
+        assertThat(getInCrtLeafValue(FOR_BITS, BIT_VAL_2),
+                   bitsLeaf.getValue(), is(BIT_VAL_2));
+
+        // 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));
+        Set value3 = bitsLeafList.getValueSet();
+        assertThat(getInCrtLeafListValue(FOR_BITS_LIST, BIT_VAL_3),
+                   value3.contains(BIT_VAL_3), is(true));
+        assertThat(getInCrtLeafListValue(FOR_BITS_LIST, BIT_VAL_4),
+                   value3.contains(BIT_VAL_4), is(true));
+        assertThat(getInCrtLeafListValue(FOR_BITS_LIST, BIT_VAL_5),
+                   value3.contains(BIT_VAL_5), is(true));
+    }
+
+    /**
+     * 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));
+        assertThat(getInCrtLeafValue(FOR_UNION, BIN_VAL_5),
+                   unionChild.getValue(), is(BIN_VAL_5));
+    }
+}
