diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YdtBuilderFromYo.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YdtBuilderFromYo.java
new file mode 100644
index 0000000..a82eea2
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YdtBuilderFromYo.java
@@ -0,0 +1,906 @@
+/*
+ * 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.yangutils.datamodel.YangAugment;
+import org.onosproject.yangutils.datamodel.YangAugmentableNode;
+import org.onosproject.yangutils.datamodel.YangCase;
+import org.onosproject.yangutils.datamodel.YangChoice;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangLeafList;
+import org.onosproject.yangutils.datamodel.YangLeavesHolder;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yms.app.utils.TraversalType;
+import org.onosproject.yms.app.ydt.YdtExtendedBuilder;
+import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.ydt.YdtContextOperationType;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.onosproject.yms.app.utils.TraversalType.CHILD;
+import static org.onosproject.yms.app.utils.TraversalType.PARENT;
+import static org.onosproject.yms.app.utils.TraversalType.ROOT;
+import static org.onosproject.yms.app.utils.TraversalType.SIBLING;
+import static org.onosproject.yms.app.ydt.AppType.YTB;
+import static org.onosproject.yms.app.ytb.YtbUtil.PERIOD;
+import static org.onosproject.yms.app.ytb.YtbUtil.STR_NULL;
+import static org.onosproject.yms.app.ytb.YtbUtil.getAttributeFromInheritance;
+import static org.onosproject.yms.app.ytb.YtbUtil.getAttributeOfObject;
+import static org.onosproject.yms.app.ytb.YtbUtil.getCapitalCase;
+import static org.onosproject.yms.app.ytb.YtbUtil.getClassLoaderForAugment;
+import static org.onosproject.yms.app.ytb.YtbUtil.getInterfaceClassFromImplClass;
+import static org.onosproject.yms.app.ytb.YtbUtil.getJavaName;
+import static org.onosproject.yms.app.ytb.YtbUtil.getOperationTypeOfTheNode;
+import static org.onosproject.yms.app.ytb.YtbUtil.getParentObjectOfNode;
+import static org.onosproject.yms.app.ytb.YtbUtil.getStringFromDataType;
+import static org.onosproject.yms.app.ytb.YtbUtil.isAugmentNode;
+import static org.onosproject.yms.app.ytb.YtbUtil.isMultiInstanceNode;
+import static org.onosproject.yms.app.ytb.YtbUtil.isNodeProcessCompleted;
+import static org.onosproject.yms.app.ytb.YtbUtil.isNonEmpty;
+import static org.onosproject.yms.app.ytb.YtbUtil.isNonProcessableNode;
+import static org.onosproject.yms.app.ytb.YtbUtil.isTypePrimitive;
+import static org.onosproject.yms.app.ytb.YtbUtil.isValueOrSelectLeafSet;
+import static org.onosproject.yms.ydt.YdtContextOperationType.NONE;
+
+/**
+ * Implements traversal of YANG node and its corresponding object, resulting
+ * in building of the YDT tree.
+ */
+public class YdtBuilderFromYo {
+
+    private static final String STR_TYPE = "type";
+    private static final String STR_SUBJECT = "subject";
+    private static final String TRUE = "true";
+    private static final String IS_LEAF_VALUE_SET_METHOD = "isLeafValueSet";
+    private static final String IS_SELECT_LEAF_SET_METHOD = "isSelectLeaf";
+    private static final String OUTPUT = "output";
+    private static final String YANG_AUGMENTED_INFO_MAP =
+            "yangAugmentedInfoMap";
+
+    /**
+     * Application YANG schema registry.
+     */
+    private final YangSchemaRegistry registry;
+
+    /**
+     * Current instance of the YDT builder where the tree is built.
+     */
+    private final YdtExtendedBuilder extBuilder;
+
+    /**
+     * YANG root object that is required for walking along with the YANG node.
+     */
+    private Object rootObj;
+
+    /**
+     * YANG root node that is required for walking along with the YANG object.
+     */
+    private YangSchemaNode rootSchema;
+
+    /**
+     * Creates YDT builder from YANG object by assigning the mandatory values.
+     *
+     * @param rootBuilder root node builder
+     * @param rootObj     root node object
+     * @param registry    application schema registry
+     */
+    public YdtBuilderFromYo(YdtExtendedBuilder rootBuilder, Object rootObj,
+                            YangSchemaRegistry registry) {
+        extBuilder = rootBuilder;
+        this.rootObj = rootObj;
+        this.registry = registry;
+    }
+
+    /**
+     * Returns schema root node, received from YSR, which searches based on
+     * the object received from YAB or YCH.
+     *
+     * @param object root node object
+     */
+    public void getModuleNodeFromYsr(Object object) {
+        Class interfaceClass = getInterfaceClassFromImplClass(object);
+        rootSchema = registry
+                .getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+                        interfaceClass.getName());
+    }
+
+    /**
+     * Returns schema root node, received from YSR, which searches based on
+     * the object received from YNH.
+     *
+     * @param object notification event object
+     */
+    public void getRootNodeWithNotificationFromYsr(Object object) {
+        rootSchema = registry.getRootYangSchemaNodeForNotification(
+                object.getClass().getName());
+    }
+
+    /**
+     * Creates the module node for in YDT before beginning with notification
+     * root node traversal. Collects sufficient information to fill YDT with
+     * notification root node in the traversal.
+     */
+    public void createModuleInYdt() {
+        extBuilder.addChild(NONE, rootSchema);
+        rootSchema = getSchemaNodeOfNotification();
+        rootObj = getObjOfNotification();
+    }
+
+    /**
+     * Creates the module and RPC node, in YDT tree, from the logical root
+     * node received from request workbench. The output schema node is taken
+     * from the child schema of RPC YANG node.
+     *
+     * @param rootNode logical root node
+     */
+    public void createModuleAndRpcInYdt(YdtExtendedContext rootNode) {
+
+        YdtExtendedContext moduleNode =
+                (YdtExtendedContext) rootNode.getFirstChild();
+        extBuilder.addChild(NONE, moduleNode.getYangSchemaNode());
+
+        YdtExtendedContext rpcNode =
+                (YdtExtendedContext) moduleNode.getFirstChild();
+        YangSchemaNode rpcSchemaNode = rpcNode.getYangSchemaNode();
+        extBuilder.addChild(NONE, rpcSchemaNode);
+
+        // Defines a schema identifier for output node.
+        YangSchemaNodeIdentifier schemaId = new YangSchemaNodeIdentifier();
+        schemaId.setName(OUTPUT);
+        schemaId.setNameSpace(rpcSchemaNode.getNameSpace());
+        try {
+            // Gets the output schema node from RPC child schema.
+            rootSchema = rpcSchemaNode.getChildSchema(schemaId).getSchemaNode();
+        } catch (DataModelException e) {
+            throw new YtbException(e);
+        }
+    }
+
+    /**
+     * Creates YDT tree from the root object, by traversing through YANG data
+     * model node, and simultaneously checking the object nodes presence and
+     * walking the object.
+     */
+    public void createYdtFromRootObject() {
+        YangNode curNode = (YangNode) rootSchema;
+        TraversalType curTraversal = ROOT;
+        YtbNodeInfo listNodeInfo = null;
+        YtbNodeInfo augmentNodeInfo = null;
+
+        while (curNode != null) {
+            /*
+             * Processes the node, if it is being visited for the first time in
+             * the schema, also if the schema node is being retraced in a multi
+             * instance node.
+             */
+            if (curTraversal != PARENT || isMultiInstanceNode(curNode)) {
+
+                if (curTraversal == PARENT && isMultiInstanceNode(curNode)) {
+                    /*
+                     * If the schema is being retraced for a multi-instance
+                     * node, it has already entered for this multi-instance
+                     * node. Now this re-processes the same schema node for
+                     * any additional list object.
+                     */
+                    listNodeInfo = getCurNodeInfoAndTraverseBack();
+                }
+
+                if (curTraversal == ROOT && !isAugmentNode(curNode)) {
+                    /*
+                     * In case of RPC output, the root node is augmentative,
+                     * so when the root traversal is coming for augment this
+                     * flow is skipped. This adds only the root node in the YDT.
+                     */
+                    processApplicationRootNode();
+                } else {
+                    /*
+                     * Gets the object corresponding to current schema node.
+                     * If object exists, this adds the corresponding YDT node
+                     * to the tree and returns the object. Else returns null.
+                     */
+                    Object processedObject = processCurSchemaNodeAndAddToYdt(
+                            curNode, listNodeInfo);
+                    /*
+                     * Clears the list info of processed node. The next time
+                     * list info is taken newly and accordingly.
+                     */
+                    listNodeInfo = null;
+                    if (processedObject == null && !isAugmentNode(curNode)) {
+                        /*
+                         * Checks the presence of next sibling of the node, by
+                         * breaking the complete chain of the current node,
+                         * when the object value is not present, or when the
+                         * list entries are completely retraced. The augment
+                         * may have sibling, so this doesn't process for
+                         * augment.
+                         */
+                        YtbTraversalInfo traverseInfo =
+                                getProcessableInfo(curNode);
+                        curNode = traverseInfo.getYangNode();
+                        curTraversal = traverseInfo.getTraverseType();
+                        continue;
+                        /*
+                         * Irrespective of root or parent, sets the traversal
+                         * type as parent, when augment node doesn't have any
+                         * value. So, the other sibling augments can be
+                         * processed, if present.
+                         */
+                    } else if (processedObject == null &&
+                            isAugmentNode(curNode)) {
+                        curTraversal = PARENT;
+                        /*
+                         * The second content in the list will be having
+                         * parent traversal, in such case it cannot go to its
+                         * child in the flow, so it is made as child
+                         * traversal and proceeded to continue.
+                         */
+                    } else if (curTraversal == PARENT &&
+                            isMultiInstanceNode(curNode)) {
+                        curTraversal = CHILD;
+                    }
+                }
+            }
+            /*
+             * Checks for the sibling augment when the first augment node is
+             * getting completed. From the current augment node the previous
+             * node info is taken for augment and the traversal is changed to
+             * child, so as to check for the presence of sibling augment.
+             */
+            if (curTraversal == PARENT && isAugmentNode(curNode)) {
+                curNode = ((YangAugment) curNode).getAugmentedNode();
+                augmentNodeInfo = getParentYtbInfo();
+                curTraversal = CHILD;
+            }
+            /*
+             * Creates an augment iterator for the first time or takes the
+             * previous augment iterator for more than one time, whenever an
+             * augmentative node arrives. If augment is present it goes back
+             * for processing. If its null, the augmentative nodes process is
+             * continued.
+             */
+            if (curTraversal != PARENT &&
+                    curNode instanceof YangAugmentableNode) {
+                YangNode augmentNode = getAugmentInsideSchemaNode(
+                        curNode, augmentNodeInfo);
+                if (augmentNode != null) {
+                    curNode = augmentNode;
+                    continue;
+                }
+            }
+            /*
+             * Processes the child, after processing the node. If complete
+             * child depth is over, it takes up sibling and processes it.
+             * Once child and sibling is over, it is traversed back to the
+             * parent, without processing. In multi instance case, before
+             * going to parent or schema sibling, its own list sibling is
+             * processed. Skips the processing of RPC,notification and
+             * augment, as these nodes are dealt in a different flow.
+             */
+            if (curTraversal != PARENT && curNode.getChild() != null) {
+                augmentNodeInfo = null;
+                listNodeInfo = null;
+                curTraversal = CHILD;
+                curNode = curNode.getChild();
+                if (isNonProcessableNode(curNode)) {
+                    YtbTraversalInfo traverseInfo = getProcessableInfo(curNode);
+                    curNode = traverseInfo.getYangNode();
+                    curTraversal = traverseInfo.getTraverseType();
+                }
+            } else if (curNode.getNextSibling() != null) {
+                if (isNodeProcessCompleted(curNode, curTraversal)) {
+                    break;
+                }
+                if (isMultiInstanceNode(curNode)) {
+                    listNodeInfo = getCurNodeInfoAndTraverseBack();
+                    augmentNodeInfo = null;
+                    continue;
+                }
+                curTraversal = SIBLING;
+                traverseToParent(curNode);
+                curNode = curNode.getNextSibling();
+                if (isNonProcessableNode(curNode)) {
+                    YtbTraversalInfo traverseInfo = getProcessableInfo(curNode);
+                    curNode = traverseInfo.getYangNode();
+                    curTraversal = traverseInfo.getTraverseType();
+                }
+            } else {
+                if (isNodeProcessCompleted(curNode, curTraversal)) {
+                    break;
+                }
+                if (isMultiInstanceNode(curNode)) {
+                    listNodeInfo = getCurNodeInfoAndTraverseBack();
+                    augmentNodeInfo = null;
+                    continue;
+                }
+                curTraversal = PARENT;
+                traverseToParent(curNode);
+                curNode = curNode.getParent();
+            }
+        }
+    }
+
+    /**
+     * Processes root YANG node and adds it as a child to the YDT
+     * extended builder which is created earlier.
+     */
+    private void processApplicationRootNode() {
+
+        YtbNodeInfo nodeInfo = new YtbNodeInfo();
+        YangNode rootYang = (YangNode) rootSchema;
+        addChildNodeInYdt(rootObj, rootYang, nodeInfo);
+        // If root node has leaf or leaf-list those will be processed.
+        processLeaves(rootYang);
+        processLeavesList(rootYang);
+    }
+
+    /**
+     * Traverses to parent, based on the schema node that requires to be
+     * traversed. Skips traversal of parent for choice and case node, as they
+     * don't get added to the YDT tree.
+     *
+     * @param curNode current YANG node
+     */
+    private void traverseToParent(YangNode curNode) {
+        if (curNode instanceof YangCase || curNode instanceof YangChoice) {
+            return;
+        }
+        extBuilder.traverseToParentWithoutValidation();
+    }
+
+    /**
+     * Returns the current YTB info of the YDT builder, and then traverses back
+     * to parent. In case of multi instance node the previous node info is
+     * used for iterating through the list.
+     *
+     * @return current YTB app info
+     */
+    private YtbNodeInfo getCurNodeInfoAndTraverseBack() {
+        YtbNodeInfo appInfo = getParentYtbInfo();
+        extBuilder.traverseToParentWithoutValidation();
+        return appInfo;
+    }
+
+    /**
+     * Returns augment node for an augmented node. From the list of augment
+     * nodes it has, one of the nodes is taken and provided linearly. If the
+     * node is not augmented or the all the augment nodes are processed, then
+     * it returns null.
+     *
+     * @param curNode         current YANG node
+     * @param augmentNodeInfo previous augment node info
+     * @return YANG augment node
+     */
+    private YangNode getAugmentInsideSchemaNode(YangNode curNode,
+                                                YtbNodeInfo augmentNodeInfo) {
+        if (augmentNodeInfo == null) {
+            List<YangAugment> augmentList = ((YangAugmentableNode) curNode)
+                    .getAugmentedInfoList();
+            if (isNonEmpty(augmentList)) {
+                YtbNodeInfo parentNodeInfo = getParentYtbInfo();
+                Iterator<YangAugment> augmentItr = augmentList.listIterator();
+                parentNodeInfo.setAugmentIterator(augmentItr);
+                return augmentItr.next();
+            }
+        } else if (augmentNodeInfo.getAugmentIterator() != null) {
+            if (augmentNodeInfo.getAugmentIterator().hasNext()) {
+                return augmentNodeInfo.getAugmentIterator().next();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Processes the current YANG node and if necessary adds it to the YDT
+     * builder tree by extracting the information from the corresponding
+     * class object.
+     *
+     * @param curNode      current YANG node
+     * @param listNodeInfo previous node info for list
+     * @return object of the schema node
+     */
+    private Object processCurSchemaNodeAndAddToYdt(YangNode curNode,
+                                                   YtbNodeInfo listNodeInfo) {
+        YtbNodeInfo curNodeInfo = new YtbNodeInfo();
+        Object nodeObj = null;
+        YtbNodeInfo parentNodeInfo = getParentYtbInfo();
+
+        switch (curNode.getYangSchemaNodeType()) {
+            case YANG_SINGLE_INSTANCE_NODE:
+                nodeObj = processSingleInstanceNode(curNode, curNodeInfo,
+                                                    parentNodeInfo);
+                break;
+            case YANG_MULTI_INSTANCE_NODE:
+                nodeObj = processMultiInstanceNode(
+                        curNode, curNodeInfo, listNodeInfo, parentNodeInfo);
+                break;
+            case YANG_CHOICE_NODE:
+                nodeObj = processChoiceNode(curNode, parentNodeInfo);
+                break;
+            case YANG_NON_DATA_NODE:
+                if (curNode instanceof YangCase) {
+                    nodeObj = processCaseNode(curNode, parentNodeInfo);
+                }
+                break;
+            case YANG_AUGMENT_NODE:
+                nodeObj = processAugmentNode(curNode, parentNodeInfo);
+                break;
+            default:
+                throw new YtbException(
+                        "Non processable schema node has arrived for adding " +
+                                "it in YDT tree");
+        }
+        // Processes leaf/leaf-list only when object has value, else it skips.
+        if (nodeObj != null) {
+            processLeaves(curNode);
+            processLeavesList(curNode);
+        }
+        return nodeObj;
+    }
+
+    /**
+     * Processes single instance node which is added to the YDT tree.
+     *
+     * @param curNode        current YANG node
+     * @param curNodeInfo    current YDT node info
+     * @param parentNodeInfo parent YDT node info
+     * @return object of the current node
+     */
+    private Object processSingleInstanceNode(YangNode curNode,
+                                             YtbNodeInfo curNodeInfo,
+                                             YtbNodeInfo parentNodeInfo) {
+        Object childObj = getChildObject(curNode, parentNodeInfo);
+        if (childObj != null) {
+            addChildNodeInYdt(childObj, curNode, curNodeInfo);
+        }
+        return childObj;
+    }
+
+    /**
+     * Processes multi instance node which has to be added to the YDT tree.
+     * For the first instance in the list, iterator is created and added to
+     * the list. For second instance or more the iterator from first instance
+     * is taken and iterated through to get the object of parent.
+     *
+     * @param curNode        current list node
+     * @param curNodeInfo    current node info for list
+     * @param listNodeInfo   previous instance node info of list
+     * @param parentNodeInfo parent node info of list
+     * @return object of the current instance
+     */
+    private Object processMultiInstanceNode(YangNode curNode,
+                                            YtbNodeInfo curNodeInfo,
+                                            YtbNodeInfo listNodeInfo,
+                                            YtbNodeInfo parentNodeInfo) {
+        Object childObj = null;
+        /*
+         * When YANG list comes to this flow for first time, its YTB node
+         * will be null. When it comes for the second or more content, then
+         * the list would have been already set for that node. According to
+         * set or not set this flow will be proceeded.
+         */
+        if (listNodeInfo == null) {
+            List<Object> childObjList = (List<Object>) getChildObject(
+                    curNode, parentNodeInfo);
+            if (isNonEmpty(childObjList)) {
+                Iterator<Object> listItr = childObjList.iterator();
+                if (!listItr.hasNext()) {
+                    return null;
+                    //TODO: Handle the subtree filtering with no list entries.
+                }
+                childObj = listItr.next();
+                /*
+                 * For that node the iterator is set. So the next time for
+                 * the list this iterator will be taken.
+                 */
+                curNodeInfo.setListIterator(listItr);
+            }
+        } else {
+            /*
+             * If the list value comes for second or more time, that list
+             * node will be having YTB node info, where iterator can be
+             * retrieved and check if any more contents are present. If
+             * present those will be processed.
+             */
+            curNodeInfo.setListIterator(listNodeInfo.getListIterator());
+            if (listNodeInfo.getListIterator().hasNext()) {
+                childObj = listNodeInfo.getListIterator().next();
+            }
+        }
+        if (childObj != null) {
+            addChildNodeInYdt(childObj, curNode, curNodeInfo);
+        }
+        return childObj;
+    }
+
+    /**
+     * Processes choice node which adds a map to the parent node info of
+     * choice name and the case object. The object taken for choice node is
+     * of case object with choice name. Also, this Skips the addition of choice
+     * to YDT.
+     *
+     * @param curNode        current choice node
+     * @param parentNodeInfo parent YTB node info
+     * @return object of the choice node
+     */
+    private Object processChoiceNode(YangNode curNode,
+                                     YtbNodeInfo parentNodeInfo) {
+        /*
+         * Retrieves the parent YTB info, to take the object of parent, so as
+         * to check the child attribute from the object.
+         */
+        Object childObj = getChildObject(curNode, parentNodeInfo);
+        if (childObj != null) {
+            Map<String, Object> choiceCaseMap = parentNodeInfo
+                    .getChoiceCaseMap();
+            if (choiceCaseMap == null) {
+                choiceCaseMap = new HashMap<>();
+                parentNodeInfo.setChoiceCaseMap(choiceCaseMap);
+            }
+            choiceCaseMap.put(curNode.getName(), childObj);
+        }
+        return childObj;
+    }
+
+    /**
+     * Processes case node from the map contents that is filled by choice
+     * nodes. Object of choice is taken when choice name and case class name
+     * matches. When the case node is not present in the map it returns null.
+     *
+     * @param curNode        current case node
+     * @param parentNodeInfo choice parent node info
+     * @return object of the case node
+     */
+    private Object processCaseNode(YangNode curNode,
+                                   YtbNodeInfo parentNodeInfo) {
+        Object childObj = null;
+        if (parentNodeInfo.getChoiceCaseMap() != null) {
+            childObj = getCaseObjectFromChoice(parentNodeInfo,
+                                               curNode);
+        }
+        if (childObj != null) {
+            /*
+             * Sets the case object in parent info, so that rest of the case
+             * children can use it as parent. Case is not added in YDT.
+             */
+            parentNodeInfo.setCaseObject(childObj);
+        }
+        return childObj;
+    }
+
+    /**
+     * Processes augment node, which is not added in the YDT, but binds
+     * itself to the parent YTB info, so rest of its child nodes can use for
+     * adding themselves to the YDT tree. If there is no augment node added
+     * in map or if the augment module is not registered, then it returns null.
+     *
+     * @param curNode        current augment node
+     * @param parentNodeInfo augment parent node info
+     * @return object of the augment node
+     */
+    private Object processAugmentNode(YangNode curNode,
+                                      YtbNodeInfo parentNodeInfo) {
+        String className = curNode.getJavaClassNameOrBuiltInType();
+        String pkgName = curNode.getJavaPackage();
+        Object parentObj = getParentObjectOfNode(parentNodeInfo,
+                                                 curNode.getParent());
+        Map augmentMap;
+        try {
+            augmentMap = (Map) getAttributeOfObject(parentObj,
+                                                    YANG_AUGMENTED_INFO_MAP);
+            /*
+             * Gets the registered module class. Loads the class and gets the
+             * augment class.
+             */
+            Class moduleClass = getClassLoaderForAugment(curNode, registry);
+            if (moduleClass == null) {
+                return null;
+            }
+            Class augmentClass = moduleClass.getClassLoader().loadClass(
+                    pkgName + PERIOD + className);
+            Object childObj = augmentMap.get(augmentClass);
+            parentNodeInfo.setAugmentObject(childObj);
+            return childObj;
+        } catch (ClassNotFoundException | NoSuchMethodException e) {
+            throw new YtbException(e);
+        }
+    }
+
+    /**
+     * Returns the YTB info from the parent node, so that its own bounded
+     * object can be taken out.
+     *
+     * @return parent node YTB node info
+     */
+    private YtbNodeInfo getParentYtbInfo() {
+        YdtExtendedContext parentExtContext =
+                (YdtExtendedContext) extBuilder.getCurNode();
+        return (YtbNodeInfo) parentExtContext.getAppInfo(YTB);
+    }
+
+    /**
+     * Returns the child object from the parent object. Uses java name of the
+     * current node to search the attribute in the parent object.
+     *
+     * @param curNode        current YANG node
+     * @param parentNodeInfo parent YTB node info
+     * @return object of the child node
+     */
+    private Object getChildObject(YangNode curNode,
+                                  YtbNodeInfo parentNodeInfo) {
+        String nodeJavaName = curNode.getJavaAttributeName();
+        Object parentObj = getParentObjectOfNode(parentNodeInfo,
+                                                 curNode.getParent());
+        try {
+            return getAttributeOfObject(parentObj, nodeJavaName);
+        } catch (NoSuchMethodException e) {
+            throw new YtbException(e);
+        }
+    }
+
+    /**
+     * Adds the child node to the YDT by taking operation type from the
+     * object. Also, binds the object to the YDT node through YTB node info.
+     *
+     * @param childObj    node object
+     * @param curNode     current YANG node
+     * @param curNodeInfo current YTB info
+     */
+    private void addChildNodeInYdt(Object childObj, YangNode curNode,
+                                   YtbNodeInfo curNodeInfo) {
+        YdtContextOperationType opType = getOperationTypeOfTheNode(childObj);
+        extBuilder.addChild(opType, curNode);
+        YdtExtendedContext curExtContext = (YdtExtendedContext) extBuilder
+                .getCurNode();
+        curNodeInfo.setYangObject(childObj);
+        curExtContext.addAppInfo(YTB, curNodeInfo);
+    }
+
+    /**
+     * Processes every leaf in a YANG node. Iterates through the leaf, takes
+     * value from the leaf and adds it to the YDT with value. If value is not
+     * present, and select leaf is set, adds it to the YDT without value.
+     *
+     * @param yangNode leaves holder node
+     */
+    private void processLeaves(YangNode yangNode) {
+        if (yangNode instanceof YangLeavesHolder) {
+            List<YangLeaf> leavesList = ((YangLeavesHolder) yangNode)
+                    .getListOfLeaf();
+            if (leavesList != null) {
+                for (YangLeaf yangLeaf : leavesList) {
+                    YtbNodeInfo parentYtbInfo = getParentYtbInfo();
+                    Object parentObj = getParentObjectOfNode(parentYtbInfo,
+                                                             yangNode);
+                    Object leafType;
+                    try {
+                        leafType = getAttributeOfObject(parentObj,
+                                                        getJavaName(yangLeaf));
+                    } catch (NoSuchMethodException e) {
+                        throw new YtbException(e);
+                    }
+
+                    addLeafWithValue(yangLeaf, parentObj, leafType);
+                    addLeafWithoutValue(yangLeaf, parentObj);
+                }
+            }
+        }
+    }
+
+    /**
+     * Processes every leaf-list in a YANG node. For each leaf-list, the list of
+     * objects are iterated, value from each object is put in a set of string,
+     * and is added to the YDT.
+     *
+     * @param yangNode list of leaf-list holder node
+     */
+    private void processLeavesList(YangNode yangNode) {
+        if (yangNode instanceof YangLeavesHolder) {
+            List<YangLeafList> listOfLeafList =
+                    ((YangLeavesHolder) yangNode).getListOfLeafList();
+
+            if (listOfLeafList != null) {
+                for (YangLeafList yangLeafList : listOfLeafList) {
+
+                    YtbNodeInfo ytbNodeInfo = getParentYtbInfo();
+                    Object parentObj = getParentObjectOfNode(ytbNodeInfo,
+                                                             yangNode);
+
+                    //TODO: Let the received object list be generic collection.
+                    List<Object> leafListObj;
+                    try {
+                        leafListObj = (List<Object>) getAttributeOfObject(
+                                parentObj, getJavaName(yangLeafList));
+                    } catch (NoSuchMethodException e) {
+                        throw new YtbException(e);
+                    }
+                    Set<String> leafListValue = new HashSet<>();
+                    /*
+                     * If list is present, then adds each object value in set.
+                     * Adds this set to the YDT, and traverse to parent.
+                     */
+                    if (leafListObj != null) {
+                        for (Object object : leafListObj) {
+                            String objValue = getStringFromDataType(
+                                    object, yangLeafList.getDataType());
+                            leafListValue.add(objValue);
+                        }
+                        extBuilder.addLeafList(leafListValue, yangLeafList);
+                        extBuilder.traverseToParentWithoutValidation();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the schema node of notification from the root node. Gets the
+     * enum value from event object and gives it to the root schema node for
+     * getting back the notification schema node.
+     *
+     * @return YANG schema node of notification
+     */
+    private YangSchemaNode getSchemaNodeOfNotification() {
+        Class parentClass = rootObj.getClass().getSuperclass();
+        Object eventObjType = getAttributeFromInheritance(
+                parentClass, rootObj, STR_TYPE);
+        String opTypeValue = String.valueOf(eventObjType);
+
+        if (opTypeValue.equals(STR_NULL) || opTypeValue.isEmpty()) {
+            throw new YtbException(
+                    "There is no notification present for the event. Invalid " +
+                            "input for notification.");
+        }
+        try {
+            return rootSchema.getNotificationSchemaNode(opTypeValue);
+        } catch (DataModelException e) {
+            throw new YtbException(e);
+        }
+    }
+
+    /**
+     * Returns the object of the notification by retrieving the attributes
+     * from the event class object.
+     *
+     * @return notification YANG object
+     */
+    private Object getObjOfNotification() {
+        Class parentClass = rootObj.getClass().getSuperclass();
+        Object eventSubjectObj = getAttributeFromInheritance(
+                parentClass, rootObj, STR_SUBJECT);
+        String notificationName = rootSchema.getJavaAttributeName();
+        try {
+            return getAttributeOfObject(eventSubjectObj, notificationName);
+        } catch (NoSuchMethodException e) {
+            throw new YtbException(e);
+        }
+    }
+
+    /**
+     * Returns case object from the map that is bound to the parent node
+     * info. For any case node, only when the key and value is matched the
+     * object of the case is provided. If a match is not found, null is
+     * returned.
+     *
+     * @param parentNodeInfo parent YTB node info
+     * @param caseNode       case schema node
+     * @return object of the case node
+     */
+    private Object getCaseObjectFromChoice(YtbNodeInfo parentNodeInfo,
+                                           YangSchemaNode caseNode) {
+        String javaName = getCapitalCase(
+                caseNode.getJavaClassNameOrBuiltInType());
+        String choiceName = ((YangNode) caseNode).getParent().getName();
+        Map<String, Object> mapObj = parentNodeInfo.getChoiceCaseMap();
+        Object caseObj = mapObj.get(choiceName);
+        Class<?> interfaceClass = getInterfaceClassFromImplClass(caseObj);
+        return interfaceClass.getSimpleName().equals(javaName) ? caseObj : null;
+    }
+
+    /**
+     * Adds leaf to YDT when value is present. For primitive types, in order
+     * to avoid default values, the value select is set or not is checked and
+     * then added.
+     *
+     * @param yangLeaf  YANG leaf node
+     * @param parentObj leaf holder object
+     * @param leafType  object of leaf type
+     */
+    private void addLeafWithValue(YangLeaf yangLeaf, Object parentObj,
+                                  Object leafType) {
+        String fieldValue = null;
+        if (isTypePrimitive(yangLeaf.getDataType())) {
+            fieldValue = getLeafValueFromValueSetFlag(parentObj, yangLeaf,
+                                                      leafType);
+            /*
+             * Checks the object is present or not, when type is
+             * non-primitive. And adds the value from the respective data type.
+             */
+        } else if (leafType != null) {
+            fieldValue = getStringFromDataType(leafType,
+                                               yangLeaf.getDataType());
+        }
+        if (isNonEmpty(fieldValue)) {
+            extBuilder.addLeaf(fieldValue, yangLeaf);
+            extBuilder.traverseToParentWithoutValidation();
+        }
+    }
+
+    /**
+     * Adds leaf without value, when the select leaf bit is set.
+     *
+     * @param yangLeaf  YANG leaf node
+     * @param parentObj leaf holder object
+     */
+    private void addLeafWithoutValue(YangLeaf yangLeaf, Object parentObj) {
+        String selectLeaf = isValueOrSelectLeafSet(
+                parentObj, getJavaName(yangLeaf), IS_SELECT_LEAF_SET_METHOD);
+        if (selectLeaf.equals(TRUE)) {
+            extBuilder.addLeaf(null, yangLeaf);
+            extBuilder.traverseToParentWithoutValidation();
+        }
+    }
+
+    /**
+     * Returns the value of type, after checking, the value leaf flag. If the
+     * flag is set, then it takes the value or returns null.
+     *
+     * @param parentObj parent object
+     * @param yangLeaf  YANG leaf node
+     * @param leafType  object of leaf type
+     * @return value of type
+     */
+    private String getLeafValueFromValueSetFlag(
+            Object parentObj, YangLeaf yangLeaf, Object leafType) {
+        String valueOfLeaf = isValueOrSelectLeafSet(
+                parentObj, getJavaName(yangLeaf), IS_LEAF_VALUE_SET_METHOD);
+        if (valueOfLeaf.equals(TRUE)) {
+            return getStringFromDataType(leafType, yangLeaf.getDataType());
+        }
+        return null;
+    }
+
+    /**
+     * Returns the node info which can be processed, by eliminating the nodes
+     * which need not to be processed at normal conditions such as RPC,
+     * notification and augment.
+     *
+     * @param curNode current node
+     * @return info of node which needs processing
+     */
+    private YtbTraversalInfo getProcessableInfo(YangNode curNode) {
+        if (curNode.getNextSibling() != null) {
+            YangNode sibling = curNode.getNextSibling();
+            while (isNonProcessableNode(sibling)) {
+                sibling = sibling.getNextSibling();
+            }
+            if (sibling != null) {
+                return new YtbTraversalInfo(sibling, SIBLING);
+            }
+        }
+        return new YtbTraversalInfo(curNode.getParent(), PARENT);
+    }
+
+}
