[ONOS-5149] YPM Implementation

Change-Id: I9814d28cfe5e4278019fa565ea6d16bd8778b4c8
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ypm/DefaultYpmNode.java b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/DefaultYpmNode.java
new file mode 100644
index 0000000..662d3c3
--- /dev/null
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/DefaultYpmNode.java
@@ -0,0 +1,226 @@
+/*
+ * 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.ypm;
+
+/**
+ * Represents implementation of interfaces to build and obtain YANG protocol metadata tree node.
+ */
+public class DefaultYpmNode implements YpmContext {
+
+    /**
+     * Name of the node.
+     */
+    private String name;
+
+    /**
+     * Parent reference.
+     */
+    private DefaultYpmNode parent;
+
+    /**
+     * First child reference.
+     */
+    private DefaultYpmNode child;
+
+    /**
+     * Next sibling reference.
+     */
+    private DefaultYpmNode nextSibling;
+
+    /**
+     * Previous sibling reference.
+     */
+    private DefaultYpmNode previousSibling;
+
+    /**
+     * Protocol metadata object.
+     */
+    private Object metaData;
+
+    /**
+     * Creates a specific type of node.
+     *
+     * @param name of ypm node
+     */
+    public DefaultYpmNode(String name) {
+        setName(name);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public DefaultYpmNode getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(YpmContext parent) {
+        this.parent = (DefaultYpmNode) parent;
+    }
+
+    @Override
+    public YpmContext getFirstChild() {
+        return child;
+    }
+
+    @Override
+    public YpmContext getChild(String ypmName) {
+        if (ypmName == null) {
+            // Input is null. So, will not proceed.
+            return null;
+        }
+
+        if (child == null) {
+            // No children
+            return null;
+        }
+
+        // Check the first child
+        if (child.name.equals(ypmName)) {
+            return child;
+        }
+
+        // Check its siblings
+        YpmContext currentChild = child;
+        while (currentChild.getNextSibling() != null) {
+            currentChild = currentChild.getNextSibling();
+            if (currentChild.getName().equals(ypmName)) {
+                return currentChild;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public void addChild(String ypmName) {
+        if (ypmName == null) {
+            // Input is null. So, will not proceed.
+            return;
+        }
+
+        if (getChild(ypmName) != null) {
+            // Already available with the same name. So, no need to add
+            return;
+        }
+
+        // Create new ypm node and attach to its parent
+        DefaultYpmNode newNode = new DefaultYpmNode(ypmName);
+        newNode.setParent(this);
+
+        // Check the first child
+        if (child == null) {
+            child = newNode;
+            return;
+        }
+
+        // Add it to its siblings
+        YpmContext currentChild = child;
+        // Go to the last child
+        while (currentChild.getNextSibling() != null) {
+            currentChild = currentChild.getNextSibling();
+        }
+        currentChild.setNextSibling(newNode);
+        newNode.setPreviousSibling((DefaultYpmNode) currentChild);
+    }
+
+    @Override
+    public YpmContext getSibling(String ypmName) {
+        if (ypmName == null) {
+            // Input is null. So, will not proceed.
+            return null;
+        }
+
+        YpmContext sibling = getNextSibling();
+        while (sibling != null) {
+            if (sibling.getName().equals(ypmName)) {
+                return sibling;
+            }
+            sibling = sibling.getNextSibling();
+        }
+        return null;
+    }
+
+    @Override
+    public void addSibling(String ypmName) {
+        if (ypmName == null) {
+            // Input is null. So, will not proceed.
+            return;
+        }
+
+        if (getSibling(ypmName) != null) {
+            // Already available with the same name. So, no need to add
+            return;
+        }
+
+        // Create new ypm node and attach to its parent
+        DefaultYpmNode newSibling = new DefaultYpmNode(ypmName);
+        newSibling.setParent(this.getParent());
+
+        // Add it as its sibling
+        YpmContext sibling = getNextSibling();
+        if (sibling == null) {
+            setNextSibling(newSibling);
+            newSibling.setPreviousSibling(this);
+        } else {
+            // Go to the last sibling
+            while (sibling.getNextSibling() != null) {
+                sibling = sibling.getNextSibling();
+            }
+            sibling.setNextSibling(newSibling);
+            newSibling.setPreviousSibling((DefaultYpmNode) sibling);
+        }
+    }
+
+    @Override
+    public DefaultYpmNode getNextSibling() {
+        return nextSibling;
+    }
+
+    @Override
+    public void setNextSibling(DefaultYpmNode sibling) {
+        nextSibling = sibling;
+    }
+
+    @Override
+    public DefaultYpmNode getPreviousSibling() {
+        return previousSibling;
+    }
+
+    @Override
+    public void setPreviousSibling(DefaultYpmNode sibling) {
+        this.previousSibling = sibling;
+    }
+
+    @Override
+    public Object getMetaData() {
+        return this.metaData;
+    }
+
+    @Override
+    public void setMetaData(Object data) {
+        this.metaData = data;
+    }
+}
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmContext.java b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmContext.java
new file mode 100644
index 0000000..fe7efb5
--- /dev/null
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmContext.java
@@ -0,0 +1,131 @@
+/*
+ * 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.ypm;
+
+/**
+ * Abstraction of an entity which represents YANG protocol metadata context
+ * information.
+ */
+public interface YpmContext {
+
+    /**
+     * Returns the node name.
+     *
+     * @return node name
+     */
+    String getName();
+
+    /**
+     * Sets the nodes name.
+     *
+     * @param name nodes name
+     */
+    void setName(String name);
+
+    /**
+     * Returns the context of parent node.
+     *
+     * @return context of parent node
+     */
+    YpmContext getParent();
+
+    /**
+     * Sets the context of parent node.
+     *
+     * @param parent node parent
+     */
+    void setParent(YpmContext parent);
+
+    /**
+     * Retrieves the first child of a node.
+     *
+     * @return first child of a node
+     */
+    YpmContext getFirstChild();
+
+    /**
+     * Retrieves the child of a node for corresponding ydt node.
+     *
+     * @param name ypm node
+     * @return child of a node
+     */
+    YpmContext getChild(String name);
+
+    /**
+     * Adds child to a node by ydt name.
+     *
+     * @param name ypm name
+     */
+    void addChild(String name);
+
+    /**
+     * Retrieves sibling of a child by (ydt) name.
+     *
+     * @param name ypm name
+     * @return sibling of a child
+     */
+    YpmContext getSibling(String name);
+
+    /**
+     * Adds new sibling to a child.
+     *
+     * @param name ypm name
+     */
+    void addSibling(String name);
+
+    /**
+     * Returns the context of next sibling.
+     *
+     * @return context of next sibling
+     */
+    YpmContext getNextSibling();
+
+    /**
+     * Sets the next sibling of node.
+     *
+     * @param sibling ypm node
+     */
+    void setNextSibling(DefaultYpmNode sibling);
+
+    /**
+     * Returns the previous sibling of a node.
+     *
+     * @return previous sibling of a node
+     */
+    DefaultYpmNode getPreviousSibling();
+
+    /**
+     * Sets the previous sibling.
+     *
+     * @param previousSibling points to predecessor sibling
+     */
+    void setPreviousSibling(DefaultYpmNode previousSibling);
+
+    /**
+     * Retrieves protocol metadata.
+     *
+     * @return metadata
+     */
+    Object getMetaData();
+
+    /**
+     * Sets the protocol metadata.
+     *
+     * @param data metadata
+     */
+    void setMetaData(Object data);
+}
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmService.java b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmService.java
new file mode 100644
index 0000000..18ecd8a
--- /dev/null
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmService.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.ypm;
+
+import org.onosproject.yms.ydt.YdtContext;
+
+/**
+ * Abstraction of an entity which provides interfaces to YANG Protocol Metadata Manager.
+ */
+public interface YpmService {
+
+    /**
+     * Returns the protocol data stored in sepecific data model path.
+     *
+     * @param rootNode YANG data tree
+     * @return YANG protocol metadata
+     */
+    YpmContext getProtocolData(YdtContext rootNode);
+
+    /**
+     * Sets the YANG protocol metadata in specific ydt path in ypm tree.
+     *
+     * @param rootNode YANG data tree
+     * @param data YANG protocol metadata
+     */
+    void setProtocolData(YdtContext rootNode, Object data);
+}
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ypm/package-info.java b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/package-info.java
new file mode 100644
index 0000000..b1472aa
--- /dev/null
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/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 protocol metadata manager. YPM maintains protocol specific information
+ * (like timestamp, entity tag, etc.) for YANG modeled data.
+ */
+package org.onosproject.yms.ypm;
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ypm/YpmManager.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ypm/YpmManager.java
new file mode 100644
index 0000000..6d6468a
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ypm/YpmManager.java
@@ -0,0 +1,177 @@
+/*
+ * 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.ypm;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.yms.ydt.YdtContext;
+import org.onosproject.yms.ypm.YpmContext;
+import org.onosproject.yms.ypm.YpmService;
+import org.onosproject.yms.ypm.DefaultYpmNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents implementation of YANG protocol metadata manager.
+ */
+@Service
+@Component(immediate = true)
+public class YpmManager implements YpmService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private YpmContext rootYpmNode;
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    @Override
+    public YpmContext getProtocolData(YdtContext rootYdtNode) {
+        if (rootYdtNode == null) {
+            log.debug("Input data is null. So, will not proceed.");
+            return null;
+        }
+
+        // Iterate through YDT and search the path in YPM tree and create new YPM tree equivalent to given YDT
+        // and return it.
+        if (rootYpmNode == null) {
+            log.debug("YPM tree has no data.");
+            return null;
+        }
+
+        YdtContext currentYdtNode = rootYdtNode;
+        YpmContext currentYpmNode = rootYpmNode;
+        YpmContext rootRetYpmNode = new DefaultYpmNode(currentYdtNode.getName());
+        YpmContext currRetYpmNode = rootRetYpmNode;
+        while (currentYdtNode != null) {
+            // Each ypm node can have children. So, create new corresponding ypm child
+            // and add it to new returning ypm tree, otherwise return new ypm tree.
+            YdtContext nextNode = currentYdtNode.getFirstChild();
+            if (nextNode != null) {
+                YpmContext ypmChild = currentYpmNode.getChild(nextNode.getName());
+                if (ypmChild != null) {
+                    currRetYpmNode.addChild(ypmChild.getName());
+                } else {
+                    return rootRetYpmNode;
+                }
+                currentYdtNode = nextNode;
+                currentYpmNode = currentYpmNode.getChild(nextNode.getName());
+                currRetYpmNode = currRetYpmNode.getChild(nextNode.getName());
+                currRetYpmNode.setMetaData(currentYpmNode.getMetaData());
+                continue;
+            }
+
+            // No child nodes, so walk tree
+            while (currentYdtNode != null) {
+                // Each ypm node can have sibling. So, create new corresponding ypm sibling node
+                // and add it to new returning ypm tree, otherwise return new ypm tree.
+                nextNode = currentYdtNode.getNextSibling();
+                if (nextNode != null) {
+                    YpmContext ypmSibling = currentYpmNode.getSibling(nextNode.getName());
+                    if (ypmSibling != null) {
+                        currRetYpmNode.addSibling(ypmSibling.getName());
+                    } else {
+                        return rootRetYpmNode;
+                    }
+                    currentYdtNode = nextNode;
+                    currentYpmNode = currentYpmNode.getSibling(nextNode.getName());
+                    currRetYpmNode = currRetYpmNode.getSibling(nextNode.getName());
+                    currRetYpmNode.setMetaData(currentYpmNode.getMetaData());
+                    break;
+                }
+
+                // Move up
+                if (currentYdtNode == rootYdtNode) {
+                    currentYdtNode = null;
+                } else {
+                    currentYdtNode = currentYdtNode.getParent();
+                    currentYpmNode = currentYpmNode.getParent();
+                    currRetYpmNode = currRetYpmNode.getParent();
+                }
+            }
+        }
+
+        return rootRetYpmNode;
+    }
+
+    @Override
+    public void setProtocolData(YdtContext rootYdtNode, Object data) {
+        if (rootYdtNode == null || data == null) {
+            log.debug("Input data is null. So, will not proceed.");
+            return;
+        }
+
+        // Iterate through YDT and add each node of this path to ypm tree if it is not exists
+        YdtContext currentYdtNode = rootYdtNode;
+        YpmContext currentYpmNode = rootYpmNode;
+        while (currentYdtNode != null) {
+            // Check the ypm root node first
+            if (rootYpmNode == null) {
+                rootYpmNode = new DefaultYpmNode(currentYdtNode.getName());
+                currentYpmNode = rootYpmNode;
+                // In logical node, should not set protocol metadata
+            }
+
+            // Move down to first child
+            YdtContext nextNode = currentYdtNode.getFirstChild();
+            if (nextNode != null) {
+                // Each ypm node can have sibling. So, get corresponding sibling node, otherwise create it.
+                if (currentYpmNode.getChild(nextNode.getName()) == null) {
+                    currentYpmNode.addChild(nextNode.getName());
+                }
+                currentYpmNode = currentYpmNode.getChild(nextNode.getName());
+                // Set/update protocol metadata
+                currentYpmNode.setMetaData(data);
+                currentYdtNode = nextNode;
+                continue;
+            }
+
+            // No child nodes, so walk tree
+            while (currentYdtNode != null) {
+                // Move to sibling if possible.
+                nextNode = currentYdtNode.getNextSibling();
+                if (nextNode != null) {
+                    // Each ypm node can have children (sibling). So, get corresponding ypm child, otherwise create it.
+                    if (currentYpmNode.getSibling(nextNode.getName()) == null) {
+                        currentYpmNode.addSibling(nextNode.getName());
+                    }
+                    currentYpmNode = currentYpmNode.getSibling(nextNode.getName());
+                    // Set/update protocol metadata
+                    currentYpmNode.setMetaData(data);
+                    currentYdtNode = nextNode;
+                    break;
+                }
+
+                // Move up
+                if (currentYdtNode == rootYdtNode) {
+                    currentYdtNode = null;
+                } else {
+                    currentYdtNode = currentYdtNode.getParent();
+                    currentYpmNode = currentYpmNode.getParent();
+                }
+            }
+        }
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ypm/package-info.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ypm/package-info.java
new file mode 100644
index 0000000..1fab78c
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ypm/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Provides implementation of YANG protocol metadata. YPM maintains protocol
+ * specific information for YANG modeled data.
+ */
+package org.onosproject.yms.app.ypm;
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/util/YdtNodeAdapter.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/util/YdtNodeAdapter.java
new file mode 100644
index 0000000..adca2d7
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/util/YdtNodeAdapter.java
@@ -0,0 +1,359 @@
+/*
+ * 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.util;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
+import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
+import org.onosproject.yms.ydt.YdtContext;
+import org.onosproject.yms.ydt.YdtContextOperationType;
+import org.onosproject.yms.ydt.YdtExtendedInfoType;
+import org.onosproject.yms.ydt.YdtType;
+import org.onosproject.yms.app.ydt.YdtNode;
+import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.ydt.AppType;
+
+/**
+ * Represents implementation of interfaces to build and obtain YANG data tree.
+ */
+public class YdtNodeAdapter<T> implements YdtExtendedContext {
+
+    /**
+     * Parent reference.
+     */
+    private YdtNodeAdapter parent;
+
+    /**
+     * First child reference.
+     */
+    private YdtNodeAdapter child;
+
+    /**
+     * Next sibling reference.
+     */
+    private YdtNodeAdapter nextSibling;
+
+    /**
+     * Previous sibling reference.
+     */
+    private YdtNodeAdapter previousSibling;
+
+    /**
+     * Last child reference.
+     */
+    private YdtNode lastChild;
+
+    /**
+     * Type of node.
+     */
+    private YdtType ydtType;
+
+    /**
+     * Flag to keep the track of context switch.
+     */
+    private boolean isContextSwitch;
+
+    private T ydtExtendedInfo;
+
+    /**
+     * YDT extended information type.
+     */
+    YdtExtendedInfoType ydtExtendedInfoType;
+
+    /**
+     * Ydt map to keep the track of node added in YDT.
+     */
+    private Map<YangSchemaNodeIdentifier, List<YdtNode<T>>> ydtNodeMap = new HashMap<>();
+
+    /**
+     * Reference for data-model schema node.
+     */
+    private YangSchemaNode yangSchemaNode;
+
+    /**
+     * Reference for ydt node operation type.
+     */
+    private YdtContextOperationType ydtContextOperationType;
+
+    /**
+     * Key object for ydtNodeMap.
+     */
+    protected YangSchemaNodeIdentifier nodeIdentifier;
+
+    /**
+     * Ydt map to keep the track of application information object with respective type.
+     */
+    Map<AppType, Object> ydtAppInfoMap = new HashMap<>();
+
+
+    /**
+     * Creation of YANG node object.
+     */
+    public YdtNodeAdapter() {
+    }
+
+    /**
+     * Creates a specific type of node.
+     *
+     * @param type of YDT node
+     * @param name name of the YDT node
+     */
+    public YdtNodeAdapter(YdtType type, String name) {
+        setYdtType(type);
+    }
+
+    @Override
+    public String getName() {
+        return this.nodeIdentifier.getName();
+    }
+
+    @Override
+    public String getNamespace() {
+        return this.nodeIdentifier.getNameSpace();
+    }
+
+    @Override
+    public <T> T getYdtContextExtendedInfo() {
+        return (T) ydtExtendedInfo;
+    }
+
+    @Override
+    public YdtExtendedInfoType getYdtExtendedInfoType() {
+        return ydtExtendedInfoType;
+    }
+
+    @Override
+    public YdtType getYdtType() {
+        return ydtType;
+    }
+
+    /**
+     * Sets the node type.
+     *
+     * @param ydtType type of YDT attribute
+     */
+    public void setYdtType(YdtType ydtType) {
+        this.ydtType = ydtType;
+    }
+
+    @Override
+    public YdtNodeAdapter getParent() {
+        return parent;
+    }
+
+    /**
+     * Sets the parent of node.
+     *
+     * @param parent node
+     */
+    public void setParent(YdtNodeAdapter parent) {
+        this.parent = parent;
+    }
+
+    @Override
+    public YdtNodeAdapter getFirstChild() {
+        return child;
+    }
+
+    @Override
+    public YdtNodeAdapter getNextSibling() {
+        return nextSibling;
+    }
+
+    /**
+     * Sets the next sibling of node.
+     *
+     * @param sibling YANG node
+     */
+    public void setNextSibling(YdtNodeAdapter sibling) {
+        nextSibling = sibling;
+    }
+
+    @Override
+    public YdtNodeAdapter getPreviousSibling() {
+        return previousSibling;
+    }
+
+    /**
+     * Sets the previous sibling.
+     *
+     * @param previousSibling points to predecessor sibling
+     */
+    public void setPreviousSibling(YdtNodeAdapter previousSibling) {
+        this.previousSibling = previousSibling;
+    }
+
+    /**
+     * Returns data-model node reference for of a given node.
+     *
+     * @return yang schema data node of a data-model.
+     */
+    public YangSchemaNode getYangSchemaNode() {
+        return yangSchemaNode;
+    }
+
+    /**
+     * Sets the data-model node reference for of a given node..
+     *
+     * @param yangSchemaNode YANG data node.
+     */
+    public void setYangSchemaNode(YangSchemaNode yangSchemaNode) {
+        this.yangSchemaNode = yangSchemaNode;
+    }
+
+    @Override
+    public YdtNode getLastChild() {
+        return lastChild;
+    }
+
+    /**
+     * Sets the last instance of a child node.
+     *
+     * @param child is last child to be set
+     */
+    public void setLastChild(YdtNode child) {
+        this.lastChild = child;
+    }
+
+    public void setNodeIdentifier(YangSchemaNodeIdentifier nodeIdentifier) {
+        this.nodeIdentifier = nodeIdentifier;
+    }
+
+    /**
+     * Adds a child node.
+     *
+     * @param newChild refers to a child to be added
+     */
+    public void addChild(YdtContext newChild) {
+
+        ((YdtNodeAdapter) newChild).setParent(this);
+
+        if (this.child == null) {
+            this.child = (YdtNodeAdapter) newChild;
+            return;
+        }
+
+        YdtNodeAdapter currNode = this.child;
+        while (currNode.getNextSibling() != null) {
+            currNode = currNode.getNextSibling();
+        }
+        currNode.setNextSibling((YdtNodeAdapter) newChild);
+        ((YdtNodeAdapter) newChild).setPreviousSibling(currNode);
+    }
+
+    @Override
+    public YdtNode getCollindingChild(YangSchemaNodeIdentifier nodeIdentifier) {
+        return null;
+    }
+
+    /**
+     * Adds a sibling to YANG data tree.
+     *
+     * @param newSibling context of sibling to be added
+     */
+    public void addSibling(YdtContext newSibling) {
+
+        ((YdtNodeAdapter) newSibling).setParent(this.getParent());
+
+        YdtNodeAdapter currNode = this;
+
+        while (currNode.getNextSibling() != null) {
+            currNode = currNode.getNextSibling();
+        }
+        currNode.setNextSibling((YdtNodeAdapter) newSibling);
+        ((YdtNodeAdapter) newSibling).setPreviousSibling(currNode);
+    }
+
+    /**
+     * Gets the flag for node if context switch.
+     *
+     * @return isContextSwitch flag of a node.
+     */
+    public boolean getContextSwitch() {
+        return isContextSwitch;
+    }
+
+    /**
+     * Sets the flag to keep the track of context switch.
+     *
+     * @param contextSwitch boolean flag.
+     */
+    public void setContextSwitch(boolean contextSwitch) {
+        isContextSwitch = contextSwitch;
+    }
+
+    @Override
+    public String getValue() {
+        return null;
+    }
+
+    @Override
+    public Set<String> getValueSet() {
+        return null;
+    }
+
+    @Override
+    public void createKeyList() {}
+
+    @Override
+    public YangSchemaNodeIdentifier getYdtNodeIdentifier() {
+        return null;
+    }
+
+    @Override
+    public void processCollidingChild() {}
+
+    @Override
+    public void validateMultiInstanceNode() {}
+
+    @Override
+    public void addValueSetWithoutValidation(Set<String> valueSet) {}
+
+    @Override
+    public YangSchemaNodeContextInfo getSchemaNodeContextInfo(YangSchemaNodeIdentifier nodeIdentifier) {
+        return null;
+    }
+
+    @Override
+    public Object getAppInfo(AppType appType) {
+        return null;
+    }
+
+    @Override
+    public void updateYdtMap(YangSchemaNodeIdentifier nodeIdentifier, YdtContext childNode) {}
+
+    @Override
+    public void addValueWithoutValidation(String value) {}
+
+    @Override
+    public void addValue(String value) {}
+
+    @Override
+    public void setAppInfo(AppType appType, Object object) {}
+
+    @Override
+    public void addValueSet(Set<String> valueSet) {}
+
+    @Override
+    public YdtContextOperationType getYdtContextOperationType() {
+        return ydtContextOperationType;
+    }
+}
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/ypm/DefaultYpmNodeTest.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/ypm/DefaultYpmNodeTest.java
new file mode 100644
index 0000000..bec2eef
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/ypm/DefaultYpmNodeTest.java
@@ -0,0 +1,193 @@
+/*
+ * 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.ypm;
+
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+import org.onosproject.yms.ypm.YpmContext;
+import org.onosproject.yms.ypm.DefaultYpmNode;
+
+/**
+ * Unit tests for DefaultYpmNode class.
+ */
+public class DefaultYpmNodeTest {
+    private final String logicalName = "logicalYpmNode";
+    private final String moduleName1 = "portPairModule1";
+    private final String moduleName2 = "portPairModule2";
+    private final String xNodeName = "x";
+    private final String yNodeName = "y";
+    private final String zNodeName = "z";
+    private final String x1NodeName = "x1";
+    private final String x2NodeName = "x2";
+    private final String y1NodeName = "y1";
+    private final String y2NodeName = "y2";
+    private final String z1NodeName = "z1";
+    private final String z2NodeName = "z2";
+
+    /**
+     * Constructs ypm tree with single module.
+     *
+     * @return ypm tree root node
+     */
+    private YpmContext constructYpmTreeSingleModule() {
+        // Create logical node
+        DefaultYpmNode rootNode = new DefaultYpmNode(logicalName);
+        // Create module node with moduleName1
+        rootNode.addChild(moduleName1); // child to logical node
+        YpmContext moduleNode = rootNode.getChild(moduleName1);
+        moduleNode.addChild(xNodeName); // child to module node
+        moduleNode.addChild(yNodeName); // sibling node to child node "x"
+        YpmContext xNode = moduleNode.getChild("x");
+        xNode.addSibling(zNodeName); // sibling node to child node "x"
+        xNode.addChild(x1NodeName); // child to node x
+        xNode.addChild(x2NodeName); // child to node x
+        YpmContext yNode = moduleNode.getChild(yNodeName);
+        yNode.addChild(y1NodeName); // child to node y
+        yNode.addChild(y2NodeName); // child to node y
+        YpmContext zNode = moduleNode.getChild(zNodeName);
+        zNode.addChild(z1NodeName); // child to node z
+        zNode.addChild(z2NodeName); // child to node z
+        return rootNode;
+    }
+
+    /**
+     * Constructs ypm tree with multi module.
+     *
+     * @return ypm tree root node
+     */
+    private YpmContext constructYpmTreeMultiModule(DefaultYpmNode rootNode) {
+        rootNode.addChild(moduleName2); // child to logical node
+        YpmContext moduleNode = rootNode.getChild(moduleName2);
+        moduleNode.addChild(xNodeName); // child to module node
+        moduleNode.addChild(yNodeName); // sibling node to child node "x"
+        YpmContext xNode = moduleNode.getChild("x");
+        xNode.addSibling(zNodeName); // sibling node to child node "x"
+        xNode.addChild(x1NodeName); // child to node x
+        xNode.addChild(x2NodeName); // child to node x
+        YpmContext yNode = moduleNode.getChild(yNodeName);
+        yNode.addChild(y1NodeName); // child to node y
+        yNode.addChild(y2NodeName); // child to node y
+        YpmContext zNode = moduleNode.getChild(zNodeName);
+        zNode.addChild(z1NodeName); // child to node z
+        zNode.addChild(z2NodeName); // child to node z
+        return rootNode;
+    }
+
+    /**
+     * Checks ypm tree single module construction.
+     */
+    @Test
+    public void testYpmTreeSingleModuleConstruction() {
+        DefaultYpmNode rootNode = (DefaultYpmNode) constructYpmTreeSingleModule();
+        // Check one by one node
+        String name = rootNode.getName();
+        assertThat(name, is(logicalName));
+        YpmContext moduleNode = rootNode.getChild(moduleName1);
+        assertThat(moduleNode.getName(), is(moduleName1));
+        YpmContext ypmNode = moduleNode.getChild(xNodeName);
+        assertThat(ypmNode.getName(), is(xNodeName));
+        // Check sibling by using getNextSibling();
+        ypmNode = ypmNode.getNextSibling();
+        assertThat(ypmNode, notNullValue()); // either y or z should be there as sibling
+        ypmNode = ypmNode.getNextSibling();
+        assertThat(ypmNode, notNullValue()); // either y or z should be there as sibling
+        ypmNode = ypmNode.getNextSibling();
+        assertThat(ypmNode, nullValue()); // last sibling point to next sibling as null
+        // Check sibling by using getPreviousSibling()
+        ypmNode = moduleNode.getChild(zNodeName);
+        assertThat(ypmNode.getName(), is(zNodeName));
+        ypmNode = ypmNode.getPreviousSibling();
+        assertThat(ypmNode, notNullValue()); // either x or y should be there as sibling
+        ypmNode = ypmNode.getPreviousSibling();
+        assertThat(ypmNode, notNullValue()); // either x or y should be there as sibling
+        ypmNode = ypmNode.getPreviousSibling();
+        assertThat(ypmNode, nullValue()); // last sibling point to next sibling as null
+        // Checks the child x1 and x2
+        ypmNode = moduleNode.getChild(xNodeName);
+        ypmNode = ypmNode.getChild(x1NodeName);
+        assertThat(ypmNode.getName(), is(x1NodeName));
+        ypmNode = ypmNode.getSibling(x2NodeName);
+        assertThat(ypmNode.getName(), is(x2NodeName));
+        // Checks the child y1 and y2
+        ypmNode = moduleNode.getChild(yNodeName);
+        ypmNode = ypmNode.getChild(y1NodeName);
+        assertThat(ypmNode.getName(), is(y1NodeName));
+        ypmNode = ypmNode.getSibling(y2NodeName);
+        assertThat(ypmNode.getName(), is(y2NodeName));
+        // Checks the child z1 and z2
+        ypmNode = moduleNode.getChild(zNodeName);
+        ypmNode = ypmNode.getChild(z1NodeName);
+        assertThat(ypmNode.getName(), is(z1NodeName));
+        ypmNode = ypmNode.getSibling(z2NodeName);
+        assertThat(ypmNode.getName(), is(z2NodeName));
+    }
+
+    /**
+     * Checks ypm tree multiple module construction.
+     */
+    @Test
+    public void testYpmTreeMultiModuleConstruction() {
+        DefaultYpmNode rootNode = (DefaultYpmNode) constructYpmTreeSingleModule();
+        rootNode = (DefaultYpmNode) constructYpmTreeMultiModule(rootNode);
+        // Check one by one node
+        String name = rootNode.getName();
+        assertThat(name, is(logicalName));
+        YpmContext moduleNode = rootNode.getChild(moduleName2);
+        assertThat(moduleNode.getName(), is(moduleName2));
+        YpmContext ypmNode = moduleNode.getChild(xNodeName);
+        assertThat(ypmNode.getName(), is(xNodeName));
+        // Check sibling by using getNextSibling();
+        ypmNode = ypmNode.getNextSibling();
+        assertThat(ypmNode, notNullValue()); // either y or z should be there as sibling
+        ypmNode = ypmNode.getNextSibling();
+        assertThat(ypmNode, notNullValue()); // either y or z should be there as sibling
+        ypmNode = ypmNode.getNextSibling();
+        assertThat(ypmNode, nullValue()); // last sibling point to next sibling as null
+        // Check sibling by using getPreviousSibling()
+        ypmNode = moduleNode.getChild(zNodeName);
+        assertThat(ypmNode.getName(), is(zNodeName));
+        ypmNode = ypmNode.getPreviousSibling();
+        assertThat(ypmNode, notNullValue()); // either x or y should be there as sibling
+        ypmNode = ypmNode.getPreviousSibling();
+        assertThat(ypmNode, notNullValue()); // either x or y should be there as sibling
+        ypmNode = ypmNode.getPreviousSibling();
+        assertThat(ypmNode, nullValue()); // last sibling point to next sibling as null
+        // Checks the child x1 and x2
+        ypmNode = moduleNode.getChild(xNodeName);
+        ypmNode = ypmNode.getChild(x1NodeName);
+        assertThat(ypmNode.getName(), is(x1NodeName));
+        ypmNode = ypmNode.getSibling(x2NodeName);
+        assertThat(ypmNode.getName(), is(x2NodeName));
+        // Checks the child y1 and y2
+        ypmNode = moduleNode.getChild(yNodeName);
+        ypmNode = ypmNode.getChild(y1NodeName);
+        assertThat(ypmNode.getName(), is(y1NodeName));
+        ypmNode = ypmNode.getSibling(y2NodeName);
+        assertThat(ypmNode.getName(), is(y2NodeName));
+        // Checks the child z1 and z2
+        ypmNode = moduleNode.getChild(zNodeName);
+        ypmNode = ypmNode.getChild(z1NodeName);
+        assertThat(ypmNode.getName(), is(z1NodeName));
+        ypmNode = ypmNode.getSibling(z2NodeName);
+        assertThat(ypmNode.getName(), is(z2NodeName));
+    }
+}
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/ypm/YpmManagerTest.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/ypm/YpmManagerTest.java
new file mode 100644
index 0000000..7ba2219
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/ypm/YpmManagerTest.java
@@ -0,0 +1,494 @@
+/*
+ * 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.ypm;
+
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
+import org.onosproject.yms.ypm.YpmContext;
+import org.onosproject.yms.ypm.DefaultYpmNode;
+import org.onosproject.yms.app.util.YdtNodeAdapter;
+
+/**
+ * Unit tests for YpmManager class.
+ */
+public class YpmManagerTest {
+    private final String logicalName = "logicalYpmNode";
+    private final String moduleName1 = "portPairModule1";
+    private final String moduleName2 = "portPairModule2";
+    private final String xNodeName = "x";
+    private final String yNodeName = "y";
+    private final String zNodeName = "z";
+    private final String x1NodeName = "x1";
+    private final String x2NodeName = "x2";
+    private final String y1NodeName = "y1";
+    private final String y2NodeName = "y2";
+    private final String y11NodeName = "y11";
+    private final String z1NodeName = "z1";
+    private final String z2NodeName = "z2";
+    private final String z3NodeName = "z3";
+
+    /**
+     * Creates module1 ydt tree.
+     */
+    public YdtNodeAdapter createModule1Tree() throws CloneNotSupportedException {
+        YangSchemaNodeIdentifier tmpNodeIdentifier;
+        YdtNodeAdapter rootNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(logicalName);
+        rootNode.setNodeIdentifier(tmpNodeIdentifier);
+
+        // Create module node with moduleName1
+        YdtNodeAdapter moduleNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(moduleName1);
+        moduleNode.setNodeIdentifier(tmpNodeIdentifier);
+        moduleNode.setParent(rootNode);
+        rootNode.addChild(moduleNode); // child to logical node
+        YdtNodeAdapter xNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(xNodeName);
+        xNode.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter yNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(yNodeName);
+        yNode.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter zNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(zNodeName);
+        zNode.setNodeIdentifier(tmpNodeIdentifier);
+        moduleNode.addChild(xNode); // child to module node
+        xNode.addSibling(yNode);
+        yNode.addSibling(zNode);
+        YdtNodeAdapter x1Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(x1NodeName);
+        x1Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter x2Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(x2NodeName);
+        x2Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter y1Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(y1NodeName);
+        y1Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter y2Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(y2NodeName);
+        y2Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter z1Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(z1NodeName);
+        z1Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter z2Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(z2NodeName);
+        z2Node.setNodeIdentifier(tmpNodeIdentifier);
+        xNode.addChild(x1Node);
+        x1Node.addSibling(x2Node);
+        yNode.addChild(y1Node);
+        y1Node.addSibling(y2Node);
+        zNode.addChild(z1Node);
+        z1Node.addSibling(z2Node);
+
+        return rootNode;
+    }
+
+    /**
+     *  Checks the protocol data added in YpmManger when only single module exists.
+     */
+    @Test
+    public void retrieveAndCheckProtocolDataWhenSingleModule() throws CloneNotSupportedException {
+        YdtNodeAdapter rootNode = createModule1Tree();
+
+        YpmManager ypmManager = new YpmManager();
+        Object metaData = 10;
+        ypmManager.setProtocolData(rootNode, metaData);
+        YpmContext ypmContext = ypmManager.getProtocolData(rootNode);
+        DefaultYpmNode rootYpmNode = (DefaultYpmNode) ypmContext;
+        assertThat(rootYpmNode.getName(), is(logicalName));
+        DefaultYpmNode currYpmNode = (DefaultYpmNode) rootYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(moduleName1));
+        currYpmNode = (DefaultYpmNode) currYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(xNodeName));  // x node
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), notNullValue()); // y or z node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), notNullValue()); // y or z node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), nullValue());  // no sibling
+
+        // Check x node leaf's x1 and x2
+        DefaultYpmNode moduleYpmNode = currYpmNode.getParent();
+        assertThat(moduleYpmNode.getName(), is(moduleName1));
+        DefaultYpmNode xYpmNode = (DefaultYpmNode) moduleYpmNode.getFirstChild();
+        assertThat(xYpmNode.getName(), is(xNodeName));
+        assertThat(xYpmNode.getMetaData(), is(metaData));
+        // Check x1 node
+        currYpmNode = (DefaultYpmNode) xYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(x1NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        // Check x2 node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getName(), is(x2NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+
+        // Check y node leaf's y1 and y2
+        DefaultYpmNode yYpmNode = xYpmNode.getNextSibling();
+        assertThat(yYpmNode.getName(), is(yNodeName));
+        assertThat(yYpmNode.getMetaData(), is(metaData));
+        // Check y1 node
+        currYpmNode = (DefaultYpmNode) yYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(y1NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        // Check y2 node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getName(), is(y2NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+
+        // Check z node leaf's z1 and z2
+        DefaultYpmNode zYpmNode = yYpmNode.getNextSibling();
+        assertThat(zYpmNode.getName(), is(zNodeName));
+        assertThat(zYpmNode.getMetaData(), is(metaData));
+        // Check z1 node
+        currYpmNode = (DefaultYpmNode) zYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(z1NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        // Check z2 node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getName(), is(z2NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+    }
+
+    /**
+     * Creates module2 ydt tree. Module1 and Module2 trees are point to same logical root.
+     */
+    public YdtNodeAdapter createModule2Tree() throws CloneNotSupportedException {
+        YangSchemaNodeIdentifier tmpNodeIdentifier;
+        YdtNodeAdapter rootNode = createModule1Tree();
+        YdtNodeAdapter moduleNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(moduleName2);
+        moduleNode.setNodeIdentifier(tmpNodeIdentifier);
+        moduleNode.setParent(rootNode);
+        rootNode.addChild(moduleNode); // child to logical node
+        YdtNodeAdapter xNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(xNodeName);
+        xNode.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter yNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(yNodeName);
+        yNode.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter zNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(zNodeName);
+        zNode.setNodeIdentifier(tmpNodeIdentifier);
+        moduleNode.addChild(xNode); // child to module node
+        xNode.addSibling(yNode);
+        yNode.addSibling(zNode);
+        YdtNodeAdapter x1Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(x1NodeName);
+        x1Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter x2Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(x2NodeName);
+        x2Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter y1Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(y1NodeName);
+        y1Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter y2Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(y2NodeName);
+        y2Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter z1Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(z1NodeName);
+        z1Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter z2Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(z2NodeName);
+        z2Node.setNodeIdentifier(tmpNodeIdentifier);
+        xNode.addChild(x1Node);
+        x1Node.addSibling(x2Node);
+        yNode.addChild(y1Node);
+        y1Node.addSibling(y2Node);
+        zNode.addChild(z1Node);
+        z1Node.addSibling(z2Node);
+
+        return rootNode;
+    }
+
+    /**
+     *  Checks the protocol data added in YpmManger when multiple modules exists.
+     */
+    @Test
+    public void retrieveAndCheckProtocolDataWhenMultipleModule() throws CloneNotSupportedException {
+        YdtNodeAdapter rootNode = createModule2Tree();
+
+        YpmManager ypmManager = new YpmManager();
+        Object metaData = 10;
+        ypmManager.setProtocolData(rootNode, metaData);
+        YpmContext ypmContext = ypmManager.getProtocolData(rootNode);
+        DefaultYpmNode rootYpmNode = (DefaultYpmNode) ypmContext;
+        assertThat(rootYpmNode.getName(), is(logicalName));
+        DefaultYpmNode currYpmNode = (DefaultYpmNode) rootYpmNode.getFirstChild();
+        currYpmNode = currYpmNode.getNextSibling(); // jump to next module (module2)
+        assertThat(currYpmNode.getName(), is(moduleName2));
+        currYpmNode = (DefaultYpmNode) currYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(xNodeName));  // x node
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), notNullValue()); // y or z node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), notNullValue()); // y or z node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), nullValue());  // no sibling
+
+        // Check x node leaf's x1 and x2
+        DefaultYpmNode moduleYpmNode = currYpmNode.getParent();
+        assertThat(moduleYpmNode.getName(), is(moduleName2));
+        DefaultYpmNode xYpmNode = (DefaultYpmNode) moduleYpmNode.getFirstChild();
+        assertThat(xYpmNode.getName(), is(xNodeName));
+        assertThat(xYpmNode.getMetaData(), is(metaData));
+        // Check x1 node
+        currYpmNode = (DefaultYpmNode) xYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(x1NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        // Check x2 node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getName(), is(x2NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+
+        // Check y node leaf's y1 and y2
+        DefaultYpmNode yYpmNode = xYpmNode.getNextSibling();
+        assertThat(yYpmNode.getName(), is(yNodeName));
+        assertThat(yYpmNode.getMetaData(), is(metaData));
+        // Check y1 node
+        currYpmNode = (DefaultYpmNode) yYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(y1NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        // Check y2 node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getName(), is(y2NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+
+        // Check z node leaf's z1 and z2
+        DefaultYpmNode zYpmNode = yYpmNode.getNextSibling();
+        assertThat(zYpmNode.getName(), is(zNodeName));
+        assertThat(zYpmNode.getMetaData(), is(metaData));
+        // Check z1 node
+        currYpmNode = (DefaultYpmNode) zYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(z1NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        // Check z2 node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getName(), is(z2NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+    }
+
+    /**
+     *  Checks the protocol data added in YpmManger, but tests only part of module1 tree.
+     */
+    @Test
+    public void retrieveAndCheckProtocolDataChosenFromPartOfModule1Tree() throws CloneNotSupportedException {
+        YangSchemaNodeIdentifier tmpNodeIdentifier;
+        YdtNodeAdapter rootNode = createModule2Tree();
+
+        // Sets the tree
+        YpmManager ypmManager = new YpmManager();
+        Object metaData = 10;
+        ypmManager.setProtocolData(rootNode, metaData);
+
+        // Create new ydt tree part of module1 tree
+        YdtNodeAdapter rootNewYdtNode = new YdtNodeAdapter();
+        // Create module node with moduleName1
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(logicalName);
+        rootNewYdtNode.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter moduleNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(moduleName1);
+        moduleNode.setNodeIdentifier(tmpNodeIdentifier);
+        moduleNode.setParent(rootNewYdtNode);
+        rootNewYdtNode.addChild(moduleNode); // child to logical node
+        YdtNodeAdapter yNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(yNodeName);
+        yNode.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter zNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(zNodeName);
+        zNode.setNodeIdentifier(tmpNodeIdentifier);
+        moduleNode.addChild(yNode); // child to module node
+        yNode.addSibling(zNode);
+        YdtNodeAdapter y1Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(y1NodeName);
+        y1Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter y2Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(y2NodeName);
+        y2Node.setNodeIdentifier(tmpNodeIdentifier);
+        yNode.addChild(y1Node);
+        y1Node.addSibling(y2Node);
+
+        // Again sets the protocol data
+        metaData = 20;
+        ypmManager.setProtocolData(rootNewYdtNode, metaData);
+
+        // Retrieve protocol data and check the contents
+        YpmContext ypmContext = ypmManager.getProtocolData(rootNewYdtNode);
+        DefaultYpmNode rootYpmNode = (DefaultYpmNode) ypmContext;
+        assertThat(rootYpmNode.getName(), is(logicalName));
+        DefaultYpmNode currYpmNode = (DefaultYpmNode) rootYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(moduleName1));
+        // Check y and z node
+        currYpmNode = (DefaultYpmNode) currYpmNode.getFirstChild();
+        DefaultYpmNode yYpmNode = currYpmNode;
+        assertThat(currYpmNode.getName(), is(yNodeName));  // x node
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), notNullValue()); // z node
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getName(), is(zNodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), nullValue());  // no sibling
+        // Check y1 and y2 node
+        currYpmNode = (DefaultYpmNode) yYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(y1NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), notNullValue()); // y2 should exists
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getName(), is(y2NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), nullValue());
+    }
+
+    /**
+     *  Checks the protocol data added in YpmManger, but tests part of module1 tree with little bit extended tree.
+     */
+    @Test
+    public void retrieveAndCheckProtocolDataChosenFromPartOfModule1TreeWithExtended()
+            throws CloneNotSupportedException {
+        YangSchemaNodeIdentifier tmpNodeIdentifier;
+        YdtNodeAdapter rootNode = createModule2Tree();
+
+        // Sets the tree
+        YpmManager ypmManager = new YpmManager();
+        Object metaData = 10;
+        ypmManager.setProtocolData(rootNode, metaData);
+
+        // Create new ydt tree part of module1 tree
+        YdtNodeAdapter rootNewYdtNode = new YdtNodeAdapter();
+        // Create module node with moduleName1
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(logicalName);
+        rootNewYdtNode.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter moduleNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(moduleName1);
+        moduleNode.setNodeIdentifier(tmpNodeIdentifier);
+        moduleNode.setParent(rootNewYdtNode);
+        rootNewYdtNode.addChild(moduleNode); // child to logical node
+        YdtNodeAdapter yNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(yNodeName);
+        yNode.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter zNode = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(zNodeName);
+        zNode.setNodeIdentifier(tmpNodeIdentifier);
+        moduleNode.addChild(yNode); // child to module node
+        yNode.addSibling(zNode);
+        YdtNodeAdapter y1Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(y1NodeName);
+        y1Node.setNodeIdentifier(tmpNodeIdentifier);
+        YdtNodeAdapter y2Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(y2NodeName);
+        y2Node.setNodeIdentifier(tmpNodeIdentifier);
+        yNode.addChild(y1Node);
+        y1Node.addSibling(y2Node);
+        YdtNodeAdapter y11Node = new YdtNodeAdapter();
+        // Add new y11 node
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(y11NodeName);
+        y11Node.setNodeIdentifier(tmpNodeIdentifier);
+        y1Node.addChild(y11Node);
+        // Add new y3 node
+        YdtNodeAdapter z3Node = new YdtNodeAdapter();
+        tmpNodeIdentifier = new YangSchemaNodeIdentifier();
+        tmpNodeIdentifier.setName(z3NodeName);
+        z3Node.setNodeIdentifier(tmpNodeIdentifier);
+        zNode.addChild(z3Node);
+
+        // Again sets the protocol data
+        metaData = 20;
+        ypmManager.setProtocolData(rootNewYdtNode, metaData);
+
+        // Retrieve protocol data and check the contents
+        YpmContext ypmContext = ypmManager.getProtocolData(rootNewYdtNode);
+        DefaultYpmNode rootYpmNode = (DefaultYpmNode) ypmContext;
+        assertThat(rootYpmNode.getName(), is(logicalName));
+        DefaultYpmNode currYpmNode = (DefaultYpmNode) rootYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(moduleName1));
+        // Check y and z node
+        currYpmNode = (DefaultYpmNode) currYpmNode.getFirstChild();
+        DefaultYpmNode yYpmNode = currYpmNode;
+        assertThat(currYpmNode.getName(), is(yNodeName));  // y node
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), notNullValue()); // z node
+        currYpmNode = currYpmNode.getNextSibling();
+        DefaultYpmNode zYpmNode = currYpmNode;
+        assertThat(currYpmNode.getName(), is(zNodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), nullValue());  // no sibling
+        // Check y1 and y2 node
+        currYpmNode = (DefaultYpmNode) yYpmNode.getFirstChild();
+        DefaultYpmNode y1YpmNode = currYpmNode;
+        assertThat(currYpmNode.getName(), is(y1NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), notNullValue()); // y2 should exists
+        currYpmNode = currYpmNode.getNextSibling();
+        assertThat(currYpmNode.getName(), is(y2NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), nullValue());
+        // Check new y11 node
+        currYpmNode = (DefaultYpmNode) y1YpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(y11NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), nullValue());
+        assertThat(currYpmNode.getFirstChild(), nullValue());
+        // Check new z3 node
+        currYpmNode = (DefaultYpmNode) zYpmNode.getFirstChild();
+        assertThat(currYpmNode.getName(), is(z3NodeName));
+        assertThat(currYpmNode.getMetaData(), is(metaData));
+        assertThat(currYpmNode.getNextSibling(), nullValue());
+        assertThat(currYpmNode.getFirstChild(), nullValue());
+    }
+}