[ONOS-5081] YANG tree builder.
Change-Id: Id47015d0cec1a446efcae6c4f3e2ffe87a0f0e0e
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilder.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilder.java
new file mode 100644
index 0000000..6f8df8e
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilder.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ytb;
+
+import org.onosproject.yms.app.ydt.YangRequestWorkBench;
+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.YdtContext;
+import org.onosproject.yms.ydt.YmsOperationType;
+
+import java.util.List;
+
+import static org.onosproject.yms.app.ytb.YtbUtil.emptyObjErrMsg;
+import static org.onosproject.yms.ydt.YmsOperationType.NOTIFICATION;
+import static org.onosproject.yms.ydt.YmsOperationType.RPC_REPLY;
+
+/**
+ * Representation of YANG tree builder which generates YANG data tree from the
+ * class objects which are provided from the applications and return it to the
+ * protocol(s).
+ */
+public class DefaultYangTreeBuilder implements YangTreeBuilder {
+
+    private static final String OBJ_LIST = "object list";
+    private static final String EVENT_OBJ = "event object";
+    private static final String OUTPUT_OBJ = "output object";
+
+    /**
+     * Creates the YANG tree builder.
+     */
+    public DefaultYangTreeBuilder() {
+    }
+
+    @Override
+    public YdtExtendedBuilder getYdtBuilderForYo(
+            List<Object> moduleObj, String rootName,
+            String rootNameSpace, YmsOperationType opType,
+            YangSchemaRegistry registry) {
+
+        if (moduleObj == null || moduleObj.isEmpty()) {
+            throw new YtbException(emptyObjErrMsg(OBJ_LIST));
+        }
+
+        YdtExtendedBuilder ydtBuilder = new YangRequestWorkBench(
+                rootName, rootNameSpace, opType, registry, false);
+
+        for (Object yangObj : moduleObj) {
+            YdtBuilderFromYo moduleBuilder = new YdtBuilderFromYo(
+                    ydtBuilder, yangObj, registry);
+
+            moduleBuilder.getModuleNodeFromYsr(yangObj);
+            moduleBuilder.createYdtFromRootObject();
+        }
+        return ydtBuilder;
+    }
+
+    @Override
+    public YdtContext getYdtForNotification(Object object, String rootName,
+                                            YangSchemaRegistry registry) {
+
+        if (object == null) {
+            throw new YtbException(emptyObjErrMsg(EVENT_OBJ));
+        }
+
+        YdtExtendedBuilder extBuilder = new YangRequestWorkBench(
+                rootName, null, NOTIFICATION, registry, false);
+        YdtBuilderFromYo moduleBuilder = new YdtBuilderFromYo(
+                extBuilder, object, registry);
+
+        moduleBuilder.getRootNodeWithNotificationFromYsr(object);
+        /*
+         * Adds module to YDT, so that notification can further enhance the
+         * tree.
+         */
+        moduleBuilder.createModuleInYdt();
+        moduleBuilder.createYdtFromRootObject();
+        return extBuilder.getRootNode();
+    }
+
+    @Override
+    public YdtExtendedBuilder getYdtForRpcResponse(
+            Object outputObj, YangRequestWorkBench workBench) {
+
+        if (outputObj == null) {
+            throw new YtbException(emptyObjErrMsg(OUTPUT_OBJ));
+        }
+
+        // Gets the logical root node from RPC request work bench.
+        YdtExtendedContext rootNode = workBench.getRootNode();
+
+        /*
+         * Creates a new work bench for RPC reply from the contents of the
+         * request work bench
+         */
+        YdtExtendedBuilder ydtBuilder = new YangRequestWorkBench(
+                rootNode.getName(), rootNode.getNamespace(),
+                RPC_REPLY, workBench.getYangSchemaRegistry(), false);
+        YdtBuilderFromYo moduleBuilder = new YdtBuilderFromYo(
+                ydtBuilder, outputObj,
+                workBench.getYangSchemaRegistry());
+
+        // Forms YDT till RPC, so that output can further enhance the tree.
+        moduleBuilder.createModuleAndRpcInYdt(rootNode);
+        moduleBuilder.createYdtFromRootObject();
+        return ydtBuilder;
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YangTreeBuilder.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YangTreeBuilder.java
new file mode 100644
index 0000000..2c1df67
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YangTreeBuilder.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ytb;
+
+import org.onosproject.yms.app.ydt.YangRequestWorkBench;
+import org.onosproject.yms.app.ydt.YdtExtendedBuilder;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.ydt.YdtContext;
+import org.onosproject.yms.ydt.YmsOperationType;
+
+import java.util.List;
+
+/**
+ * Abstraction of an entity which provides interfaces to build YANG data tree
+ * from the object received from YNH, YAB or YCH.
+ */
+public interface YangTreeBuilder {
+
+    /**
+     * Returns the YDT builder after building the tree corresponding to the
+     * response YANG object received from any of the protocol such as YAB or
+     * YCH.
+     *
+     * @param moduleObj     application module object
+     * @param rootName      root node name
+     * @param rootNameSpace root node namespace
+     * @param opType        root node operation type
+     * @param registry      application schema registry
+     * @return YDT builder from the tree
+     */
+    YdtExtendedBuilder getYdtBuilderForYo(List<Object> moduleObj,
+                                          String rootName,
+                                          String rootNameSpace,
+                                          YmsOperationType opType,
+                                          YangSchemaRegistry registry);
+
+    /**
+     * Returns the YDT context after building the tree received from the
+     * protocol YNH.
+     *
+     * @param object   application notification object
+     * @param rootName root node name
+     * @param registry application schema registry
+     * @return YDT context from the tree
+     */
+    YdtContext getYdtForNotification(Object object, String rootName,
+                                     YangSchemaRegistry registry);
+
+    /**
+     * Returns the YDT context after building the RPC response tree. The input
+     * for building the tree is RPC request workbench, RPC output java object.
+     * These are received from the YSB protocol.
+     *
+     * @param outputObj application output object
+     * @param workBench RPC request workbench from YDT
+     * @return YDT builder where RPC response tree is created
+     */
+    YdtExtendedBuilder getYdtForRpcResponse(Object outputObj,
+                                            YangRequestWorkBench workBench);
+}
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);
+    }
+
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbException.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbException.java
new file mode 100644
index 0000000..98f141a
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbException.java
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+/**
+ * Represents exception that needs to be handled by YTB.
+ */
+public class YtbException extends RuntimeException {
+
+    /**
+     * Creates YTB exception with an exception message.
+     *
+     * @param exceptionMessage message with which exception must be thrown
+     */
+    public YtbException(String exceptionMessage) {
+        super(exceptionMessage);
+    }
+
+    /**
+     * Creates YTB exception with the cause for it.
+     *
+     * @param cause cause of the exception
+     */
+    public YtbException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbNodeInfo.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbNodeInfo.java
new file mode 100644
index 0000000..6815bca
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbNodeInfo.java
@@ -0,0 +1,186 @@
+/*
+ * 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 java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Represents YTB node info for all the nodes that are added to the YDT
+ * builder tree.Contains the information which can be attached and retrieved
+ * back from YDT while walking.
+ */
+public class YtbNodeInfo {
+
+    /**
+     * Object of the corresponding YANG construct. This object is bound to
+     * each and every YDT node. So, whenever walk of parent and sibling
+     * happens, object can be retrieved from its YDT node.
+     */
+    private Object yangObject;
+
+    /**
+     * The list iterator since first content of the multi instance node is
+     * faced. With this iterator the node can be walked multiple times till
+     * it becomes empty.
+     */
+    private Iterator<Object> listIterator;
+
+    /**
+     * The current YTB node's, list of augments are iterated through this
+     * iterator. Every time an augment is built completely, this iterator
+     * gives the next augment node until it becomes empty.
+     */
+    private Iterator<YangAugment> augmentNodeItr;
+
+    /**
+     * The map with case object as value and choice node name as key is added
+     * for the current YTB info. Every time a case schema node comes, it takes
+     * this map and checks if it is present.
+     */
+    private Map<String, Object> choiceCaseMap;
+
+    /**
+     * When the case finds its object in map, it assigns it to case object of
+     * the YTB info, so when its child wants to take the parent object, they
+     * can take from the YTB info's case object.
+     */
+    private Object caseObject;
+
+    /**
+     * When the augment object is present, it assigns it to augment object of
+     * the YTB info, so when its child wants to take the parent object, they
+     * can take from the YTB info's augment object.
+     */
+    private Object augmentObject;
+
+    /**
+     * Constructs a default YTB node info.
+     */
+    public YtbNodeInfo() {
+    }
+
+    /**
+     * Returns the object of the YANG schema node.
+     *
+     * @return YANG node object
+     */
+    public Object getYangObject() {
+        return yangObject;
+    }
+
+    /**
+     * Sets the object of the YANG schema node.
+     *
+     * @param yangObject YANG node object
+     */
+    public void setYangObject(Object yangObject) {
+        this.yangObject = yangObject;
+    }
+
+    /**
+     * Returns the current list iterator of the YANG schema node.
+     *
+     * @return current list iterator for the schema node
+     */
+    public Iterator<Object> getListIterator() {
+        return listIterator;
+    }
+
+    /**
+     * Sets the current list iterator of the YANG schema node.
+     *
+     * @param listIterator current list iterator for the schema node
+     */
+    public void setListIterator(Iterator<Object> listIterator) {
+        this.listIterator = listIterator;
+    }
+
+    /**
+     * Returns the map of choice schema name and case object.
+     *
+     * @return choice name and case object map
+     */
+    public Map<String, Object> getChoiceCaseMap() {
+        return choiceCaseMap;
+    }
+
+    /**
+     * Sets the map of choice schema name and case object.
+     *
+     * @param choiceCaseMap choice name and case object map
+     */
+    public void setChoiceCaseMap(Map<String, Object> choiceCaseMap) {
+        this.choiceCaseMap = choiceCaseMap;
+    }
+
+    /**
+     * Returns the case object.
+     *
+     * @return case object
+     */
+    public Object getCaseObject() {
+        return caseObject;
+    }
+
+    /**
+     * Sets the case node object.
+     *
+     * @param caseObject case node object
+     */
+    public void setCaseObject(Object caseObject) {
+        this.caseObject = caseObject;
+    }
+
+    /**
+     * Returns the augment node object.
+     *
+     * @return augment node object
+     */
+    public Object getAugmentObject() {
+        return augmentObject;
+    }
+
+    /**
+     * Sets the augment node object.
+     *
+     * @param augmentObject augment node object
+     */
+    public void setAugmentObject(Object augmentObject) {
+        this.augmentObject = augmentObject;
+    }
+
+    /**
+     * Returns the current list iterator of the YANG augment node.
+     *
+     * @return augment node iterator
+     */
+    public Iterator<YangAugment> getAugmentIterator() {
+        return augmentNodeItr;
+    }
+
+    /**
+     * Sets the current list iterator of the YANG augment node.
+     *
+     * @param augmentNodeItr augment node iterator
+     */
+    public void setAugmentIterator(Iterator<YangAugment> augmentNodeItr) {
+        this.augmentNodeItr = augmentNodeItr;
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbTraversalInfo.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbTraversalInfo.java
new file mode 100644
index 0000000..4435c0a
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbTraversalInfo.java
@@ -0,0 +1,68 @@
+/*
+ * 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.YangNode;
+import org.onosproject.yms.app.utils.TraversalType;
+
+/**
+ * Represents YTB Traversal info which is needed every time the traversal of
+ * a YANG node happens. This contains YANG node and its corresponding traversal
+ * type information.
+ */
+public class YtbTraversalInfo {
+
+    /**
+     * YANG node of the current traversal.
+     */
+    private YangNode yangNode;
+
+    /**
+     * Traverse type of the current traversal.
+     */
+    private TraversalType traverseType;
+
+    /**
+     * Creates YTB traversal info by taking the traversal type and the YANG
+     * node.
+     *
+     * @param yangNode     YANG node
+     * @param traverseType traversal type
+     */
+    public YtbTraversalInfo(YangNode yangNode, TraversalType traverseType) {
+        this.yangNode = yangNode;
+        this.traverseType = traverseType;
+    }
+
+    /**
+     * Returns the YANG node of the current traversal.
+     *
+     * @return YANG node
+     */
+    public YangNode getYangNode() {
+        return yangNode;
+    }
+
+    /**
+     * Returns the traversal type of the current traversal.
+     *
+     * @return traversal type
+     */
+    public TraversalType getTraverseType() {
+        return traverseType;
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbUtil.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbUtil.java
new file mode 100644
index 0000000..8329c9f
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbUtil.java
@@ -0,0 +1,449 @@
+/*
+ * 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.YangCase;
+import org.onosproject.yangutils.datamodel.YangLeafRef;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNotification;
+import org.onosproject.yangutils.datamodel.YangOutput;
+import org.onosproject.yangutils.datamodel.YangRpc;
+import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
+import org.onosproject.yangutils.translator.tojava.javamodel.JavaLeafInfoContainer;
+import org.onosproject.yms.app.utils.TraversalType;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.ydt.YdtContextOperationType;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_AUGMENT_NODE;
+import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_MULTI_INSTANCE_NODE;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BOOLEAN;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.DECIMAL64;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.EMPTY;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT16;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT32;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT64;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT8;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.LEAFREF;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT16;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT32;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT64;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT8;
+import static org.onosproject.yms.app.utils.TraversalType.PARENT;
+
+/**
+ * Representation of utility for YANG tree builder.
+ */
+public final class YtbUtil {
+
+    /**
+     * Static attribute for string value having null.
+     */
+    public static final String STR_NULL = "null";
+
+    /**
+     * Static attribute for a dot string.
+     */
+    public static final String PERIOD = ".";
+
+    private static final int ONE = 1;
+    private static final String SCHEMA_NAME_IN_ENUM = "schemaName";
+    private static final String OPERATION_TYPE = "onosYangNodeOperationType";
+    private static final String STR_NONE = "NONE";
+    private static final String EQUALS = "=";
+    private static final String ENUM_LEAF_IDENTIFIER = "$LeafIdentifier";
+    private static final char CLOSE_BRACE = '}';
+    private static final Set<YangDataTypes> PRIMITIVE_TYPES =
+            new HashSet<>(Arrays.asList(INT8, INT16, INT32, INT64, UINT8,
+                                        UINT16, UINT32, UINT64, DECIMAL64,
+                                        BOOLEAN, EMPTY));
+
+    // No instantiation.
+    private YtbUtil() {
+    }
+
+    /**
+     * Returns the object of the node from the node info. Getting object for
+     * augment and case differs from other node.
+     *
+     * @param nodeInfo node info of the holder
+     * @param yangNode YANG node of the holder
+     * @return object of the parent
+     */
+    public static Object getParentObjectOfNode(YtbNodeInfo nodeInfo,
+                                               YangNode yangNode) {
+        Object object;
+        if (yangNode instanceof YangCase) {
+            object = nodeInfo.getCaseObject();
+        } else if (yangNode instanceof YangAugment) {
+            object = nodeInfo.getAugmentObject();
+        } else {
+            object = nodeInfo.getYangObject();
+        }
+        return object;
+    }
+
+    /**
+     * Returns the capital cased first letter of the given string.
+     *
+     * @param name string to be capital cased
+     * @return capital cased string
+     */
+    public static String getCapitalCase(String name) {
+        // TODO: It will be removed if common util is committed.
+        return name.substring(0, 1).toUpperCase() +
+                name.substring(1);
+    }
+
+    /**
+     * Returns the value of an attribute, in a class object. The attribute
+     * name is taken from the YANG node java name.
+     *
+     * @param nodeObj   object of the node
+     * @param fieldName name of the attribute
+     * @return object of the attribute
+     * @throws NoSuchMethodException method not found exception
+     */
+    public static Object getAttributeOfObject(Object nodeObj, String fieldName)
+            throws NoSuchMethodException {
+        Class<?> nodeClass = nodeObj.getClass();
+        Method getterMethod;
+        try {
+            getterMethod = nodeClass.getDeclaredMethod(fieldName);
+            return getterMethod.invoke(nodeObj);
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            throw new YtbException(e);
+        }
+    }
+
+    /**
+     * Returns the object of the declared method in parent class by invoking
+     * through the child class object.
+     *
+     * @param parentClass parent class of the declared method
+     * @param childClass  child class which inherits the parent class
+     * @param methodName  name of the declared method
+     * @return value of the method
+     */
+    public static Object getAttributeFromInheritance(
+            Class<?> parentClass, Object childClass, String methodName) {
+        Method getterMethod;
+        try {
+            getterMethod = parentClass.getDeclaredMethod(methodName);
+            return getterMethod.invoke(childClass);
+        } catch (InvocationTargetException | NoSuchMethodException |
+                IllegalAccessException e) {
+            throw new YtbException(e);
+        }
+    }
+
+    /**
+     * Returns interface class from an implementation class object.
+     *
+     * @param implClassObj implementation class object
+     * @return interface class
+     */
+    public static Class<?> getInterfaceClassFromImplClass(Object implClassObj) {
+        Class<?> implClass = implClassObj.getClass();
+        Class<?>[] interfaces = implClass.getInterfaces();
+        if (interfaces.length > ONE) {
+            // TODO: Need to handle when impl class has more than one interface.
+            throw new YtbException("Implementation class having more than one" +
+                                           " interface is not handled");
+        }
+        return interfaces[0];
+    }
+
+    /**
+     * Returns the operation type value for a class object. If the operation
+     * type is not set, then none type is returned.
+     *
+     * @param nodeObj node object
+     * @return operation type of the class
+     */
+    public static YdtContextOperationType getOperationTypeOfTheNode(
+            Object nodeObj) {
+        Object opTypeObj;
+        try {
+            opTypeObj = getAttributeOfObject(nodeObj, OPERATION_TYPE);
+        } catch (NoSuchMethodException e) {
+            return YdtContextOperationType.valueOf(STR_NONE);
+        }
+        String opTypeValue = String.valueOf(opTypeObj);
+        if (opTypeValue.equals(STR_NULL)) {
+            opTypeValue = STR_NONE;
+        }
+        return YdtContextOperationType.valueOf(opTypeValue);
+    }
+
+    /**
+     * Returns true, if data type of leaf is primitive data type; false
+     * otherwise.
+     *
+     * @param yangType leaf type
+     * @return true if data type is primitive; false otherwise
+     */
+    public static boolean isTypePrimitive(YangType yangType) {
+        if (yangType.getDataType() == LEAFREF) {
+            YangLeafRef leafRef =
+                    (YangLeafRef) yangType.getDataTypeExtendedInfo();
+            return isPrimitiveDataType(leafRef.getEffectiveDataType()
+                                               .getDataType());
+        }
+        return isPrimitiveDataType(yangType.getDataType());
+    }
+
+    /**
+     * Returns the registered class from the YSR of the module node where
+     * augment is present.
+     *
+     * @param curNode  current augment node
+     * @param registry schema registry
+     * @return class loader of module
+     */
+    public static Class<?> getClassLoaderForAugment(
+            YangNode curNode, YangSchemaRegistry registry) {
+        YangNode moduleNode = curNode.getParent();
+        String moduleName = moduleNode.getJavaClassNameOrBuiltInType();
+        String modulePackage = moduleNode.getJavaPackage();
+        return registry.getRegisteredClass(moduleNode,
+                                           modulePackage + PERIOD + moduleName);
+    }
+
+    /**
+     * Returns the string true, if the leaf data is actually set; false
+     * otherwise.
+     *
+     * @param nodeObj    object if the node
+     * @param javaName   java name of the leaf
+     * @param methodName getter method name
+     * @return string value of the boolean method
+     */
+    public static String isValueOrSelectLeafSet(
+            Object nodeObj, String javaName, String methodName) {
+
+        Class<?> nodeClass = nodeObj.getClass();
+        Class<?> interfaceClass = getInterfaceClassFromImplClass(nodeObj);
+
+        // Appends the enum inner package to the interface class package.
+        String enumPackage = interfaceClass.getName() + ENUM_LEAF_IDENTIFIER;
+
+        ClassLoader classLoader = interfaceClass.getClassLoader();
+        Class leafEnum;
+        try {
+            leafEnum = classLoader.loadClass(enumPackage);
+            Method getterMethod = nodeClass.getMethod(methodName, leafEnum);
+            // Gets the value of the enum.
+            Enum<?> value = Enum.valueOf(leafEnum, javaName.toUpperCase());
+            // Invokes the method with the value of enum as param.
+            return String.valueOf(getterMethod.invoke(nodeObj, value));
+        } catch (IllegalAccessException | InvocationTargetException |
+                NoSuchMethodException | ClassNotFoundException e) {
+            throw new YtbException(e);
+        }
+    }
+
+    /**
+     * Returns the string value from the respective data types of the
+     * leaf/leaf-list.
+     * // TODO: Remove this method and append to the data model utils.
+     *
+     * @param fieldObj object of the leaf/leaf-list field
+     * @param dataType type of the leaf/leaf-list
+     * @return string value from the type
+     */
+    public static String getStringFromDataType(Object fieldObj,
+                                               YangType dataType) {
+        YangDataTypes type = dataType.getDataType();
+        switch (type) {
+            case INT8:
+            case INT16:
+            case INT32:
+            case INT64:
+            case UINT8:
+            case UINT16:
+            case UINT32:
+            case UINT64:
+            case EMPTY:
+            case IDENTITYREF:
+            case STRING:
+            case DECIMAL64:
+            case INSTANCE_IDENTIFIER:
+            case DERIVED:
+            case UNION:
+                //TODO: Generated code has to be changed, it must select
+                // the setting leaf and it must give back the corresponding
+                // toString of that type.
+            case BOOLEAN:
+            case BITS:
+                return getValueFromToStringHelper(String.valueOf(fieldObj));
+
+            case BINARY:
+                return Base64.getEncoder().encodeToString((byte[]) fieldObj);
+
+            case LEAFREF:
+                YangLeafRef leafRef =
+                        (YangLeafRef) dataType.getDataTypeExtendedInfo();
+                return getStringFromDataType(fieldObj,
+                                             leafRef.getEffectiveDataType());
+
+            case ENUMERATION:
+                Object value;
+                try {
+                    value = getAttributeOfObject(fieldObj, SCHEMA_NAME_IN_ENUM);
+                } catch (NoSuchMethodException e) {
+                    throw new YtbException(e);
+                }
+                return getValueFromToStringHelper(String.valueOf(value));
+
+            default:
+                throw new YtbException("Unsupported data type. Cannot be " +
+                                               "processed.");
+        }
+    }
+
+    /**
+     * Returns the value, from the toString value which uses toStringHelper.
+     * It gives values in non-usable format(e.g., {value = 5}). But the value
+     * that has to be returned is only 5.So it parses the string and returns
+     * only the value. In certain toString, to string helper is not used, so
+     * the original value is sent without parsing.
+     *
+     * @param rawString raw string
+     * @return parsed value
+     */
+    private static String getValueFromToStringHelper(String rawString) {
+        if (rawString.contains(EQUALS)) {
+            int index = rawString.lastIndexOf(EQUALS);
+            int braceIndex = rawString.indexOf(CLOSE_BRACE);
+            if (index != -1) {
+                return rawString.substring(index + 1, braceIndex);
+            }
+        }
+        return rawString;
+    }
+
+    /**
+     * Returns true, if the data type is primitive; false otherwise.
+     *
+     * @param dataType data type
+     * @return true if the data type is primitive; false otherwise
+     */
+    private static boolean isPrimitiveDataType(YangDataTypes dataType) {
+        return PRIMITIVE_TYPES.contains(dataType);
+    }
+
+    /**
+     * Returns true, if processing of the node is not required; false otherwise.
+     * For the nodes such as notification, RPC, augment there is a different
+     * flow, so these nodes are skipped in normal conditions.
+     *
+     * @param yangNode node to be checked
+     * @return true if node processing is not required; false otherwise.
+     */
+    public static boolean isNonProcessableNode(YangNode yangNode) {
+        return yangNode != null && (yangNode instanceof YangNotification) ||
+                (yangNode instanceof YangRpc) || (yangNode instanceof YangAugment);
+    }
+
+    /**
+     * Returns true, if multi instance node; false otherwise.
+     *
+     * @param yangNode YANG node
+     * @return true, if multi instance node; false otherwise.
+     */
+    public static boolean isMultiInstanceNode(YangNode yangNode) {
+        return yangNode.getYangSchemaNodeType() == YANG_MULTI_INSTANCE_NODE;
+    }
+
+    /**
+     * Returns true, if augment node; false otherwise.
+     *
+     * @param yangNode YANG node
+     * @return true, if augment node; false otherwise.
+     */
+    public static boolean isAugmentNode(YangNode yangNode) {
+        return yangNode.getYangSchemaNodeType() == YANG_AUGMENT_NODE;
+    }
+
+    /**
+     * Returns string for throwing error when empty object is given as input
+     * to YTB.
+     *
+     * @param objName name of the object
+     * @return error message
+     */
+    public static String emptyObjErrMsg(String objName) {
+        return "The " + objName + " given for tree creation cannot be null";
+    }
+
+    /**
+     * Returns the java name for the nodes, leaf/leaf-list.
+     *
+     * @param node YANG node
+     * @return node java name
+     */
+    public static String getJavaName(Object node) {
+        return ((JavaLeafInfoContainer) node).getJavaName(null);
+    }
+
+    /**
+     * Returns true, if the list is not null and non-empty; false otherwise.
+     *
+     * @param object list object
+     * @return true, if the list is not null and non-empty; false otherwise
+     */
+    public static boolean isNonEmpty(List object) {
+        return object != null && !object.isEmpty();
+    }
+
+    /**
+     * Returns true, if the string is not null and non-empty; false otherwise.
+     *
+     * @param str string value
+     * @return true, if the string is not null and non-empty; false otherwise.
+     */
+    public static boolean isNonEmpty(String str) {
+        return str != null && !str.isEmpty();
+    }
+
+    /**
+     * Returns true when the node processing of RPC and notification is
+     * completed; false otherwise. For RPC and notification, processing of
+     * other nodes are invalid, so once node gets completed, it must be stopped.
+     *
+     * @param curNode      current node
+     * @param curTraversal current traversal of the node
+     * @return true, if the node processing is completed; false otherwise.
+     */
+    public static boolean isNodeProcessCompleted(
+            YangNode curNode, TraversalType curTraversal) {
+        return (curTraversal == PARENT &&
+                curNode instanceof YangNotification) ||
+                curNode instanceof YangOutput;
+    }
+
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/package-info.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/package-info.java
new file mode 100644
index 0000000..1a4a827
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides implementation of YANG tree builder. YTB handles creation of YDT
+ * from YANG modeled objects.
+ */
+package org.onosproject.yms.app.ytb;