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
