diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/YangApplicationBroker.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/YangApplicationBroker.java
new file mode 100644
index 0000000..cb6f7d7
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/YangApplicationBroker.java
@@ -0,0 +1,872 @@
+/*
+ * 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.yab;
+
+import org.onosproject.yangutils.datamodel.YangAugment;
+import org.onosproject.yangutils.datamodel.YangAugmentableNode;
+import org.onosproject.yangutils.datamodel.YangInput;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangRpc;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+import org.onosproject.yms.app.utils.TraversalType;
+import org.onosproject.yms.app.yab.exceptions.YabException;
+import org.onosproject.yms.app.ydt.DefaultYdtAppContext;
+import org.onosproject.yms.app.ydt.YangRequestWorkBench;
+import org.onosproject.yms.app.ydt.YangResponseWorkBench;
+import org.onosproject.yms.app.ydt.YdtAppContext;
+import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.ydt.YdtMultiInstanceNode;
+import org.onosproject.yms.app.ydt.YdtNode;
+import org.onosproject.yms.app.yob.DefaultYobBuilder;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.app.ytb.DefaultYangTreeBuilder;
+import org.onosproject.yms.ydt.YdtBuilder;
+import org.onosproject.yms.ydt.YdtContext;
+import org.onosproject.yms.ydt.YdtResponse;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+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.AppNodeFactory.getAppContext;
+import static org.onosproject.yms.app.ydt.YdtAppNodeOperationType.DELETE_ONLY;
+import static org.onosproject.yms.app.ydt.YdtAppNodeOperationType.OTHER_EDIT;
+import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
+import static org.onosproject.yms.ydt.YmsOperationExecutionStatus.EXECUTION_SUCCESS;
+
+/**
+ * Represents YANG application broker. It acts as a broker between Protocol and
+ * YANG based application.
+ */
+public class YangApplicationBroker {
+
+    private static final String GET = "get";
+    private static final String SET = "set";
+    private static final String AUGMENTED = "Augmented";
+    private static final String VOID = "void";
+    private final YangSchemaRegistry schemaRegistry;
+
+    /**
+     * Creates a new YANG application broker.
+     *
+     * @param schemaRegistry YANG schema registry
+     */
+    public YangApplicationBroker(YangSchemaRegistry schemaRegistry) {
+        this.schemaRegistry = schemaRegistry;
+    }
+
+    /**
+     * Processes query request of a NBI protocol.
+     *
+     * @param ydtWorkBench YANG request work bench
+     * @return YANG response data tree node context
+     * @throws YabException violation in execution of YAB
+     */
+    public YdtResponse processQuery(YdtBuilder ydtWorkBench)
+            throws YabException {
+        List<Object> responseObjects = new LinkedList<>();
+        YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
+
+        for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
+             appContext != null; appContext = appContext.getNextSibling()) {
+            Object responseObject = processQueryOfApplication(appContext);
+            responseObjects.add(responseObject);
+        }
+
+        YdtContext rootYdtContext = workBench.getRootNode();
+        YdtBuilder responseYdt = buildResponseYdt(responseObjects,
+                                                  rootYdtContext.getName(),
+                                                  rootYdtContext.getNamespace());
+
+        return new YangResponseWorkBench(responseYdt.getRootNode(),
+                                         EXECUTION_SUCCESS,
+                                         ydtWorkBench.getYmsOperationType());
+    }
+
+    /**
+     * Processes edit request of a NBI protocol.
+     *
+     * @param ydtWorkBench YANG request work bench
+     * @return YANG response data tree node context
+     * @throws YabException               violation in execution of YAB
+     * @throws CloneNotSupportedException clone is not supported
+     */
+    public YdtResponse processEdit(YdtBuilder ydtWorkBench)
+            throws CloneNotSupportedException, YabException {
+        YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
+
+        for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
+             appContext != null; appContext = appContext.getNextSibling()) {
+            processEditOfApplication(appContext);
+        }
+
+        /*
+         * Since for set operation return type is void, there will not be
+         * response ydt tree so returning null.
+         */
+        return new YangResponseWorkBench(null, EXECUTION_SUCCESS,
+                                         workBench.getYmsOperationType());
+    }
+
+    /**
+     * Processes operation request of a NBI protocol.
+     *
+     * @param ydtWorkBench YANG request work bench
+     * @return YANG response data tree node context
+     * @throws YabException violation in execution of YAB
+     */
+    public YdtResponse processOperation(YdtBuilder ydtWorkBench)
+            throws YabException {
+        YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
+        YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
+        YdtContext ydtNode = appContext.getModuleContext();
+        while (ydtNode != null) {
+            YdtContext childYdtNode = ydtNode.getFirstChild();
+            YangSchemaNode yangNode = ((YdtNode) childYdtNode).getYangSchemaNode();
+            if (yangNode instanceof YangRpc) {
+                return processRpcOperationOfApplication(childYdtNode,
+                                                        appContext, yangNode,
+                                                        workBench);
+            }
+            ydtNode = ydtNode.getNextSibling();
+        }
+        return new YangResponseWorkBench(null, EXECUTION_SUCCESS,
+                                         ydtWorkBench.getYmsOperationType());
+    }
+
+    /**
+     * Processes rpc request of an application.
+     *
+     * @param appContext application context
+     * @return response object from application
+     */
+    private YdtResponse processRpcOperationOfApplication(YdtContext rpcYdt,
+                                                         YdtAppContext appContext,
+                                                         YangSchemaNode yangRpc,
+                                                         YangRequestWorkBench workBench)
+            throws YabException {
+        Object inputObject = null;
+        YdtContext inputYdtNode = getInputYdtNode(rpcYdt);
+        if (inputYdtNode != null) {
+            inputObject = getYangObject(inputYdtNode);
+        }
+
+        Object appObject = getApplicationObjectForRpc(appContext);
+
+        String methodName = yangRpc.getJavaClassNameOrBuiltInType();
+        Object outputObject = invokeRpcApplicationsMethod(appObject,
+                                                          inputObject,
+                                                          methodName);
+
+        String returnType = getReturnTypeOfRpcResponse(appObject,
+                                                       inputObject, yangRpc);
+
+        if (!returnType.equals(VOID)) {
+            YdtBuilder responseYdt = buildRpcResponseYdt(outputObject,
+                                                         workBench);
+            return new YangResponseWorkBench(responseYdt.getRootNode(),
+                                             EXECUTION_SUCCESS,
+                                             workBench.getYmsOperationType());
+        }
+
+        return new YangResponseWorkBench(null, EXECUTION_SUCCESS,
+                                         workBench.getYmsOperationType());
+    }
+
+    /**
+     * Processes query request of an application.
+     *
+     * @param appContext application context
+     * @return response object from application
+     */
+    private Object processQueryOfApplication(YdtAppContext appContext)
+            throws YabException {
+        YdtContext ydtNode = appContext.getModuleContext();
+
+        // Update application context tree if any node is augmented
+        YangNode yangNode = (YangNode) appContext.getYangSchemaNode();
+        if (yangNode.isDescendantNodeAugmented()) {
+            processAugmentForChildNode(appContext, yangNode);
+        }
+
+        String appName = getCapitalCase(((YdtNode) appContext.getModuleContext())
+                                                .getYangSchemaNode()
+                                                .getJavaClassNameOrBuiltInType());
+
+        // get YangObject of YdtContext from YOB
+        Object outputObject = getYangObject(ydtNode);
+
+        TraversalType curTraversal = ROOT;
+        do {
+            if (curTraversal != PARENT) {
+
+                // find application and get application's object using YSR
+                Object appManagerObject = getApplicationObject(appContext);
+
+                // find which method to invoke
+                String methodName = getApplicationMethodName(appContext,
+                                                             appName, GET);
+
+                // invoke application's getter method
+                outputObject = invokeApplicationsMethod(appManagerObject,
+                                                        outputObject,
+                                                        methodName);
+            }
+
+            /*
+             * AppContext may contain other nodes if it is augmented, so
+             * traverse the appContext tree
+             */
+            if (curTraversal != PARENT && appContext.getFirstChild() != null) {
+                curTraversal = CHILD;
+                appContext = appContext.getFirstChild();
+            } else if (appContext.getNextSibling() != null) {
+                curTraversal = SIBLING;
+                appContext = appContext.getNextSibling();
+            } else {
+                curTraversal = PARENT;
+                if (appContext.getParent().getParent() != null) {
+                    appContext = appContext.getParent();
+                }
+            }
+            // no need to do any operation for logical root node
+        } while (appContext.getParent().getParent() != null);
+        return outputObject;
+    }
+
+    /**
+     * Processes edit request of an application.
+     *
+     * @param appContext application context
+     * @throws YabException               violation in execution of YAB
+     * @throws CloneNotSupportedException clone is not supported
+     */
+    private void processEditOfApplication(YdtAppContext appContext)
+            throws CloneNotSupportedException, YabException {
+
+        // process delete request if operation type is delete and both
+        if (appContext.getOperationType() != OTHER_EDIT) {
+            processDeleteRequestOfApplication(appContext);
+        }
+
+        // process edit request if operation type is other edit and both
+        if (appContext.getOperationType() != DELETE_ONLY) {
+            YdtContext ydtNode = appContext.getModuleContext();
+
+            String appName = getCapitalCase(((YdtNode) appContext.getModuleContext())
+                                                    .getYangSchemaNode()
+                                                    .getJavaClassNameOrBuiltInType());
+
+            // get YO from YOB
+            Object outputObject = getYangObject(ydtNode);
+
+            TraversalType curTraversal = ROOT;
+            do {
+                if (curTraversal != PARENT) {
+
+                    // find application and get application's object using YSR
+                    Object appManagerObject = getApplicationObject(appContext);
+
+                    // find which method to invoke
+                    String methodName = getApplicationMethodName(appContext,
+                                                                 appName, SET);
+
+                    // invoke application's setter method
+                    invokeApplicationsMethod(appManagerObject, outputObject,
+                                             methodName);
+                }
+
+                /*
+                 * AppContext may contain other nodes if it is augmented,
+                 * so traverse the appContext tree
+                 */
+                if (curTraversal != PARENT && appContext.getFirstChild() != null) {
+                    curTraversal = CHILD;
+                    appContext = appContext.getFirstChild();
+                } else if (appContext.getNextSibling() != null) {
+                    curTraversal = SIBLING;
+                    appContext = appContext.getNextSibling();
+                } else {
+                    curTraversal = PARENT;
+                    if (appContext.getParent().getParent() != null) {
+                        appContext = appContext.getParent();
+                    }
+                }
+                // no need to do any operation for logical root node
+            } while (appContext.getParent().getParent() != null);
+        }
+    }
+
+    /**
+     * Processes delete request of an application.
+     *
+     * @param appContext application context
+     * @throws YabException               violation in execution of YAB
+     * @throws CloneNotSupportedException clone is not supported
+     */
+    private void processDeleteRequestOfApplication(YdtAppContext appContext)
+            throws CloneNotSupportedException, YabException {
+        TraversalType curTraversal = ROOT;
+        List<YdtContext> deleteNodes = appContext.getDeleteNodes();
+
+        if (deleteNodes != null && !deleteNodes.isEmpty()) {
+
+            /*
+             * Split the current Ydt tree into two trees.
+             * Delete Tree with all nodes with delete operation and other
+             * tree with other edit operation
+             */
+            YdtContext deleteTree = buildDeleteTree(deleteNodes);
+
+            /*
+             * If any of nodes in ydt delete tree is augmented then add
+             * augmented nodes to current ydt tree
+             */
+            processAugmentedNodesForDelete(deleteTree.getFirstChild(), appContext);
+
+            Object inputObject = getYangObject(deleteTree.getFirstChild());
+
+            String appName = getCapitalCase(((YdtNode) appContext.getModuleContext())
+                                                    .getYangSchemaNode()
+                                                    .getJavaClassNameOrBuiltInType());
+
+            do {
+                if (curTraversal == ROOT || curTraversal == SIBLING) {
+                    while (appContext.getLastChild() != null) {
+                        appContext = appContext.getLastChild();
+                    }
+                }
+
+                // getAugmentApplication manager object
+                Object appManagerObject = getApplicationObject(appContext);
+
+                // find which method to invoke
+                String methodName = getApplicationMethodName(appContext,
+                                                             appName, SET);
+
+                // invoke application's setter method
+                invokeApplicationsMethod(appManagerObject, inputObject, methodName);
+
+                if (appContext.getPreviousSibling() != null) {
+                    curTraversal = SIBLING;
+                    appContext = appContext.getPreviousSibling();
+                } else if (appContext.getParent() != null) {
+                    curTraversal = PARENT;
+                    appContext = appContext.getParent();
+                }
+            } while (appContext.getParent() != null);
+        }
+    }
+
+    /**
+     * Traverses data model tree and if any node is augmented, then
+     * adds child to current application context.
+     *
+     * @param curAppContext current application context
+     * @param schemaNode    YANG data model node, either module or augment
+     */
+    protected void processAugmentForChildNode(YdtAppContext curAppContext,
+                                              YangNode schemaNode) {
+        YangNode yangNode = schemaNode.getChild();
+        if (yangNode == null) {
+            return;
+        }
+
+        TraversalType curTraversal = CHILD;
+        while (!yangNode.equals(schemaNode)) {
+            if (curTraversal != PARENT && yangNode instanceof YangAugmentableNode
+                    && !((YangAugmentableNode) yangNode).getAugmentedInfoList()
+                    .isEmpty()) {
+                updateAppTreeWithAugmentNodes(yangNode, curAppContext);
+            }
+
+            if (curTraversal != PARENT && yangNode.getChild() != null
+                    && yangNode.isDescendantNodeAugmented()) {
+                curTraversal = CHILD;
+                yangNode = yangNode.getChild();
+            } else if (yangNode.getNextSibling() != null) {
+                curTraversal = SIBLING;
+                yangNode = yangNode.getNextSibling();
+            } else {
+                curTraversal = PARENT;
+                yangNode = yangNode.getParent();
+            }
+        }
+    }
+
+    /**
+     * Traverses YDT delete tree and if any YDT node is augmented then
+     * updates the YDT delete tree with augment nodes.
+     *
+     * @param deleteTree YDT delete tree
+     * @param appContext application context
+     */
+    protected void processAugmentedNodesForDelete(YdtContext deleteTree,
+                                                  YdtAppContext appContext) {
+        TraversalType curTraversal = ROOT;
+        YdtContext ydtContext = deleteTree.getFirstChild();
+
+        if (ydtContext == null) {
+            /*
+             * Delete request is for module, so check all the nodes under
+             * module whether it is augmented.
+             */
+            YangNode yangNode = ((YangNode) ((YdtNode) deleteTree)
+                    .getYangSchemaNode());
+            if (yangNode.isDescendantNodeAugmented()) {
+                processAugmentForChildNode(appContext, yangNode);
+            }
+            return;
+        }
+
+        while (!ydtContext.equals(deleteTree)) {
+            if (curTraversal != PARENT && ((YdtNode) ydtContext)
+                    .getYdtContextOperationType() == DELETE) {
+                YangNode yangNode = ((YangNode) ((YdtNode) ydtContext)
+                        .getYangSchemaNode());
+                if (yangNode instanceof YangAugmentableNode) {
+                    updateAppTreeWithAugmentNodes(yangNode, appContext);
+                }
+                if (yangNode.isDescendantNodeAugmented()) {
+                    processAugmentForChildNode(appContext, yangNode);
+                }
+            }
+
+            if (curTraversal != PARENT && ydtContext.getFirstChild() != null) {
+                curTraversal = CHILD;
+                ydtContext = ydtContext.getFirstChild();
+            } else if (ydtContext.getNextSibling() != null) {
+                curTraversal = SIBLING;
+                ydtContext = ydtContext.getNextSibling();
+            } else {
+                curTraversal = PARENT;
+                ydtContext = ydtContext.getParent();
+            }
+        }
+    }
+
+    /**
+     * Returns response YANG data tree using YTB.
+     *
+     * @param responseObjects list of application's response objects
+     * @param name            application YANG name
+     * @param namespace       application YANG namespace
+     * @return response YANG data tree
+     */
+    private YdtBuilder buildResponseYdt(List<Object> responseObjects,
+                                        String name, String namespace) {
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        return treeBuilder.getYdtBuilderForYo(responseObjects,
+                                              name, namespace, null, schemaRegistry);
+    }
+
+    private YdtBuilder buildRpcResponseYdt(Object responseObject,
+                                           YangRequestWorkBench requestWorkBench) {
+        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
+        return treeBuilder.getYdtForRpcResponse(responseObject, requestWorkBench);
+    }
+
+    /**
+     * Builds delete tree for list of delete nodes.
+     *
+     * @param deleteNodes list of delete nodes
+     * @return deleteTree YANG data tree for delete operation
+     * @throws CloneNotSupportedException clone is not supported
+     */
+    protected YdtContext buildDeleteTree(List<YdtContext> deleteNodes) throws
+            CloneNotSupportedException {
+        Iterator<YdtContext> iterator = deleteNodes.iterator();
+        YdtContext deleteTree = null;
+        while (iterator.hasNext()) {
+            YdtContext deleteNode = iterator.next();
+            if (((YdtExtendedContext) deleteNode.getParent())
+                    .getYdtContextOperationType() != DELETE) {
+                cloneAncestorsOfDeleteNode(deleteNode);
+                deleteTree = unlinkDeleteNodeFromCurrentTree((YdtNode) deleteNode);
+            }
+        }
+
+        if (deleteTree != null) {
+            while (deleteTree.getParent() != null) {
+                deleteTree = deleteTree.getParent();
+            }
+        }
+        return deleteTree;
+    }
+
+    /**
+     * Clones ancestor nodes of delete node.
+     *
+     * @param deleteNode node to be deleted
+     * @throws CloneNotSupportedException clone not supported
+     */
+    private void cloneAncestorsOfDeleteNode(YdtContext deleteNode)
+            throws CloneNotSupportedException {
+        YdtNode clonedNode;
+        YdtNode previousNode = null;
+
+        // Clone the parents of delete node to form delete tree
+        YdtNode nodeToClone = (YdtNode) deleteNode.getParent();
+        while (nodeToClone != null) {
+            // If node is not cloned yet
+            if (nodeToClone.getClonedNode() == null) {
+                clonedNode = nodeToClone.clone();
+                unlinkCurrentYdtNode(clonedNode);
+                if (nodeToClone instanceof YdtMultiInstanceNode) {
+                    addKeyLeavesToClonedNode(nodeToClone, clonedNode);
+                }
+                nodeToClone.setClonedNode(clonedNode);
+            } else {
+                // already node is cloned
+                clonedNode = (YdtNode) nodeToClone.getClonedNode();
+            }
+
+            if (previousNode != null) {
+                /*
+                 * add previous cloned node as child of current cloned node
+                 * so that tree will be formed from delete node parent to
+                 * logical root node.
+                 */
+                clonedNode.addChild(previousNode, false);
+            }
+            previousNode = clonedNode;
+            nodeToClone = nodeToClone.getParent();
+        }
+    }
+
+    /**
+     * Unlinks delete node from current YANG data tree of application
+     * and links it to cloned delete tree.
+     *
+     * @param deleteNode node to be unlinked
+     * @return deleteNode delete node linked to cloned delete tree
+     */
+    private YdtNode unlinkDeleteNodeFromCurrentTree(YdtNode deleteNode) {
+        YdtNode parentClonedNode = (YdtNode) deleteNode.getParent().getClonedNode();
+        unlinkNodeFromParent(deleteNode);
+        unlinkNodeFromSibling(deleteNode);
+
+        /*
+         * Set all the pointers of node to null before adding as child
+         * to parent's cloned node.
+         */
+        deleteNode.setParent(null);
+        deleteNode.setPreviousSibling(null);
+        deleteNode.setNextSibling(null);
+
+        parentClonedNode.addChild(deleteNode, false);
+        return deleteNode;
+    }
+
+    /**
+     * Adds key leaf nodes to cloned YDT node from current Ydt node.
+     *
+     * @param curNode    current YDT node
+     * @param clonedNode cloned YDT node
+     */
+    private void addKeyLeavesToClonedNode(YdtNode curNode, YdtNode clonedNode)
+            throws CloneNotSupportedException {
+        YdtNode keyClonedLeaf;
+        List<YdtContext> keyList = ((YdtMultiInstanceNode) curNode)
+                .getKeyNodeList();
+        if (keyList != null && !keyList.isEmpty()) {
+            for (YdtContext keyLeaf : keyList) {
+                keyClonedLeaf = ((YdtNode) keyLeaf).clone();
+                unlinkCurrentYdtNode(keyClonedLeaf);
+                clonedNode.addChild(keyClonedLeaf, true);
+            }
+        }
+    }
+
+    /**
+     * Updates application context tree if any of the nodes in current
+     * application context tree is augmented.
+     *
+     * @param yangNode      YANG schema node which is augmented
+     * @param curAppContext current application context tree
+     */
+    private void updateAppTreeWithAugmentNodes(YangNode yangNode,
+                                               YdtAppContext curAppContext) {
+        YdtAppContext childAppContext;
+        for (YangAugment yangAugment : ((YangAugmentableNode) yangNode)
+                .getAugmentedInfoList()) {
+            Object appManagerObject = schemaRegistry
+                    .getRegisteredApplication(yangAugment.getParent());
+            if (appManagerObject != null) {
+                childAppContext = addChildToYdtAppTree(curAppContext,
+                                                       yangAugment);
+                processAugmentForChildNode(childAppContext, yangAugment);
+            }
+        }
+    }
+
+    /**
+     * Adds child node to current application context tree.
+     *
+     * @param curAppContext current application context
+     * @param augment       augment data model node
+     * @return childAppContext child node added
+     */
+    private YdtAppContext addChildToYdtAppTree(YdtAppContext curAppContext,
+                                               YangNode augment) {
+        DefaultYdtAppContext childAppContext = getAppContext(true);
+        childAppContext.setParent(curAppContext);
+        childAppContext.setOperationType(curAppContext.getOperationType());
+        childAppContext.setAugmentingSchemaNode(augment);
+        curAppContext.addChild(childAppContext);
+        return childAppContext;
+    }
+
+    /**
+     * Unlinks the current node from its parent.
+     *
+     * @param deleteNode node which should be unlinked from YDT tree
+     */
+    private void unlinkNodeFromParent(YdtNode deleteNode) {
+        YdtNode parentNode = deleteNode.getParent();
+        if (parentNode.getFirstChild().equals(deleteNode)
+                && parentNode.getLastChild().equals(deleteNode)) {
+            parentNode.setChild(null);
+            parentNode.setLastChild(null);
+        } else if (parentNode.getFirstChild().equals(deleteNode)) {
+            parentNode.setChild(deleteNode.getNextSibling());
+        } else if (parentNode.getLastChild().equals(deleteNode)) {
+            parentNode.setLastChild(deleteNode.getPreviousSibling());
+        }
+    }
+
+    /**
+     * Unlinks the current node from its sibling.
+     *
+     * @param deleteNode node which should be unlinked from YDT tree
+     */
+    private void unlinkNodeFromSibling(YdtNode deleteNode) {
+        YdtNode previousSibling = deleteNode.getPreviousSibling();
+        YdtNode nextSibling = deleteNode.getNextSibling();
+        if (nextSibling != null && previousSibling != null) {
+            previousSibling.setNextSibling(nextSibling);
+            nextSibling.setPreviousSibling(previousSibling);
+        } else if (nextSibling != null) {
+            nextSibling.setPreviousSibling(null);
+        } else if (previousSibling != null) {
+            previousSibling.setNextSibling(null);
+        }
+    }
+
+    /**
+     * Unlinks current Ydt node from parent, sibling and child.
+     *
+     * @param ydtNode YANG data tree node
+     */
+    private void unlinkCurrentYdtNode(YdtNode ydtNode) {
+        ydtNode.setParent(null);
+        ydtNode.setNextSibling(null);
+        ydtNode.setPreviousSibling(null);
+        ydtNode.setChild(null);
+        ydtNode.setLastChild(null);
+    }
+
+    /**
+     * Returns YANG object for YDT node.
+     *
+     * @param ydtNode YANG data node
+     * @return YANG object for YDT node
+     */
+    private Object getYangObject(YdtContext ydtNode) {
+        checkNotNull(ydtNode);
+        DefaultYobBuilder yobBuilder = new DefaultYobBuilder();
+        return yobBuilder.getYangObject((YdtExtendedContext) ydtNode,
+                                        schemaRegistry);
+    }
+
+    /**
+     * Returns application manager object for YDT node.
+     *
+     * @param appContext YDT application context
+     * @return application manager object
+     */
+    private Object getApplicationObjectForRpc(YdtAppContext appContext) {
+        checkNotNull(appContext);
+        while (appContext.getFirstChild() != null) {
+            appContext = appContext.getFirstChild();
+        }
+        return schemaRegistry.getRegisteredApplication(appContext.getAppData()
+                                                               .getRootSchemaNode());
+    }
+
+    /**
+     * Returns application manager object of application.
+     *
+     * @param appContext application context
+     * @return application manager object
+     */
+    private Object getApplicationObject(YdtAppContext appContext) {
+        return schemaRegistry.getRegisteredApplication(appContext.getAppData()
+                                                               .getRootSchemaNode());
+    }
+
+    /**
+     * Converts name to capital case.
+     *
+     * @param yangIdentifier identifier
+     * @return name to capital case
+     */
+    private String getCapitalCase(String yangIdentifier) {
+        return yangIdentifier.substring(0, 1).toUpperCase() +
+                yangIdentifier.substring(1);
+    }
+
+    /**
+     * Returns get/set method name for application's request.
+     *
+     * @param appContext application context
+     * @return get/set method name for application's query request
+     */
+    private String getApplicationMethodName(YdtAppContext appContext,
+                                            String appName,
+                                            String operation) {
+        if (appContext.getYangSchemaNode() instanceof YangModule) {
+            return operation + appName;
+        }
+
+        String augment = ((YangAugment) appContext
+                .getAugmentingSchemaNode()).getTargetNode().get(0)
+                .getResolvedNode().getJavaClassNameOrBuiltInType();
+        return new StringBuilder().append(operation).append(AUGMENTED)
+                .append(appName).append(getCapitalCase(augment)).toString();
+    }
+
+    /**
+     * Returns rpc's input schema node.
+     *
+     * @param rpcNode rpc schema node
+     * @return rpc's input YDT node
+     */
+    private YdtContext getInputYdtNode(YdtContext rpcNode) {
+        YdtContext inputNode = rpcNode.getFirstChild();
+        while (inputNode != null) {
+            YangSchemaNode yangInputNode = ((YdtNode) inputNode)
+                    .getYangSchemaNode();
+            if (yangInputNode instanceof YangInput) {
+                return inputNode;
+            }
+            inputNode = rpcNode.getNextSibling();
+        }
+        return null;
+    }
+
+    /**
+     * Invokes application method for RPC request.
+     *
+     * @param appManagerObject application manager object
+     * @param inputObject      input parameter object of method
+     * @param methodName       method name which should be invoked
+     * @return response object from application
+     * @throws YabException violation in execution of YAB
+     */
+    private Object invokeApplicationsMethod(Object appManagerObject,
+                                            Object inputObject,
+                                            String methodName) throws YabException {
+        checkNotNull(appManagerObject);
+        Class<?> appClass = appManagerObject.getClass();
+        try {
+            Method methodObject = appClass.getDeclaredMethod(methodName,
+                                                             inputObject.getClass());
+            if (methodObject != null) {
+                return methodObject.invoke(appManagerObject, inputObject);
+            }
+            throw new YabException("No such method in application");
+        } catch (IllegalAccessException | NoSuchMethodException |
+                InvocationTargetException e) {
+            throw new YabException(e);
+        }
+    }
+
+    /**
+     * Invokes application method for RPC request.
+     *
+     * @param appObject   application manager object
+     * @param inputObject input parameter object of method
+     * @param yangNode    method name which should be invoked
+     * @return response object from application
+     * @throws YabException violation in execution of YAB
+     */
+    private String getReturnTypeOfRpcResponse(Object appObject,
+                                              Object inputObject, YangSchemaNode
+                                                      yangNode) throws YabException {
+        Method methodObject = null;
+        try {
+            if (inputObject == null) {
+                methodObject = appObject.getClass()
+                        .getDeclaredMethod(yangNode.getJavaClassNameOrBuiltInType(),
+                                           null);
+            } else {
+                methodObject = appObject.getClass()
+                        .getDeclaredMethod(yangNode.getJavaClassNameOrBuiltInType(),
+                                           inputObject.getClass().getInterfaces());
+            }
+        } catch (NoSuchMethodException e) {
+            new YabException(e);
+        }
+        return methodObject.getReturnType().getSimpleName();
+    }
+
+    /**
+     * Invokes application method for RPC request.
+     *
+     * @param appManagerObject application manager object
+     * @param inputParamObject input parameter object of method
+     * @param methodName       method name which should be invoked
+     * @return response object from application
+     * @throws YabException violation in execution of YAB
+     */
+    private Object invokeRpcApplicationsMethod(Object appManagerObject,
+                                               Object inputParamObject,
+                                               String methodName) throws YabException {
+        checkNotNull(appManagerObject);
+        Class<?> appClass = appManagerObject.getClass();
+        try {
+            Method methodObject;
+            if (inputParamObject == null) {
+                methodObject = appClass.getDeclaredMethod(methodName, null);
+                if (methodObject != null) {
+                    return methodObject.invoke(appManagerObject);
+                }
+            } else {
+                methodObject = appClass.getDeclaredMethod(methodName,
+                                                          inputParamObject
+                                                                  .getClass()
+                                                                  .getInterfaces());
+                if (methodObject != null) {
+                    return methodObject.invoke(appManagerObject, inputParamObject);
+                }
+            }
+            throw new YabException("No such method in application");
+        } catch (IllegalAccessException | NoSuchMethodException |
+                InvocationTargetException e) {
+            throw new YabException(e);
+        }
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/exceptions/YabException.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/exceptions/YabException.java
new file mode 100644
index 0000000..846276c
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/exceptions/YabException.java
@@ -0,0 +1,59 @@
+/*
+ * 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.yab.exceptions;
+
+/**
+ * Represents base class for exceptions in YDT operations.
+ */
+public class YabException extends RuntimeException {
+
+    private static final long serialVersionUID = 20160211L;
+
+    /**
+     * Creates a new YDT exception.
+     */
+    public YabException() {
+    }
+
+    /**
+     * Creates a new YDT exception with given message.
+     *
+     * @param message the detail of exception in string
+     */
+    public YabException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new YDT exception from given message and cause.
+     *
+     * @param message the detail of exception in string
+     * @param cause   underlying cause of the error
+     */
+    public YabException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new YDT exception from cause.
+     *
+     * @param cause underlying cause of the error
+     */
+    public YabException(final Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/exceptions/package-info.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/exceptions/package-info.java
new file mode 100644
index 0000000..a00b592
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/exceptions/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * YANG application broker exception.
+ */
+package org.onosproject.yms.app.yab.exceptions;
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/package-info.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/package-info.java
new file mode 100644
index 0000000..aabbc22
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/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 interfaces to YANG request broker. YRB is responsible for
+ * interaction with applications in YANG modeled objects.
+ */
+package org.onosproject.yms.app.yab;
\ No newline at end of file
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
index 5ae1230..625f1ed 100644
--- 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
@@ -125,7 +125,7 @@
     /*
      * Flag to identify data validation need to be done by YDT or not.
      */
-    private final boolean validate;
+    private boolean validate = false;
     // TODO validate need to be handle later with interaction type basis in
     // future when it will be supported
 
@@ -164,6 +164,19 @@
     }
 
     /**
+     * Creates an instance of YANG request work bench which is used to build YDT
+     * tree in YAB.
+     *
+     * @param curNode       current YDT node
+     * @param operationType YMS operation type
+     */
+    public YangRequestWorkBench(YdtNode curNode,
+                                YmsOperationType operationType) {
+        this.curNode = curNode;
+        ymsOperationType = operationType;
+    }
+
+    /**
      * Sets the logical root context information available in YDT node.
      *
      * @param node logical root node
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/YmsManager.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/YmsManager.java
index b9ea3a8..ba0554b 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/YmsManager.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/YmsManager.java
@@ -25,6 +25,7 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.core.IdGenerator;
+import org.onosproject.yms.app.yab.YangApplicationBroker;
 import org.onosproject.yms.app.ydt.DefaultYdtWalker;
 import org.onosproject.yms.app.ydt.YangRequestWorkBench;
 import org.onosproject.yms.app.ynh.YangNotificationExtendedService;
@@ -126,6 +127,24 @@
 
     @Override
     public YdtResponse executeOperation(YdtBuilder operationRequest) {
+        YangApplicationBroker requestBroker =
+                new YangApplicationBroker(schemaRegistry);
+        switch (operationRequest.getYmsOperationType()) {
+            case EDIT_CONFIG_REQUEST:
+                try {
+                    return requestBroker.processEdit(operationRequest);
+                } catch (CloneNotSupportedException e) {
+                    log.error("YAB: failed to process edit request.");
+                }
+            case QUERY_CONFIG_REQUEST:
+                // TODO : to be implemented
+            case QUERY_REQUEST:
+                return requestBroker.processQuery(operationRequest);
+            case RPC_REQUEST:
+                return requestBroker.processOperation(operationRequest);
+            default:
+                // TODO : throw exception
+        }
         return null;
     }
 
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java
index 7e12be3..e2190f0 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java
@@ -21,6 +21,7 @@
 import org.onosproject.yangutils.datamodel.YangSchemaNode;
 import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.yob.exception.YobExceptions;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -70,8 +71,9 @@
         YangSchemaNode node = curYdtNode.getYangSchemaNode();
 
         String qualName = getQualifiedDefaultClassName(node);
-        ClassLoader classLoader = getClassLoader(registry, qualName,
-                                                 curYdtNode);
+        ClassLoader classLoader = getClassLoader(registry,
+                                                 qualName,
+                                                 curYdtNode, rootYdtNode);
 
         if (curYdtNode != rootYdtNode) {
             setterName = node.getJavaAttributeName();
@@ -248,7 +250,7 @@
         String qualifiedClassName = packageName + PERIOD + className;
         ClassLoader classLoader = getClassLoader(registry,
                                                  qualifiedClassName,
-                                                 ydtExtendedContext);
+                                                 ydtExtendedContext, null);
         try {
             childSetClass = classLoader.loadClass(qualifiedClassName);
         } catch (ClassNotFoundException e) {
@@ -292,27 +294,35 @@
      * Updates class loader for all the classes.
      *
      * @param registry           YANG schema registry
-     * @param context            YDT context
+     * @param curNode            YDT context
      * @param qualifiedClassName qualified class name
      * @return current class loader
      */
     private ClassLoader getClassLoader(YangSchemaRegistry registry,
                                        String qualifiedClassName,
+                                       YdtExtendedContext curNode,
                                        YdtExtendedContext context) {
 
-        YangSchemaNode yangSchemaNode = context.getYangSchemaNode();
-        if (yangSchemaNode instanceof RpcNotificationContainer) {
+        if (context != null && curNode == context) {
+            YangSchemaNode yangSchemaNode = curNode.getYangSchemaNode();
+            while (!(yangSchemaNode instanceof RpcNotificationContainer)) {
+                curNode = (YdtExtendedContext) curNode.getParent();
+                if (curNode == null) {
+                    throw new YobExceptions("Invalid YANG data tree");
+                }
+                yangSchemaNode = curNode.getYangSchemaNode();
+            }
+
             Class<?> regClass = registry.getRegisteredClass(yangSchemaNode,
                                                             qualifiedClassName);
             return regClass.getClassLoader();
         } else {
-
             YdtExtendedContext parent =
-                    (YdtExtendedContext) context.getParent();
+                    (YdtExtendedContext) curNode.getParent();
             YobWorkBench parentBuilderContainer =
                     (YobWorkBench) parent.getAppInfo(YOB);
             Object parentObj =
-                    parentBuilderContainer.getParentBuilder(context, registry);
+                    parentBuilderContainer.getParentBuilder(curNode, registry);
             return parentObj.getClass().getClassLoader();
         }
     }
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/yab/MockYmsManager.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/yab/MockYmsManager.java
new file mode 100644
index 0000000..22f4fd9
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/yab/MockYmsManager.java
@@ -0,0 +1,124 @@
+/*
+ * 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.yab;
+
+import org.onosproject.yms.app.ydt.YangRequestWorkBench;
+import org.onosproject.yms.app.ysr.TestYangSchemaNodeProvider;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.ych.YangCodecHandler;
+import org.onosproject.yms.ych.YangDataTreeCodec;
+import org.onosproject.yms.ych.YangProtocolEncodingFormat;
+import org.onosproject.yms.ydt.YdtBuilder;
+import org.onosproject.yms.ydt.YdtResponse;
+import org.onosproject.yms.ydt.YdtWalker;
+import org.onosproject.yms.ydt.YmsOperationType;
+import org.onosproject.yms.ymsm.YmsService;
+import org.onosproject.yms.ynh.YangNotificationService;
+import org.onosproject.yms.ysr.YangModuleIdentifier;
+import org.onosproject.yms.ysr.YangModuleLibrary;
+
+import java.util.List;
+
+/**
+ * Represents implementation of YANG application management system manager.
+ */
+public class MockYmsManager
+        implements YmsService {
+
+    YangSchemaRegistry schemaRegistry;
+    TestYangSchemaNodeProvider testYangSchemaNodeProvider =
+            new TestYangSchemaNodeProvider();
+
+    @Override
+    public YdtBuilder getYdtBuilder(String logicalRootName,
+                                    String rootNamespace,
+                                    YmsOperationType operationType) {
+        testYangSchemaNodeProvider.processSchemaRegistry(new TestManager());
+        schemaRegistry = testYangSchemaNodeProvider.getDefaultYangSchemaRegistry();
+        return new YangRequestWorkBench(logicalRootName, rootNamespace,
+                                        operationType, schemaRegistry, false);
+    }
+
+    @Override
+    public YdtBuilder getYdtBuilder(String logicalRootName,
+                                    String rootNamespace,
+                                    YmsOperationType operationType,
+                                    Object schemaRegistryForYdt) {
+        return null;
+    }
+
+    @Override
+    public YdtWalker getYdtWalker() {
+        return null;
+    }
+
+    @Override
+    public YdtResponse executeOperation(YdtBuilder operationRequest) {
+        YangApplicationBroker requestBroker =
+                new YangApplicationBroker(schemaRegistry);
+        switch (operationRequest.getYmsOperationType()) {
+            case EDIT_CONFIG_REQUEST:
+                try {
+                    return requestBroker.processEdit(operationRequest);
+                } catch (CloneNotSupportedException e) {
+                }
+                break;
+            case QUERY_CONFIG_REQUEST:
+            case QUERY_REQUEST:
+                return requestBroker.processQuery(operationRequest);
+            case RPC_REQUEST:
+                return requestBroker.processOperation(operationRequest);
+            default:
+        }
+        return null;
+    }
+
+    @Override
+    public YangNotificationService getYangNotificationService() {
+        return null;
+    }
+
+    @Override
+    public void registerService(Object appManager, Class<?> yangService,
+                                List<String> supportedFeatureList) {
+    }
+
+    @Override
+    public void unRegisterService(Object appManager, Class<?> yangService) {
+
+    }
+
+    @Override
+    public YangModuleLibrary getYangModuleLibrary() {
+        return null;
+    }
+
+    @Override
+    public String getYangFile(YangModuleIdentifier moduleIdentifier) {
+        return null;
+    }
+
+    @Override
+    public void registerDefaultCodec(YangDataTreeCodec defaultCodec,
+                                     YangProtocolEncodingFormat dataFormat) {
+    }
+
+    @Override
+    public YangCodecHandler getYangCodecHandler() {
+        return null;
+    }
+}
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/yab/TestManager.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/yab/TestManager.java
new file mode 100644
index 0000000..c07a18f
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/yab/TestManager.java
@@ -0,0 +1,82 @@
+/*
+ * 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.yab;
+
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.Test;
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.TestOpParam;
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.TestService;
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.test.Cont1;
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.test.DefaultCont1;
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.test.rockthehouse.DefaultRockTheHouseOutput;
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.test.rockthehouse.RockTheHouseInput;
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.test.rockthehouse.RockTheHouseOutput;
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.test.rockthehouse1.RockTheHouse1Input;
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.test.rockthehouse2.DefaultRockTheHouse2Output;
+import org.onosproject.yang.gen.v1.ydt.test.rev20160524.test.rockthehouse2.RockTheHouse2Output;
+
+/**
+ * Implementation of the application management service.
+ */
+public class TestManager implements TestService {
+
+    Test response;
+
+    @Override
+    public Test getTest(TestOpParam test) {
+        Cont1 cont = new DefaultCont1.Cont1Builder().leaf4("4").build();
+        Test response = new TestOpParam.TestBuilder().cont1(cont).build();
+        return response;
+    }
+
+    @Override
+    public void setTest(TestOpParam test) {
+        response = test;
+    }
+
+    @Override
+    public Test getAugmentedTestCont4(TestOpParam test) {
+        Cont1 cont = new DefaultCont1.Cont1Builder().leaf4("4").build();
+        Test response = new TestOpParam.TestBuilder().cont1(cont).build();
+        return response;
+    }
+
+    @Override
+    public void setAugmentedTestCont4(TestOpParam augmentedTestCont4) {
+        response = augmentedTestCont4;
+    }
+
+    @Override
+    public RockTheHouseOutput rockTheHouse(RockTheHouseInput inputVar) {
+        return DefaultRockTheHouseOutput.builder().hello("hello").build();
+    }
+
+
+    @Override
+    public void rockTheHouse1(RockTheHouse1Input inputVar) {
+        // TODO : to be implemented
+    }
+
+    @Override
+    public RockTheHouse2Output rockTheHouse2() {
+        return DefaultRockTheHouse2Output
+                .builder().leaf14("14").build();
+    }
+
+    @Override
+    public void rockTheHouse3() {
+    }
+}
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/yab/YangApplicationBrokerTest.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/yab/YangApplicationBrokerTest.java
new file mode 100644
index 0000000..0d77306
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/yab/YangApplicationBrokerTest.java
@@ -0,0 +1,1088 @@
+/*
+ * 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.yab;
+
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangAugment;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yms.app.ydt.YangRequestWorkBench;
+import org.onosproject.yms.app.ydt.YdtAppContext;
+import org.onosproject.yms.app.ydt.YdtAppNodeOperationType;
+import org.onosproject.yms.app.ydt.YdtNode;
+import org.onosproject.yms.ydt.YdtContext;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.MERGE;
+import static org.onosproject.yms.ydt.YmsOperationType.EDIT_CONFIG_REQUEST;
+import static org.onosproject.yms.ydt.YmsOperationType.QUERY_CONFIG_REQUEST;
+import static org.onosproject.yms.ydt.YmsOperationType.RPC_REQUEST;
+
+/**
+ * Unit test case for YANG application broker.
+ */
+public class YangApplicationBrokerTest {
+
+    MockYmsManager ymsManager = new MockYmsManager();
+
+    /**
+     * Returns YANG data tree to check edit operation of container.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForEditOperationWithoutDelete() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                EDIT_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test", MERGE);
+        defaultYdtBuilder.addChild("cont1", null, MERGE);
+        defaultYdtBuilder.addChild("cont2", null, MERGE);
+        defaultYdtBuilder.addChild("cont3", null, MERGE);
+        defaultYdtBuilder.addLeaf("leaf1", null, "1");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf4", null, "4");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("cont4", null, MERGE);
+        defaultYdtBuilder.addChild("cont5", null, MERGE);
+        defaultYdtBuilder.addLeaf("leaf9", null, "9");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf10", null, "10");
+        return defaultYdtBuilder;
+    }
+
+    private YangRequestWorkBench buildYdtForKeyLeavesInDeleteTree() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                EDIT_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test", MERGE);
+        defaultYdtBuilder.addChild("list2", null, MERGE);
+        defaultYdtBuilder.addLeaf("leaf5", null, "5");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf6", null, "6");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf7", null, "7");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("cont7", null, DELETE);
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check delete operation of container.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForEditOperationWithDelete() {
+        String rootName = "rootNode";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                EDIT_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test", MERGE);
+        defaultYdtBuilder.addChild("cont1", null, MERGE);
+        defaultYdtBuilder.addChild("cont2", null, DELETE);
+        defaultYdtBuilder.addChild("cont3", null, DELETE);
+        defaultYdtBuilder.addLeaf("leaf1", null, "1");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf4", null, "4");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("cont4", null, DELETE);
+        defaultYdtBuilder.addChild("cont5", null, DELETE);
+        defaultYdtBuilder.addLeaf("leaf9", null, "9");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf10", null, "10");
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check edit operation of list.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForListEditOperationWithoutDelete() {
+        String rootName = "listWithoutDelete";
+        Set<String> valueSet = new HashSet<>();
+        valueSet.add("10");
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                EDIT_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test", MERGE);
+        defaultYdtBuilder.addChild("cont1", null, MERGE);
+        defaultYdtBuilder.addChild("list1", null, MERGE);
+        defaultYdtBuilder.addLeaf("leaf2", null, "2");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf3", null, "3");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf4", null, "4");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("list2", null, MERGE);
+        defaultYdtBuilder.addLeaf("leaf5", null, "5");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf6", null, "6");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf7", null, "7");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaflist8", null, valueSet);
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf10", null, "10");
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check delete operation of list.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForListEditOperationWithDelete() {
+        String rootName = "listWithDelete";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                EDIT_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test", MERGE);
+        defaultYdtBuilder.addChild("cont1", null, MERGE);
+        defaultYdtBuilder.addChild("list1", null, DELETE);
+        defaultYdtBuilder.addLeaf("leaf2", null, "2");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf3", null, "3");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf4", null, "4");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("list2", null, DELETE);
+        defaultYdtBuilder.addLeaf("leaf5", null, "5");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf6", null, "6");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf10", null, "10");
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check query operation of container.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForQueryOperation() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                QUERY_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test");
+        defaultYdtBuilder.addChild("cont1", null);
+        defaultYdtBuilder.addChild("cont2", null);
+        defaultYdtBuilder.addChild("cont3", null);
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("cont4", null);
+        defaultYdtBuilder.addChild("cont5", null);
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check query operation of list.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForListQueryOperation() {
+        String rootName = "listQuery";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                QUERY_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test");
+        defaultYdtBuilder.addChild("cont1", null);
+        defaultYdtBuilder.addChild("list1", null);
+        defaultYdtBuilder.addLeaf("leaf2", null, "2");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("list2", null);
+        defaultYdtBuilder.addLeaf("leaf5", null, "5");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf6", null, "6");
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check delete operation of a node.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtWithOneDeleteNode() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                EDIT_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test");
+        defaultYdtBuilder.addChild("cont1", null, MERGE);
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("cont4", null, DELETE);
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf10", null, "10");
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check delete operation of last node.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtWithDeleteNodeAsLastChild() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                EDIT_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test", MERGE);
+        defaultYdtBuilder.addChild("cont1", null, MERGE);
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("list2", null, MERGE);
+        defaultYdtBuilder.addLeaf("leaf5", null, "10");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf6", null, "10");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("cont4", null, DELETE);
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to with delete operation of all the nodes.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtWithAllDeleteNode() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                EDIT_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test", DELETE);
+        defaultYdtBuilder.addChild("cont1", null, DELETE);
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("list2", null, DELETE);
+        defaultYdtBuilder.addLeaf("leaf5", null, "10");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addLeaf("leaf6", null, "10");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("cont4", null, DELETE);
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check rpc operation with only input.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForRpcWithOnlyInput() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                RPC_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test");
+        defaultYdtBuilder.addChild("rock-the-house1", null);
+        defaultYdtBuilder.addChild("input", null);
+        defaultYdtBuilder.addLeaf("leaf13", null, "5");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check rpc operation with only output.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForRpcWithOnlyOutput() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                RPC_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test");
+        defaultYdtBuilder.addChild("rock-the-house2", null);
+        defaultYdtBuilder.addChild("output", null);
+        defaultYdtBuilder.addLeaf("leaf14", null, "14");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check rpc operation with both input and output.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForRpcWithBothInputOutput() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                RPC_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test");
+        defaultYdtBuilder.addChild("rock-the-house", null);
+        defaultYdtBuilder.addChild("input", null);
+        defaultYdtBuilder.addLeaf("zip-code", null, "5");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.addChild("output", null);
+        defaultYdtBuilder.addLeaf("hello", null, "5");
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check rpc operation.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForRpc() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                RPC_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test");
+        defaultYdtBuilder.addChild("rock-the-house3", null);
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check query operation with multiple level of
+     * augment.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForQueryWithMultipleAugment() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                QUERY_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test");
+        defaultYdtBuilder.traverseToParent();
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Returns YANG data tree to check delete operation with multiple level of
+     * augment.
+     *
+     * @return YANG data tree
+     */
+    private YangRequestWorkBench buildYdtForDeleteWithMultipleAugment() {
+        String rootName = "root";
+        YangRequestWorkBench defaultYdtBuilder =
+                (YangRequestWorkBench) ymsManager.getYdtBuilder(rootName, null,
+                                                                EDIT_CONFIG_REQUEST);
+        defaultYdtBuilder.addChild("test", "ydt.test");
+        defaultYdtBuilder.addChild("cont4", null, DELETE);
+        defaultYdtBuilder.traverseToParent();
+        defaultYdtBuilder.traverseToParent();
+        return defaultYdtBuilder;
+    }
+
+    /**
+     * Checks whether YANG data tree and delete tree is correct.
+     */
+    @Test
+    public void validateDeleteTreeOnlyOneNodeInDeleteList()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForEditOperationWithDelete();
+        YdtAppContext appContext =
+                defaultYdtBuilder.getAppRootNode().getFirstChild();
+        YdtContext ydtContext = appContext.getModuleContext();
+        List<YdtContext> deleteNodes = appContext.getDeleteNodes();
+
+        YdtContext cont1YdtContext;
+        YdtContext cont2YdtContext;
+        YdtContext cont3YdtContext;
+        YdtContext cont4YdtContext;
+        YdtContext deleteTree;
+
+        // verify whether ydt tree is correct
+        assertThat(ydtContext.getName(), is("test"));
+
+        cont1YdtContext = ydtContext.getFirstChild();
+        assertThat(cont1YdtContext.getName(), is("cont1"));
+
+        cont2YdtContext = cont1YdtContext.getFirstChild();
+        assertThat(cont2YdtContext.getName(), is("cont2"));
+
+        cont3YdtContext = cont2YdtContext.getFirstChild();
+        assertThat(cont3YdtContext.getName(), is("cont3"));
+
+        ydtContext = cont3YdtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf1"));
+        assertThat(ydtContext.getValue(), is("1"));
+
+        ydtContext = cont2YdtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf4"));
+        assertThat(ydtContext.getValue(), is("4"));
+
+        cont4YdtContext = cont1YdtContext.getNextSibling();
+        assertThat(cont4YdtContext.getName(), is("cont4"));
+
+        ydtContext = cont4YdtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("cont5"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf9"));
+        assertThat(ydtContext.getValue(), is("9"));
+
+        ydtContext = cont4YdtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf10"));
+        assertThat(ydtContext.getValue(), is("10"));
+
+        // build delete tree
+        YangApplicationBroker yab = new YangApplicationBroker(null);
+        deleteTree = yab.buildDeleteTree(deleteNodes);
+
+        // verify whether delete ydt tree is correct
+        assertThat(deleteTree.getFirstChild().getName(), is("test"));
+
+        cont1YdtContext = deleteTree.getFirstChild().getFirstChild();
+        assertThat(cont1YdtContext.getName(), is("cont1"));
+
+        cont2YdtContext = cont1YdtContext.getFirstChild();
+        assertThat(cont2YdtContext.getName(), is("cont2"));
+
+        cont3YdtContext = cont2YdtContext.getFirstChild();
+        assertThat(cont3YdtContext.getName(), is("cont3"));
+
+        ydtContext = cont3YdtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf1"));
+        assertThat(ydtContext.getValue(), is("1"));
+
+        assertThat(cont2YdtContext.getNextSibling(), nullValue());
+
+        cont4YdtContext = cont1YdtContext.getNextSibling();
+        assertThat(cont4YdtContext.getName(), is("cont4"));
+
+        ydtContext = cont4YdtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("cont5"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf9"));
+        assertThat(ydtContext.getValue(), is("9"));
+
+        assertThat(cont4YdtContext.getNextSibling(), nullValue());
+
+        // ydtTree after removing delete nodes
+        ydtContext = appContext.getModuleContext();
+        assertThat(ydtContext.getName(), is("test"));
+
+        cont1YdtContext = ydtContext.getFirstChild();
+        assertThat(cont1YdtContext.getName(), is("cont1"));
+
+        ydtContext = cont1YdtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf4"));
+        assertThat(ydtContext.getValue(), is("4"));
+
+        ydtContext = cont1YdtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf10"));
+        assertThat(ydtContext.getValue(), is("10"));
+    }
+
+    /**
+     * Checks whether YANG data tree and delete tree is correct.
+     */
+    @Test
+    public void validateListDeleteTree()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForListEditOperationWithDelete();
+        YdtAppContext appContext =
+                defaultYdtBuilder.getAppRootNode().getFirstChild();
+        YdtContext ydtContext = appContext.getModuleContext();
+        List<YdtContext> deleteNodes = appContext.getDeleteNodes();
+
+        YdtContext cont1YdtContext;
+        YdtContext list1YdtContext;
+        YdtContext list2YdtContext;
+        YdtContext deleteTree;
+
+        // verify whether ydt tree is correct
+        assertThat(ydtContext.getName(), is("test"));
+
+        cont1YdtContext = ydtContext.getFirstChild();
+        assertThat(cont1YdtContext.getName(), is("cont1"));
+
+        list1YdtContext = cont1YdtContext.getFirstChild();
+        assertThat(list1YdtContext.getName(), is("list1"));
+
+        ydtContext = list1YdtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf2"));
+        assertThat(ydtContext.getValue(), is("2"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf3"));
+        assertThat(ydtContext.getValue(), is("3"));
+
+        ydtContext = list1YdtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf4"));
+        assertThat(ydtContext.getValue(), is("4"));
+
+        list2YdtContext = cont1YdtContext.getNextSibling();
+        assertThat(list2YdtContext.getName(), is("list2"));
+
+        ydtContext = list2YdtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf5"));
+        assertThat(ydtContext.getValue(), is("5"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf6"));
+        assertThat(ydtContext.getValue(), is("6"));
+
+        ydtContext = list2YdtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf10"));
+        assertThat(ydtContext.getValue(), is("10"));
+
+        // build delete tree
+        YangApplicationBroker yab = new YangApplicationBroker(null);
+        deleteTree = yab.buildDeleteTree(deleteNodes);
+
+        assertThat(deleteTree.getFirstChild().getName(), is("test"));
+
+        cont1YdtContext = deleteTree.getFirstChild().getFirstChild();
+        assertThat(cont1YdtContext.getName(), is("cont1"));
+
+        list1YdtContext = cont1YdtContext.getFirstChild();
+        assertThat(list1YdtContext.getName(), is("list1"));
+
+        ydtContext = list1YdtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf2"));
+        assertThat(ydtContext.getValue(), is("2"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf3"));
+        assertThat(ydtContext.getValue(), is("3"));
+
+        assertThat(list1YdtContext.getNextSibling(), nullValue());
+
+        list2YdtContext = cont1YdtContext.getNextSibling();
+        assertThat(list2YdtContext.getName(), is("list2"));
+
+        ydtContext = list2YdtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf5"));
+        assertThat(ydtContext.getValue(), is("5"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf6"));
+        assertThat(ydtContext.getValue(), is("6"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+
+        // verify whether ydt tree is correct
+        ydtContext = appContext.getModuleContext();
+        assertThat(ydtContext.getName(), is("test"));
+
+        cont1YdtContext = ydtContext.getFirstChild();
+        assertThat(cont1YdtContext.getName(), is("cont1"));
+
+        ydtContext = cont1YdtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf4"));
+        assertThat(ydtContext.getValue(), is("4"));
+
+        ydtContext = cont1YdtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf10"));
+        assertThat(ydtContext.getValue(), is("10"));
+    }
+
+    /**
+     * Checks whether there is no exception when there is valid edit
+     * request.
+     */
+    @Test
+    public void testExecuteEditOperationWithoutDelete()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForEditOperationWithoutDelete();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks whether there is no exception when there is valid delete
+     * request.
+     */
+    @Test
+    public void testExecuteEditOperationWithDelete()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForEditOperationWithDelete();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks whether there is no exception when there is valid edit
+     * request for list.
+     */
+    @Test
+    public void testExecuteListEditOperationWithoutDelete()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForListEditOperationWithoutDelete();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks whether there is no exception when there is valid delete
+     * request for list.
+     */
+    @Test
+    public void testExecuteListEditOperationWithDelete()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForListEditOperationWithDelete();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks whether there is no exception when there is valid query
+     * request.
+     */
+    @Test
+    public void testExecuteQueryOperation()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder = buildYdtForQueryOperation();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks whether there is no exception when there is valid query
+     * request for list.
+     */
+    @Test
+    public void testExecuteListQueryOperation()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForListQueryOperation();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks whether delete tree is updated correctly.
+     */
+    @Test
+    public void testSiblingsInDeleteTree()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder = buildYdtWithOneDeleteNode();
+        YdtAppContext appContext =
+                defaultYdtBuilder.getAppRootNode().getFirstChild();
+        YdtContext ydtContext = appContext.getModuleContext();
+        List<YdtContext> deleteNodes = appContext.getDeleteNodes();
+
+        // verify whether ydt tree is correct
+        assertThat(ydtContext.getName(), is("test"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("cont1"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("cont4"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf10"));
+        assertThat(ydtContext.getValue(), is("10"));
+
+        // build delete tree
+        YangApplicationBroker yab = new YangApplicationBroker(null);
+        YdtContext deleteTree = yab.buildDeleteTree(deleteNodes);
+
+        assertThat(deleteTree.getFirstChild().getName(), is("test"));
+
+        ydtContext = deleteTree.getFirstChild().getFirstChild();
+        assertThat(ydtContext.getName(), is("cont4"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+        assertThat(ydtContext.getPreviousSibling(), nullValue());
+
+        ydtContext = appContext.getModuleContext();
+
+        // verify whether ydt tree is correct
+        assertThat(ydtContext.getName(), is("test"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("cont1"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf10"));
+        assertThat(ydtContext.getValue(), is("10"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+    }
+
+    /**
+     * Checks last child is updated correctly after delete tree is built.
+     */
+    @Test
+    public void testLastChildInYdtTree()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtWithDeleteNodeAsLastChild();
+        YdtAppContext appContext =
+                defaultYdtBuilder.getAppRootNode().getFirstChild();
+        YdtContext ydtContext = appContext.getModuleContext();
+        List<YdtContext> deleteNodes = appContext.getDeleteNodes();
+        assertThat(YdtAppNodeOperationType.BOTH,
+                   is(appContext.getOperationType()));
+
+        // verify whether ydt tree is correct
+        assertThat(ydtContext.getName(), is("test"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("cont1"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("list2"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("cont4"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+
+        // build delete tree
+        YangApplicationBroker yab = new YangApplicationBroker(null);
+        YdtContext deleteTree = yab.buildDeleteTree(deleteNodes);
+
+        assertThat(deleteTree.getFirstChild().getName(), is("test"));
+
+        ydtContext = deleteTree.getFirstChild().getFirstChild();
+        assertThat(ydtContext.getName(), is("cont4"));
+
+        ydtContext = deleteTree.getFirstChild().getLastChild();
+        assertThat(ydtContext.getName(), is("cont4"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+        assertThat(ydtContext.getPreviousSibling(), nullValue());
+
+        ydtContext = appContext.getModuleContext();
+
+        assertThat(ydtContext.getLastChild().getName(), is("list2"));
+
+        // verify whether ydt tree is correct
+        assertThat(ydtContext.getName(), is("test"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("cont1"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("list2"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+    }
+
+    /**
+     * Checks YDT tree with all delete nodes.
+     */
+    @Test
+    public void testYdtTreeWithAllDeleteNodes()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder = buildYdtWithAllDeleteNode();
+        YdtAppContext appContext =
+                defaultYdtBuilder.getAppRootNode().getFirstChild();
+        YdtContext ydtContext = appContext.getModuleContext();
+        List<YdtContext> deleteNodes = appContext.getDeleteNodes();
+
+        assertThat(YdtAppNodeOperationType.DELETE_ONLY,
+                   is(appContext.getOperationType()));
+
+        // verify whether ydt tree is correct
+        assertThat(ydtContext.getName(), is("test"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("cont1"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("list2"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("cont4"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+
+        // build delete tree
+        YangApplicationBroker yab = new YangApplicationBroker(null);
+        YdtContext deleteTree = yab.buildDeleteTree(deleteNodes);
+
+        assertThat(deleteTree.getFirstChild().getName(), is("test"));
+
+        ydtContext = deleteTree.getFirstChild().getFirstChild();
+        assertThat(ydtContext.getName(), is("cont1"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("list2"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("cont4"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+    }
+
+    /**
+     * Checks whether key leaves are also available when there is delete
+     * request for list.
+     */
+    @Test
+    public void testKeyLeavesInDeleteTree() throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder = buildYdtForKeyLeavesInDeleteTree();
+
+        YdtAppContext appContext =
+                defaultYdtBuilder.getAppRootNode().getFirstChild();
+        YdtContext ydtContext = appContext.getModuleContext();
+        List<YdtContext> deleteNodes = appContext.getDeleteNodes();
+
+        assertThat(YdtAppNodeOperationType.BOTH, is(appContext.getOperationType()));
+
+        // verify whether ydt tree is correct
+        assertThat(ydtContext.getName(), is("test"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("list2"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf5"));
+        assertThat(ydtContext.getValue(), is("5"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf6"));
+        assertThat(ydtContext.getValue(), is("6"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf7"));
+        assertThat(ydtContext.getValue(), is("7"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("cont7"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+
+        // build delete tree
+        YangApplicationBroker yab = new YangApplicationBroker(null);
+        YdtContext deleteTree = yab.buildDeleteTree(deleteNodes);
+
+        assertThat(deleteTree.getFirstChild().getName(), is("test"));
+
+        ydtContext = deleteTree.getFirstChild().getFirstChild();
+        assertThat(ydtContext.getName(), is("list2"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext, notNullValue());
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext, notNullValue());
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("cont7"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+
+        ydtContext = appContext.getModuleContext();
+
+        // verify whether ydt tree is correct
+        assertThat(ydtContext.getName(), is("test"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("list2"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("leaf5"));
+        assertThat(ydtContext.getValue(), is("5"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf6"));
+        assertThat(ydtContext.getValue(), is("6"));
+
+        ydtContext = ydtContext.getNextSibling();
+        assertThat(ydtContext.getName(), is("leaf7"));
+        assertThat(ydtContext.getValue(), is("7"));
+
+        assertThat(ydtContext.getNextSibling(), nullValue());
+    }
+
+    /**
+     * Checks YDT tree and application tree for query request with mutiple
+     * augments.
+     */
+    @Test
+    public void testApptreeForQueryWithMultipleAugment()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder = buildYdtForQueryWithMultipleAugment();
+        YdtAppContext appContext = defaultYdtBuilder.getAppRootNode()
+                .getFirstChild();
+        YdtContext ydtNode = appContext.getModuleContext();
+        YangNode yangNode = (YangNode) ((YdtNode) ydtNode).getYangSchemaNode();
+
+        YangApplicationBroker yab = new YangApplicationBroker(defaultYdtBuilder.
+                getYangSchemaRegistry());
+        yab.processAugmentForChildNode(appContext, yangNode);
+
+        assertThat(appContext.getModuleContext().getName(), is("test"));
+
+        appContext = appContext.getFirstChild();
+
+        String augmentName = ((YangAugment) appContext
+                .getAugmentingSchemaNode()).getTargetNode().get(0)
+                .getResolvedNode().getJavaClassNameOrBuiltInType();
+        assertThat(augmentName, is("cont4"));
+
+        appContext = appContext.getFirstChild();
+        augmentName = ((YangAugment) appContext
+                .getAugmentingSchemaNode()).getTargetNode().get(0)
+                .getResolvedNode().getJavaClassNameOrBuiltInType();
+        assertThat(augmentName, is("cont4"));
+        assertThat(appContext.getFirstChild(), nullValue());
+        assertThat(appContext.getLastChild(), nullValue());
+    }
+
+    /**
+     * Checks whether there is no exception when there is valid query request
+     * for data resource with multiple augments.
+     */
+    @Test
+    public void testQueryWithMultipleAugment()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder = buildYdtForQueryWithMultipleAugment();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks whether YDT is updated correctly for delete with multiple augment.
+     */
+    @Test
+    public void testYdtForDeleteWithMultipleAugment()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForDeleteWithMultipleAugment();
+        YdtAppContext appContext = defaultYdtBuilder.getAppRootNode()
+                .getFirstChild();
+
+        YangApplicationBroker yab = new YangApplicationBroker(defaultYdtBuilder.
+                getYangSchemaRegistry());
+        YdtContext deleteTree = yab.buildDeleteTree(appContext.getDeleteNodes());
+        yab.processAugmentedNodesForDelete(deleteTree.getFirstChild(),
+                                           appContext);
+
+        assertThat(appContext.getModuleContext().getName(), is("test"));
+
+        appContext = appContext.getFirstChild();
+        String augmentName = ((YangAugment) appContext
+                .getAugmentingSchemaNode()).getTargetNode().get(0)
+                .getResolvedNode().getJavaClassNameOrBuiltInType();
+        assertThat(augmentName, is("cont4"));
+
+        appContext = appContext.getFirstChild();
+        augmentName = ((YangAugment) appContext
+                .getAugmentingSchemaNode()).getTargetNode().get(0)
+                .getResolvedNode().getJavaClassNameOrBuiltInType();
+        assertThat(augmentName, is("cont4"));
+        assertThat(appContext.getFirstChild(), nullValue());
+        assertThat(appContext.getLastChild(), nullValue());
+
+        YdtContext ydtContext = deleteTree.getFirstChild();
+        assertThat(ydtContext.getName(), is("test"));
+
+        ydtContext = ydtContext.getFirstChild();
+        assertThat(ydtContext.getName(), is("cont4"));
+    }
+
+    /**
+     * Checks whether there is no exception when there is valid delete request
+     * for data resource with multiple augments.
+     */
+    @Test
+    public void testDeleteWithMultipleAugment() {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForDeleteWithMultipleAugment();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks execute operation for rpc request with only output.
+     */
+    @Test
+    public void testRpcWithOutput()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForRpcWithOnlyOutput();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks execute operation for rpc request with only input.
+     */
+    @Test
+    public void testRpcWithInput()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForRpcWithOnlyInput();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks execute operation for rpc request with input and output.
+     */
+    @Test
+    public void testRpcWithInputOutput()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForRpcWithBothInputOutput();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+
+    /**
+     * Checks execute operation for rpc request without input and
+     * output.
+     */
+    @Test
+    public void testRpcWithoutInputOutput()
+            throws IOException, CloneNotSupportedException {
+        YangRequestWorkBench defaultYdtBuilder =
+                buildYdtForRpc();
+        ymsManager.executeOperation(defaultYdtBuilder);
+    }
+}
\ No newline at end of file
diff --git a/apps/yms/app/src/test/resources/yabTestYangFiles/test.yang b/apps/yms/app/src/test/resources/yabTestYangFiles/test.yang
new file mode 100644
index 0000000..e37bed6
--- /dev/null
+++ b/apps/yms/app/src/test/resources/yabTestYangFiles/test.yang
@@ -0,0 +1,111 @@
+module test {
+
+    yang-version 1;
+    namespace "ydt.test";
+    prefix "t6";
+    organization "ON-LAB";
+
+    revision "2016-05-24" {
+        description "Initial revision.";
+    }
+
+    container cont1 {
+        container cont2 {
+                container cont3 {
+                    leaf leaf1 {
+                        type string;
+                    }
+                }
+        }
+        list list1 {
+           key leaf2;
+           leaf leaf2 {
+               type string;
+           }
+           leaf leaf3 {
+               type string;
+           }
+       }
+       leaf leaf4 {
+          type string;
+       }
+    }
+    list list2 {
+        key "leaf5 leaf6";
+        leaf leaf5 {
+            type string;
+        }
+        leaf leaf6 {
+            type string;
+        }
+        leaf leaf7 {
+            type string;
+        }
+        leaf-list leaflist8 {
+            type string;
+        }
+        container cont7 {
+            leaf leaf12 {
+                type string;
+            }
+        }
+    }
+    container cont4 {
+        container cont5 {
+            leaf leaf9 {
+                type string;
+            }
+        }
+    }
+    leaf leaf10 {
+       type string;
+    }
+
+    rpc rock-the-house {
+        input {
+            leaf zip-code {
+                type string;
+            }
+        }
+        output {
+            leaf hello {
+                type string;
+            }
+        }
+    }
+
+    rpc rock-the-house1 {
+        input {
+            leaf leaf13 {
+               type string;
+            }
+        }
+    }
+
+    rpc rock-the-house2 {
+        output {
+            leaf leaf14 {
+                type string;
+            }
+        }
+    }
+
+    rpc rock-the-house3 {
+    }
+
+    augment "/cont4" {
+        container cont6 {
+            leaf leaf11 {
+                type string;
+            }
+        }
+    }
+
+    augment "/cont4/cont6" {
+        container cont7 {
+            leaf leaf12 {
+                type string;
+            }
+        }
+    }
+}
