diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YdtUtils.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YdtUtils.java
new file mode 100644
index 0000000..a9f15f2
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YdtUtils.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.onosproject.yms.app.ydt;
+
+import org.onosproject.yangutils.datamodel.YangAugment;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
+import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yms.app.ydt.exceptions.YdtException;
+import org.onosproject.yms.ydt.YdtContextOperationType;
+
+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.app.ydt.YdtConstants.errorMsg;
+import static org.onosproject.yms.ydt.YdtContextOperationType.CREATE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.MERGE;
+
+/**
+ * Utils to support yang data tree node creation.
+ */
+final class YdtUtils {
+
+    // YDT formatted error string
+    private static final String E_CREATE_OP =
+            "Create request is not allowed under delete operation.";
+    private static final String E_DELETE_OP =
+            "Delete request is not allowed under create operation.";
+    private static final String FMT_TOO_FEW =
+            "Too few key parameters in %s. Expected %d; actual %d.";
+    private static final String FMT_TOO_MANY =
+            "Too many key parameters in %s. Expected %d; actual %d.";
+
+    //No instantiation.
+    private YdtUtils() {
+    }
+
+    /**
+     * Returns the app tree operation type with the help of YdtOperation type.
+     *
+     * @param opType ydt operation type
+     * @return app tree operation type
+     */
+    static YdtAppNodeOperationType getAppOpTypeFromYdtOpType(
+            YdtContextOperationType opType) {
+        // Get the app tree operation type.
+        switch (opType) {
+            case CREATE:
+            case MERGE:
+            case REPLACE:
+                return OTHER_EDIT;
+
+            case DELETE:
+            case REMOVE:
+                return DELETE_ONLY;
+
+            default:
+                return null;
+            //TODO handle the default data type.
+        }
+    }
+
+    /**
+     * Validates the various combination of operation type.
+     *
+     * @param parentOpType Reference for parent node operation type
+     * @param childOpType  type of YANG data tree node operation
+     * @throws YdtException when user requested node operation type is
+     *                      not valid as per parent node operation type
+     */
+    private static void validateOperationType(YdtContextOperationType parentOpType,
+                                              YdtContextOperationType childOpType)
+            throws YdtException {
+
+        switch (parentOpType) {
+            case CREATE:
+                // Inside the create operation delete operation should not come.
+                if (childOpType == DELETE) {
+                    throw new YdtException(E_CREATE_OP);
+                }
+                break;
+            case DELETE:
+                // Inside the delete operation create operation should not come.
+                if (childOpType == CREATE) {
+                    throw new YdtException(E_DELETE_OP);
+                }
+                break;
+            default:
+                //TODO check all possible scenario.
+        }
+    }
+
+    /**
+     * Returns the operation type for non leaf node.
+     * When "operation" attribute for current node is not specified or null,
+     * then the operation applied to the parent data node of the
+     * configuration is used. If no parent data node is available,
+     * then the default-operation'value is used.
+     * If default operation type is not set, merge will be taken as default
+     * operation type.
+     *
+     * @param type    operation type of parent node
+     * @param defType YDT default operation type
+     * @return operation type for current non leaf node
+     */
+    private static YdtContextOperationType getOperationType(
+            YdtContextOperationType type, YdtContextOperationType defType) {
+        return type != null ? type : (defType != null ? defType : MERGE);
+    }
+
+    /**
+     * Returns the yang node identifier with requested name and namespace.
+     *
+     * @param name      name of the node
+     * @param namespace namespace of the node
+     * @return yang node identifier
+     */
+    static YangSchemaNodeIdentifier getNodeIdentifier(String name,
+                                                      String namespace) {
+        YangSchemaNodeIdentifier id = new YangSchemaNodeIdentifier();
+        id.setName(name);
+        id.setNameSpace(new NameSpace(namespace));
+        return id;
+    }
+
+    /**
+     * Checks the user supplied list of argument match's the expected value
+     * or not.
+     *
+     * @param name     name of the parent list/leaf-list node
+     * @param expected count suppose to be
+     * @param actual   user supplied values count
+     * @throws YdtException when user requested multi instance node instance's
+     *                      count doesn't fit into the allowed instance limit
+     */
+    static void checkElementCount(String name, int expected,
+                                  int actual) throws YdtException {
+        if (expected < actual) {
+            throw new YdtException(
+                    errorMsg(FMT_TOO_MANY, name, expected, actual));
+        } else if (expected > actual) {
+            throw new YdtException(
+                    errorMsg(FMT_TOO_FEW, name, expected, actual));
+        }
+    }
+
+    /**
+     * Returns the valid operation type for requested ydt node after performing
+     * validation.
+     *
+     * @param opType     user requested operation type
+     * @param newNode    new requested ydt node
+     * @param parentNode parent node under which new node to be added
+     * @return operation type
+     * @throws YdtException when user requested node operation type is
+     *                      not valid as per parent node operation type
+     */
+    static YdtContextOperationType getValidOpType(
+            YdtContextOperationType opType, YdtContextOperationType defOpType,
+            YdtNode newNode, YdtNode parentNode)
+            throws YdtException {
+
+        switch (newNode.getYdtType()) {
+
+            case SINGLE_INSTANCE_NODE:
+            case MULTI_INSTANCE_NODE:
+
+                // Reference for parent node operation type.
+                YdtContextOperationType parentOpType =
+                        parentNode.getYdtContextOperationType();
+
+                if (opType == null) {
+                    opType = getOperationType(parentOpType, defOpType);
+                } else if (parentOpType != null) {
+                    validateOperationType(parentOpType, opType);
+                }
+
+                return opType;
+
+            /*
+             * Nodes other then single/multi instance node does not support
+             * operation type so no need of validation for those.
+             */
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Returns augmenting node module yang schema node.
+     *
+     * @param id          schema node identifier
+     * @param contextInfo Yang Schema node context info
+     *                    which is having YangSchemaNode and
+     *                    ContextSwitchedNode
+     * @return augmenting node module yang schema node
+     * @throws YdtException when user requested node schema doesn't exist
+     */
+    public static YangSchemaNode getAugmentingSchemaNode(
+            YangSchemaNodeIdentifier id,
+            YangSchemaNodeContextInfo contextInfo) throws YdtException {
+        YangSchemaNode lastAugMod = null;
+        YangSchemaNode switchedNode =
+                contextInfo.getContextSwitchedNode();
+
+        // Finding the last augmenting schema for case/choice scenario.
+        while (switchedNode != null) {
+            if (switchedNode instanceof YangAugment) {
+                lastAugMod = switchedNode;
+            }
+            try {
+                switchedNode = switchedNode.getChildSchema(id)
+                        .getContextSwitchedNode();
+            } catch (DataModelException e) {
+                throw new YdtException(e.getMessage());
+            }
+        }
+        return lastAugMod;
+    }
+
+    /**
+     * De-reference all the tree node by walking the whole YDT from logical
+     * root node.
+     * This will be called only when any exception occurs while processing
+     * the node in Ydt tree.
+     *
+     * @param rootNode ydt logical root node
+     */
+    public static void freeRestResources(YdtNode rootNode) {
+
+        YdtNode currentNode = rootNode;
+        while (currentNode != null) {
+
+            // Move down to first child
+            YdtNode nextNode = currentNode.getFirstChild();
+            if (nextNode != null) {
+                currentNode = nextNode;
+                continue;
+            }
+
+            // No child nodes, so walk tree
+            while (currentNode != null) {
+                // To keep the track of last sibling.
+                YdtNode lastSibling = currentNode;
+
+                // Move to sibling if possible.
+                nextNode = currentNode.getNextSibling();
+
+                // free currentNode resources
+                free(lastSibling);
+
+                lastSibling.getNamespace();
+                if (nextNode != null) {
+                    currentNode = nextNode;
+                    break;
+                }
+
+                // Move up
+                if (currentNode.equals(rootNode)) {
+                    currentNode = null;
+                } else {
+                    currentNode = currentNode.getParent();
+                    lastSibling.setParent(null);
+                }
+            }
+        }
+    }
+
+    /**
+     * Free the give YDT node by de-referencing it to null.
+     *
+     * @param node node to be freed
+     */
+    private static void free(YdtNode node) {
+        if (node.getParent() != null) {
+            YdtNode parent = node.getParent();
+            parent.setChild(null);
+            parent.setLastChild(null);
+            if (node.getNextSibling() != null) {
+                parent.setChild(node.getNextSibling());
+            }
+        }
+        YdtNode parentRef = node.getParent();
+        node = new YdtLogicalNode(null, null);
+        node.setParent(parentRef);
+    }
+}
