diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YangRequestWorkBench.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YangRequestWorkBench.java
new file mode 100644
index 0000000..5ae1230
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YangRequestWorkBench.java
@@ -0,0 +1,758 @@
+/*
+ * 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.ydt;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
+import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.ydt.YdtContext;
+import org.onosproject.yms.ydt.YdtContextOperationType;
+import org.onosproject.yms.ydt.YdtType;
+import org.onosproject.yms.ydt.YmsOperationType;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_MULTI_INSTANCE_LEAF_NODE;
+import static org.onosproject.yms.app.ydt.AppNodeFactory.getAppContext;
+import static org.onosproject.yms.app.ydt.RequestedCallType.LEAF;
+import static org.onosproject.yms.app.ydt.RequestedCallType.OTHER;
+import static org.onosproject.yms.app.ydt.RequestedCardinality.MULTI_INSTANCE;
+import static org.onosproject.yms.app.ydt.RequestedCardinality.MULTI_INSTANCE_LEAF;
+import static org.onosproject.yms.app.ydt.RequestedCardinality.SINGLE_INSTANCE;
+import static org.onosproject.yms.app.ydt.RequestedCardinality.UNKNOWN;
+import static org.onosproject.yms.app.ydt.YdtConstants.errorMsg;
+import static org.onosproject.yms.app.ydt.YdtNodeFactory.getAppOpTypeFromYdtOpType;
+import static org.onosproject.yms.ydt.YdtContextOperationType.CREATE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.MERGE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.REMOVE;
+import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_LEAF_VALUE_NODE;
+import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_NODE;
+
+/**
+ * Represents YANG request work bench which contains all parameters for
+ * request handling and methods to build and obtain YANG data tree
+ * which is data (sub)instance representation, abstract of protocol.
+ */
+public class YangRequestWorkBench implements YdtExtendedBuilder {
+
+    // ydt formatted error string
+    private static final String FMT_NOT_EXIST =
+            "Application with name \"%s\" doesn't exist.";
+    private static final String E_USE_ADDLEAF =
+            "Requested Node should be created using addLeaf interface";
+    private static final String E_MULTI_INS =
+            "Adds an instance of type list or leaf-list node only";
+    private static final String E_CREATE =
+            "Create request is not allowed under delete operation";
+    private static final String E_DEL =
+            "Delete request is not allowed under create operation";
+    private static final String E_INVOKE_PARENT =
+            "Can't invoke get parent at logical root node";
+    private static final String FMT_TOO_FEW =
+            "Too few key parameters in %s. Expected %d; actual %d.";
+    private static final String FMT_TOO_MANY =
+            "Too many key parameters in %s. Expected %d; actual %d.";
+
+    /*
+     * Current node in YANG data tree, kept to maintain the
+     * current context in YDT.
+     */
+    private YdtNode curNode;
+
+    /*
+     * Root node in YANG data tree, kept to maintain the root context in
+     * YDT.
+     */
+    private YdtNode rootNode;
+
+    /*
+     * Current node in YANG data tree, kept to maintain the current context
+     * in ydt application tree.
+     */
+    private YdtAppContext appCurNode;
+
+    /*
+     * Root node in YANG data tree, kept to maintain the root context in ydt
+     * application tree.
+     */
+    private YdtAppContext appRootNode;
+
+    /**
+     * Root Node Tag attribute in YANG data tree, kept to maintain the root
+     * tag attributes in YDT.
+     * <p>
+     * First key param of map represent tagName  name of tag attribute.
+     * Second param of map represent tagValue value of tag attribute
+     */
+    private Map<String, String> rootTagAttributeMap;
+
+    /*
+     * YANG schema registry reference.
+     */
+    private YangSchemaRegistry registry = null;
+
+    /*
+     * YMS operation type.
+     */
+    private final YmsOperationType ymsOperationType;
+
+    /*
+     * YDT default operation type.
+     */
+    private YdtContextOperationType ydtDefaultOpType;
+
+    /*
+     * Flag to identify data validation need to be done by YDT or not.
+     */
+    private final boolean validate;
+    // TODO validate need to be handle later with interaction type basis in
+    // future when it will be supported
+
+
+    /**
+     * Creates an instance of YANG request work bench which is use to initialize
+     * logical rootNode and and schema registry.
+     *
+     * @param name       name of logical container of a protocol
+     *                   which is a holder of the complete tree
+     * @param namespace  namespace of logical container
+     * @param opType     type of operation done by using YANG
+     *                   interface
+     * @param registry   Yang schema registry
+     * @param isValidate Flag to identify data validation need to be
+     *                   done by YDT or not
+     */
+    public YangRequestWorkBench(String name, String namespace,
+                                YmsOperationType opType,
+                                YangSchemaRegistry registry,
+                                boolean isValidate) {
+        YdtNode newNode;
+        YangSchemaNodeIdentifier nodeIdentifier =
+                new YangSchemaNodeIdentifier();
+        nodeIdentifier.setName(name);
+        nodeIdentifier.setNameSpace(namespace);
+        newNode = new YdtSingleInstanceNode(nodeIdentifier);
+        setRootNode(newNode);
+        this.registry = registry;
+        ymsOperationType = opType;
+        validate = isValidate;
+        // Set the logical root node for yang data app tree.
+        DefaultYdtAppContext appNode = getAppContext(true);
+
+        setAppRootNode(appNode);
+    }
+
+    /**
+     * Sets the logical root context information available in YDT node.
+     *
+     * @param node logical root node
+     */
+    private void setRootNode(YdtNode node) {
+        rootNode = node;
+        curNode = node;
+    }
+
+    /**
+     * Sets the app context tree logical root node  for ydt application tree.
+     *
+     * @param node application tree's logical root node
+     */
+    private void setAppRootNode(YdtAppContext node) {
+        appRootNode = node;
+        appCurNode = node;
+    }
+
+    /**
+     * Returns the YANG schema registry of Ydt.
+     * This method will be used by ytb.
+     *
+     * @return YANG schema registry
+     */
+    public YangSchemaRegistry getYangSchemaRegistry() {
+        return registry;
+    }
+
+    /**
+     * Returns the app context tree root node for ydt application tree.
+     * This method will be used by yab.
+     *
+     * @return YdtAppContext refers to root node of ydt application tree
+     */
+    public YdtAppContext getAppRootNode() {
+        return appRootNode;
+    }
+
+    /**
+     * Returns the data tree for given node identifier.
+     *
+     * @param id        Represents node identifier of YANG data tree node
+     * @param namespace namespace of the application requested by user
+     * @return YANG data tree node
+     */
+    private YdtNode moduleHandler(YangSchemaNodeIdentifier id,
+                                  String namespace) {
+
+        YangSchemaNode node = registry
+                .getYangSchemaNodeUsingSchemaName(id.getName());
+
+        if (node == null ||
+                namespace != null && !namespace.equals(node.getNameSpace())) {
+            curNode.errorHandler(errorMsg(
+                    FMT_NOT_EXIST, id.getName()), rootNode);
+        }
+
+        YdtNode newNode = new YdtSingleInstanceNode(id);
+        newNode.setYangSchemaNode(node);
+        id.setNameSpace(node.getNameSpace());
+        return newNode;
+    }
+
+    @Override
+    public void setRootTagAttributeMap(Map<String, String> attributeTag) {
+        rootTagAttributeMap = attributeTag;
+    }
+
+    @Override
+    public Map<String, String> getRootTagAttributeMap() {
+        if (rootTagAttributeMap != null) {
+            return ImmutableMap.copyOf(rootTagAttributeMap);
+        }
+        return null;
+    }
+
+    @Override
+    public void addChild(String name, String namespace) {
+        addChild(name, namespace, UNKNOWN, null, OTHER);
+    }
+
+    @Override
+    public void addChild(String name, String namespace, YdtType ydtType) {
+        addChild(name, namespace, ydtType, null);
+    }
+
+    @Override
+    public void addChild(String name, String namespace,
+                         YdtContextOperationType opType) {
+        addChild(name, namespace, UNKNOWN, opType, OTHER);
+    }
+
+    @Override
+    public void addChild(String name, String namespace, YdtType ydtType,
+                         YdtContextOperationType opType) {
+        RequestedCardinality cardinality = null;
+        switch (ydtType) {
+            case MULTI_INSTANCE_NODE:
+                cardinality = MULTI_INSTANCE;
+                break;
+            case SINGLE_INSTANCE_NODE:
+                cardinality = SINGLE_INSTANCE;
+                break;
+            default:
+                curNode.errorHandler(E_USE_ADDLEAF, rootNode);
+        }
+        addChild(name, namespace, cardinality, opType, OTHER);
+    }
+
+    /**
+     * Adds a last child to YANG data tree; this method is to be used by all
+     * protocols internally which are aware or unaware of the nature
+     * (single/multiple) of node.
+     *
+     * @param name        name of child to be added
+     * @param namespace   namespace of child to be added
+     * @param cardinality type of YANG data tree node operation
+     * @param opType      type of requested operation over a node
+     * @param callType    to identify the whether its a leaf or other node
+     */
+    private void addChild(String name, String namespace,
+                          RequestedCardinality cardinality,
+                          YdtContextOperationType opType,
+                          RequestedCallType callType) {
+
+        YdtNode childNode;
+        boolean isContextSwitch = false;
+        YangSchemaNode schemaNode = null;
+        YangSchemaNodeContextInfo contextInfo;
+        YangSchemaNode augmentingSchema = null;
+
+        YangSchemaNodeIdentifier id = new YangSchemaNodeIdentifier();
+        id.setName(name);
+
+        // Module/sub-module node handler.
+        if (curNode.equals(rootNode)) {
+            childNode = moduleHandler(id, namespace);
+        } else {
+
+            // If namespace given by user null, then take namespace from parent.
+            if (namespace == null) {
+                namespace = curNode.getYdtNodeIdentifier().getNameSpace();
+            }
+
+            id.setNameSpace(namespace);
+
+            /*
+             * Get the already exiting YDT node in YDT tree with same
+             * nodeIdentifier
+             */
+            childNode = curNode.getCollidingChild(id);
+
+            /*
+             * If colliding child doesn't exist ,
+             * then query yang data model for schema of given node.
+             */
+            if (childNode == null) {
+                /*
+                 * Get Yang Schema node context info which is having
+                 * YangSchemaNode and ContextSwitchedNode.
+                 */
+                contextInfo = curNode.getSchemaNodeContextInfo(id);
+
+                if (contextInfo.getContextSwitchedNode() != null) {
+                    augmentingSchema = appCurNode.getAugmentingSchemaNode(
+                            id, contextInfo);
+                    if (augmentingSchema != null) {
+                        /*
+                         * As two tree(YDT and YDT Application Tree) are getting
+                         * prepared in parallel, So  setting context switch
+                         * flag it will help ydt to keep the track whether
+                         * ydtApp tree also need to be traversed back to parent
+                         * or not with YDT tree traverse to parent call.
+                         */
+                        isContextSwitch = true;
+                    }
+                }
+                schemaNode = contextInfo.getSchemaNode();
+            } else {
+                /*
+                 * If colliding child exist , then will be leaf-list or list
+                 * If its leaf-list then return and add new requested
+                 * value/valueSet in same node else take yang data model
+                 * information from colliding child.
+                 */
+                if (childNode.getYdtType() == MULTI_INSTANCE_LEAF_VALUE_NODE) {
+                    curNode = childNode;
+                    return;
+                }
+                schemaNode = childNode.getYangSchemaNode();
+            }
+            childNode = YdtNodeFactory.getNode(id, schemaNode, cardinality,
+                                               callType);
+        }
+
+        opType = getValidOpType(opType, callType, schemaNode);
+
+        childNode.setYdtContextOperationType(opType);
+
+        curNode.addChild(childNode, true);
+
+        // Update parent ydt node map.
+        curNode.updateYdtMap(id, childNode);
+
+        processAppTree(opType, childNode, augmentingSchema, isContextSwitch);
+
+        // Updating the curNode.
+        curNode = childNode;
+    }
+
+    /**
+     * Processes application tree on the bases of requested ydt node.
+     *
+     * @param opType           user requested operation type
+     * @param childNode        requested ydt node
+     * @param augmentingSchema schema of last augmenting node
+     * @param isContextSwitch  true, for module node call; false for modules
+     *                         sub-node calls
+     */
+    private void processAppTree(
+            YdtContextOperationType opType, YdtNode childNode,
+            YangSchemaNode augmentingSchema, boolean isContextSwitch) {
+
+        if (augmentingSchema != null) {
+            if (!appCurNode.addSchemaToAppSet(augmentingSchema)) {
+                return;
+            }
+        }
+        if (opType == null) {
+            opType = curNode.getYdtContextOperationType();
+        } else {
+            // Updating operation type for parent nodes
+            appCurNode.updateAppOperationType(opType);
+        }
+
+        /*
+         * Create entry of module node in ydt app tree.
+         * Or if context switch happened then also add entry for same ydt
+         * node in the ydt application tree.
+         */
+        if (curNode.equals(rootNode) || isContextSwitch) {
+            addChildInAppTree(childNode, augmentingSchema, opType,
+                              isContextSwitch);
+
+            // Setting app tree node operation.
+            appCurNode.setOperationType(getAppOpTypeFromYdtOpType(opType));
+        }
+
+        // Updating the delete operation list in app tree.
+        if (opType == DELETE || opType == REMOVE) {
+            appCurNode.addDeleteNode(childNode);
+        }
+    }
+
+    /**
+     * Returns the valid operation type for requested ydt node after performing
+     * validation.
+     *
+     * @param opType     user requested operation type
+     * @param callType   to identify the whether its a leaf or other node
+     * @param schemaNode schema node of user requested ydt node
+     * @return operation type
+     */
+    private YdtContextOperationType getValidOpType(
+            YdtContextOperationType opType, RequestedCallType callType,
+            YangSchemaNode schemaNode) {
+
+        // Operation type not supported for leaf node.
+        if (callType == LEAF || (callType == RequestedCallType.MULTI_INSTANCE &&
+                schemaNode.getYangSchemaNodeType() ==
+                        YANG_MULTI_INSTANCE_LEAF_NODE)) {
+            return null;
+        }
+
+        // Reference for parent node operation type.
+        YdtContextOperationType parentOpType = curNode
+                .getYdtContextOperationType();
+
+        if (opType != null && parentOpType != null) {
+            validateOperationType(parentOpType, opType);
+        } else if (opType == null) {
+            opType = getOperationType(parentOpType);
+        }
+        return opType;
+    }
+
+    /**
+     * Returns the operation type for non leaf node.
+     * When "operation" attribute for current node is not specified or null,
+     * then the operation applied to the parent data node of the
+     * configuration is used. If no parent data node is available,
+     * then the default-operation'value is used.
+     * If default operation type is not set, merge will be taken as default
+     * operation type.
+     *
+     * @param parentOpType operation type of parent node
+     * @return operation type for current non leaf node
+     */
+    private YdtContextOperationType getOperationType(
+            YdtContextOperationType parentOpType) {
+
+        return parentOpType != null ? parentOpType :
+                (ydtDefaultOpType != null ? ydtDefaultOpType : MERGE);
+    }
+
+    /**
+     * Adds a last child to YANG app data tree.this method is to be used
+     * internally by other ydt interfaces.
+     *
+     * @param childNode       node to be added in tree
+     * @param schemaNode      last augmenting module node
+     * @param childOpType     operation type of node
+     * @param isContextSwitch true, for module node call; false for modules
+     *                        sub-node calls
+     */
+    private void addChildInAppTree(YdtNode childNode,
+                                   YangSchemaNode schemaNode,
+                                   YdtContextOperationType childOpType,
+                                   boolean isContextSwitch) {
+
+        YdtAppNodeOperationType opType;
+
+        DefaultYdtAppContext appContext = getAppContext(isContextSwitch);
+
+        // Add context switched child in ydt App tree.
+        appCurNode.addChild(appContext);
+        //Updating the curNode.
+        appCurNode = appContext;
+
+        // Get the app tree operation type from ydt operation type.
+        opType = getAppOpTypeFromYdtOpType(childOpType);
+
+        appCurNode.setAppData(childNode, schemaNode);
+
+        appCurNode.setOperationType(opType);
+
+        childNode.setAppContextSwitch();
+    }
+
+    /**
+     * Validates the various combination of operation type.
+     *
+     * @param parentOpType Reference for parent node operation type
+     * @param childOpType  type of YANG data tree node operation
+     */
+    private void validateOperationType(YdtContextOperationType parentOpType,
+                                       YdtContextOperationType childOpType) {
+
+        switch (parentOpType) {
+            case CREATE:
+                // Inside the create operation delete operation should not come.
+                if (childOpType == DELETE) {
+                    curNode.errorHandler(E_CREATE, rootNode);
+                }
+                break;
+            case DELETE:
+                // Inside the delete operation create operation should not come.
+                if (childOpType == CREATE) {
+                    curNode.errorHandler(E_DEL, rootNode);
+                }
+                break;
+            default:
+                //TODO check all possible scenario.
+        }
+    }
+
+    @Override
+    public void addLeaf(String name, String namespace, String value) {
+        addLeaf(name, namespace, value, null, UNKNOWN);
+    }
+
+    @Override
+    public void addLeaf(String name, String namespace, Set<String> valueSet) {
+        addLeaf(name, namespace, null, valueSet, MULTI_INSTANCE_LEAF);
+    }
+
+    /**
+     * Adds a last leaf with list of values/single value to YANG data tree.
+     * This method is used by all protocols which knows the nature
+     * (single/multiple) or not.
+     * Value of leaf can be null which indicates selection node in get
+     * operation.
+     *
+     * @param name        name of child to be added
+     * @param namespace   namespace of child to be added, if it's
+     *                    null, parent's
+     *                    namespace will be applied to child
+     * @param value       value of the child
+     * @param valueSet    list of value of the child
+     * @param cardinality type of YANG data tree node operation
+     */
+    private void addLeaf(String name, String namespace, String value,
+                         Set<String> valueSet,
+                         RequestedCardinality cardinality) {
+        addChild(name, namespace, cardinality, null, LEAF);
+
+        // After successful addition of child node updating the values in same.
+        if (value != null) {
+            curNode.addValue(value);
+        } else if (valueSet != null) {
+            curNode.addValueSet(valueSet);
+        }
+    }
+
+    @Override
+    public void traverseToParent() {
+        // If traverse back to parent for logical root node comes
+        if (curNode.equals(rootNode)) {
+            curNode.errorHandler(E_INVOKE_PARENT, rootNode);
+        }
+
+        // If node is of multiInstanceNode type then check key uniqueness.
+        if (curNode.getYdtType() == MULTI_INSTANCE_NODE) {
+            curNode.createKeyNodeList();
+        }
+
+        /*
+         * Check application switch for curNode if set,
+         * then traverseToParent in YDT application tree.
+         */
+        if (curNode.getParent().equals(rootNode) ||
+                curNode.getAppContextSwitch()) {
+            traverseToAppTreeParent();
+        }
+
+        /*
+         * Validate all multi Instance inside current context,
+         * This is not valid for leaf and leaf-list node.
+         */
+        if (curNode instanceof YdtMultiInstanceNode ||
+                curNode instanceof YdtSingleInstanceNode) {
+            curNode.validateMultiInstanceNode();
+        }
+
+        curNode = curNode.getParent();
+    }
+
+    /**
+     * Traverses up in YANG application tree to the parent node,
+     * This will be used when Ydt current context switch flag is set.
+     */
+    private void traverseToAppTreeParent() {
+        appCurNode = appCurNode.getParent();
+    }
+
+    @Override
+    public YdtContext getCurNode() {
+        return curNode;
+    }
+
+    @Override
+    public void setDefaultEditOperationType(
+            YdtContextOperationType opType) {
+        ydtDefaultOpType = opType;
+    }
+
+    @Override
+    public YdtExtendedContext getRootNode() {
+        return rootNode;
+    }
+
+    @Override
+    public YmsOperationType getYmsOperationType() {
+        return ymsOperationType;
+    }
+
+    @Override
+    public void addMultiInstanceChild(String name, String namespace,
+                                      List<String> keysValueList,
+                                      YdtContextOperationType opType) {
+        addChild(name, namespace, UNKNOWN, opType,
+                 RequestedCallType.MULTI_INSTANCE);
+        int inputCount = keysValueList.size();
+        int expectedCount;
+        if (curNode.getYdtType() == MULTI_INSTANCE_LEAF_VALUE_NODE) {
+            // After successful addition of child node updating
+            // the values in same.
+            // inputCount = curNode.getValueSet().size() + inputCount;
+            // checkElementCount(expectedCount, inputCount);
+            // TODO check the element count
+            for (String value : keysValueList) {
+                curNode.addValue(value);
+            }
+        } else if (curNode.getYdtType() == MULTI_INSTANCE_NODE) {
+            YangList yangListHolder = (YangList) curNode.getYangSchemaNode();
+            List<String> schemaKeyList = yangListHolder.getKeyList();
+            expectedCount = schemaKeyList.size();
+            checkElementCount(name, expectedCount, inputCount);
+
+            Iterator<String> sklIter = schemaKeyList.iterator();
+            Iterator<String> kvlIter = keysValueList.iterator();
+            String keyEleName;
+            while (kvlIter.hasNext()) {
+                String value = kvlIter.next();
+                keyEleName = sklIter.next();
+                addLeaf(keyEleName, namespace, value);
+                if (kvlIter.hasNext()) {
+                    traverseToParentWithoutValidation();
+                }
+            }
+            curNode = curNode.getParent();
+        } else {
+            curNode.errorHandler(E_MULTI_INS, rootNode);
+        }
+    }
+
+    /**
+     * Checks the user supplied list of argument match's the expected value
+     * or not.
+     *
+     * @param name     name of the parent list/leaf-list node
+     * @param expected count suppose to be
+     * @param actual   user supplied values count
+     */
+    private void checkElementCount(String name, int expected,
+                                   int actual) {
+        if (expected < actual) {
+            curNode.errorHandler(errorMsg(FMT_TOO_MANY, name, expected, actual),
+                                 rootNode);
+        } else if (expected > actual) {
+            curNode.errorHandler(errorMsg(FMT_TOO_FEW, name, expected, actual),
+                                 rootNode);
+        }
+    }
+
+    /**
+     * Adds a last child to YANG data tree, this method is to be used by
+     * YANG object builder sub-calls internally.
+     *
+     * @param opType type of requested operation over a node
+     * @return returns added ydt node in YDT tree
+     */
+    private YdtNode addExtendedChildNode(YdtContextOperationType opType,
+                                         YangSchemaNode schemaNode) {
+
+        YdtNode childNode;
+        YangSchemaNodeIdentifier id =
+                schemaNode.getYangSchemaNodeIdentifier();
+
+        childNode = YdtNodeFactory
+                .getYangSchemaNodeTypeSpecificContext(
+                        id, schemaNode.getYangSchemaNodeType());
+
+        childNode.setId(id);
+
+        childNode.setYangSchemaNode(schemaNode);
+
+        childNode.setYdtContextOperationType(opType);
+
+        curNode.addChild(childNode, true);
+
+        curNode = childNode;
+
+        return childNode;
+    }
+
+    @Override
+    public YdtExtendedContext addChild(YdtContextOperationType opType,
+                                       YangSchemaNode schemaNode) {
+        return addExtendedChildNode(opType, schemaNode);
+    }
+
+    @Override
+    public YdtExtendedContext addLeafList(Set<String> valueSet,
+                                          YangSchemaNode schemaNode) {
+        YdtNode childNode = addExtendedChildNode(null, schemaNode);
+
+        // After successful addition of child node updating the values in same.
+        childNode.addValueSetWithoutValidation(valueSet);
+        return childNode;
+    }
+
+    @Override
+    public YdtExtendedContext addLeaf(String value,
+                                      YangSchemaNode schemaNode) {
+        YdtNode childNode = addExtendedChildNode(null, schemaNode);
+
+        // After successful addition of child node updating the values in same.
+        childNode.addValueWithoutValidation(value);
+        return childNode;
+    }
+
+    @Override
+    public void traverseToParentWithoutValidation() {
+        // If traverse back to parent for logical root node comes
+        if (curNode.equals(rootNode)) {
+            curNode.errorHandler(E_INVOKE_PARENT, rootNode);
+        }
+        curNode = curNode.getParent();
+    }
+}
