submodule level data handling

Change-Id: I1afbaf89acad913dfd96a0f2caf324db6613c75a
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/SerializerHelper.java b/runtime/src/main/java/org/onosproject/yang/runtime/SerializerHelper.java
index ee3298a..e52cf6d 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/SerializerHelper.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/SerializerHelper.java
@@ -446,6 +446,9 @@
 
         SchemaId id = new SchemaId(name, namespace);
         child = ((SingleInstanceNodeContext) context).getChildContext(id);
+        if (child == null) {
+            throw new IllegalArgumentException(errorMsg(FMT_NOT_EXIST, name));
+        }
         return child;
     }
 
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java
index a16d7ff..7eeee89 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java
@@ -18,9 +18,12 @@
 
 import org.onosproject.yang.compiler.datamodel.SchemaDataNode;
 import org.onosproject.yang.compiler.datamodel.YangChoice;
+import org.onosproject.yang.compiler.datamodel.YangInclude;
+import org.onosproject.yang.compiler.datamodel.YangModule;
 import org.onosproject.yang.compiler.datamodel.YangNode;
 import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
 import org.onosproject.yang.compiler.datamodel.YangSchemaNodeIdentifier;
+import org.onosproject.yang.compiler.datamodel.YangSubModule;
 import org.onosproject.yang.compiler.datamodel.exceptions.DataModelException;
 import org.onosproject.yang.model.DataNode;
 import org.onosproject.yang.model.SchemaContext;
@@ -60,6 +63,7 @@
 
     private static final String AT = "@";
     private final Logger log = getLogger(getClass());
+    private static final String E_NEXIST = "node with {} namespace not found.";
     /*
      * Map for storing YANG schema nodes. Key will be the schema name of
      * module node defined in YANG file.
@@ -252,7 +256,7 @@
 
         YangSchemaNode node = nameSpaceSchemaStore.get(nameSpace);
         if (node == null && !isForChildContext) {
-            log.error("node with {} namespace not found.", nameSpace);
+            log.error(E_NEXIST, nameSpace);
         }
         return node;
     }
@@ -295,9 +299,18 @@
 
         qNameKeyStore.put(getInterfaceClassName(appNode).toLowerCase(), appNode);
 
-        //update namespaceSchema store.
-        nameSpaceSchemaStore.put(appNode.getNameSpace().getModuleNamespace(),
-                                 appNode);
+        /*
+         * The name of a module determines the namespace of all data node names
+         * defined in that module.  If a data node is defined in a submodule,
+         * then the namespace-qualified member name uses the name of the main
+         * module to which the submodule belongs.
+         * So skipping the submodule entry in namespace map.
+         */
+        if (!(appNode instanceof YangSubModule)) {
+            //update namespaceSchema store.
+            nameSpaceSchemaStore.put(appNode.getNameSpace().getModuleNamespace(),
+                                     appNode);
+        }
 
         log.info("successfully registered this application {}", name);
     }
@@ -405,6 +418,42 @@
         return new SchemaId("/", null);
     }
 
+    @Override
+    public SchemaContext getChildContext(SchemaId schemaId) {
+
+        checkNotNull(schemaId);
+        String ns = schemaId.namespace();
+        if (ns == null) {
+            log.error("namespace should not be null for a node");
+        }
+        YangSchemaNode schemaNode = null;
+
+        YangSchemaNode node = getForNameSpace(ns, true);
+        if (node == null) {
+            //If namespace is module name.
+            node = getForSchemaName(ns);
+        }
+        YangSchemaNodeIdentifier id = getNodeIdFromSchemaId(schemaId, ns);
+
+        if (node != null) {
+            try {
+                schemaNode = node.getChildSchema(id).getSchemaNode();
+            } catch (DataModelException e) {
+                // if exception occurs check for submodule
+            }
+            if (schemaNode == null) {
+                List<YangInclude> includeList = ((YangModule) node)
+                        .getIncludeList();
+                // Checking requested node in submodule.
+                schemaNode = getSubModlueChildNode(id, includeList);
+            }
+            return schemaNode;
+        } else {
+            log.error(E_NEXIST, ns);
+        }
+        return null;
+    }
+
     /**
      * Updates child's context. It sets itself as a parent context for first
      * level child's in module/sub-module.
@@ -468,32 +517,33 @@
         updateContextForChoiceCase(child);
     }
 
-    @Override
-    public SchemaContext getChildContext(SchemaId schemaId) {
-
-        checkNotNull(schemaId);
-        if (schemaId.namespace() == null) {
-            log.error("node with {} namespace not found.", schemaId.namespace());
-        }
-
-        String namespace = schemaId.namespace();
-        YangSchemaNode node = getForNameSpace(namespace, true);
-        if (node == null) {
-            //If namespace if module name.
-            node = getForSchemaName(schemaId.namespace());
-        }
-        YangSchemaNodeIdentifier id = getNodeIdFromSchemaId(schemaId, namespace);
-
-        try {
-            if (node != null) {
-                return node.getChildSchema(id).getSchemaNode();
-            } else {
-                log.error("node with {} namespace not found.", schemaId
-                        .namespace());
+    /**
+     * Returns the child schema for given node id from the list of included
+     * submodule.
+     * <p>
+     * To reference an item that is defined in one of its
+     * submodules, the module MUST include the submodule and if
+     * a submodule that needs to reference an item defined in another
+     * submodule of the same module, MUST include this submodule.
+     * <p>
+     * In other words if submodule is including any submodule which
+     * belongs to same module then module should also include that
+     * submodule.
+     *
+     * @param id   child node identifier
+     * @param list list of included submodule
+     */
+    private YangSchemaNode getSubModlueChildNode(YangSchemaNodeIdentifier id,
+                                                 List<YangInclude> list) {
+        YangSchemaNode schemaNode = null;
+        for (YangInclude l : list) {
+            try {
+                schemaNode = l.getIncludedNode().getChildSchema(id)
+                        .getSchemaNode();
+            } catch (DataModelException e) {
+                log.error("failed to get child schema", e);
             }
-        } catch (DataModelException e) {
-            log.error("failed to get child schema", e);
         }
-        return null;
+        return schemaNode;
     }
 }
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/serializerhelper/AddToDataNodeList1SubModuleTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/serializerhelper/AddToDataNodeList1SubModuleTest.java
new file mode 100644
index 0000000..a452078
--- /dev/null
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/serializerhelper/AddToDataNodeList1SubModuleTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2017-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.yang.runtime.impl.serializerhelper;
+
+import org.junit.Test;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.InnerNode;
+import org.onosproject.yang.model.KeyLeaf;
+import org.onosproject.yang.model.ListKey;
+import org.onosproject.yang.model.NodeKey;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.HelperContext;
+import org.onosproject.yang.runtime.impl.TestYangSerializerContext;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+
+import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_LEAF_VALUE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_LEAF_VALUE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_NODE;
+import static org.onosproject.yang.runtime.SerializerHelper.addDataNode;
+import static org.onosproject.yang.runtime.SerializerHelper.exitDataNode;
+import static org.onosproject.yang.runtime.SerializerHelper.getResourceId;
+import static org.onosproject.yang.runtime.SerializerHelper.initializeDataNode;
+import static org.onosproject.yang.runtime.impl.TestUtils.LNS;
+import static org.onosproject.yang.runtime.impl.TestUtils.L_NAME;
+import static org.onosproject.yang.runtime.impl.TestUtils.validateDataNode;
+import static org.onosproject.yang.runtime.impl.TestUtils.validateLeafDataNode;
+import static org.onosproject.yang.runtime.impl.TestUtils.validateResourceId;
+import static org.onosproject.yang.runtime.impl.TestUtils.walkINTree;
+
+/**
+ * Tests the serializer helper methods for submodule handling.
+ */
+public class AddToDataNodeList1SubModuleTest {
+
+    TestYangSerializerContext context = new TestYangSerializerContext();
+
+    /*
+     * Reference for data node info.
+     */
+    HelperContext info;
+
+    /*
+     * Reference for data node builder.
+     */
+    DataNode.Builder dBlr;
+
+    /*
+     * Reference for resource id.
+     */
+    ResourceId id;
+
+    /*
+     * Reference for the value.
+     */
+    String value;
+
+    /*
+     * Reference for string array to used for resource id testing.
+     */
+    String[] nA;
+    String[] nsA;
+    String[] valA;
+
+    private static final String[] EXPECTED = {
+            "Entry Node is /.",
+            "Entry Node is l4.",
+            "Entry Node is k1.",
+            "Exit Node is k1.",
+            "Entry Node is c1.",
+            "Entry Node is leaf_c1.",
+            "Exit Node is leaf_c1.",
+            "Exit Node is c1.",
+            "Exit Node is l4.",
+            "Entry Node is leaf4.",
+            "Exit Node is leaf4.",
+            "Entry Node is leaf4.",
+            "Exit Node is leaf4.",
+            "Entry Node is leaf4.",
+            "Exit Node is leaf4.",
+            "Entry Node is leaf4.",
+            "Exit Node is leaf4.",
+            "Exit Node is /."
+    };
+
+    /**
+     * Test add to data node builder.
+     */
+    @Test
+    public void addToDataListTest() throws IOException {
+        ResourceId id;
+        dBlr = initializeDataNode(context);
+        dBlr = addDataNode(dBlr, "l4", L_NAME, value, null);
+        value = "1";
+        dBlr = addDataNode(dBlr, "k1", null, value, null);
+        dBlr = exitDataNode(dBlr);
+        dBlr = addDataNode(dBlr, "c1", null, null, null);
+        value = "0";
+        dBlr = addDataNode(dBlr, "leaf_c1", null, value, null);
+
+        info = (HelperContext) dBlr.appInfo();
+        id = getResourceId(dBlr);
+        dBlr = exitDataNode(dBlr);
+
+        ResourceId id1 = getResourceId(dBlr);
+        dBlr = exitDataNode(dBlr);
+
+        info = (HelperContext) dBlr.appInfo();
+        ResourceId id2 = getResourceId(dBlr);
+
+        dBlr = exitDataNode(dBlr);
+
+        // Checking leaf list
+        value = "1";
+        dBlr = addDataNode(dBlr, "leaf4", L_NAME, value, null);
+        dBlr = exitDataNode(dBlr);
+        value = "2";
+        dBlr = addDataNode(dBlr, "leaf4", L_NAME, value, null);
+        dBlr = exitDataNode(dBlr);
+        value = "3";
+        dBlr = addDataNode(dBlr, "leaf4", L_NAME, value, null);
+        dBlr = exitDataNode(dBlr);
+        value = null;
+        dBlr = addDataNode(dBlr, "leaf4", L_NAME, value, null);
+        ResourceId id3 = getResourceId(dBlr);
+        dBlr = exitDataNode(dBlr);
+
+        //Tree validation
+        nA = new String[]{"/", "l4", "k1", "c1", "leaf_c1"};
+        nsA = new String[]{null, LNS, LNS, LNS, LNS};
+        valA = new String[]{"1", "2", "3", "0"};
+        validateResourceId(nA, nsA, valA, id);
+
+        nA = new String[]{"/", "l4", "k1", "c1"};
+        nsA = new String[]{null, LNS, LNS, LNS};
+        valA = new String[]{"1", "2", "3"};
+        validateResourceId(nA, nsA, valA, id1);
+
+        nA = new String[]{"/", "l4", "k1"};
+        nsA = new String[]{null, LNS, LNS};
+        valA = new String[]{"1", "2", "3"};
+        validateResourceId(nA, nsA, valA, id2);
+
+        nA = new String[]{"/", "leaf4"};
+        nsA = new String[]{null, LNS};
+        valA = new String[]{null};
+        validateResourceId(nA, nsA, valA, id3);
+
+        // Validating the data node.
+        DataNode node = dBlr.build();
+        validateDataNode(node, "/", null, SINGLE_INSTANCE_NODE, true, null);
+
+        Map<NodeKey, DataNode> childMap = ((InnerNode) node).childNodes();
+        Iterator<Map.Entry<NodeKey, DataNode>> it = childMap.entrySet().iterator();
+        Map.Entry<NodeKey, DataNode> n = it.next();
+        validateDataNode(n.getValue(), "l4", LNS, MULTI_INSTANCE_NODE,
+                         true, null);
+
+        Iterator<KeyLeaf> keyIt = ((ListKey) n.getKey()).keyLeafs().iterator();
+
+        validateLeafDataNode(keyIt.next(), "k1", LNS, "1");
+
+        Iterator<Map.Entry<NodeKey, DataNode>> it1;
+        it1 = ((InnerNode) n.getValue()).childNodes().entrySet().iterator();
+        validateDataNode(it1.next().getValue(), "k1", LNS,
+                         SINGLE_INSTANCE_LEAF_VALUE_NODE, false, "1");
+        DataNode n1 = it1.next().getValue();
+        validateDataNode(n1, "c1", LNS,
+                         SINGLE_INSTANCE_NODE, true, null);
+
+        Iterator<Map.Entry<NodeKey, DataNode>> it2;
+        it2 = ((InnerNode) n1).childNodes().entrySet().iterator();
+        validateDataNode(it2.next().getValue(), "leaf_c1", LNS,
+                         SINGLE_INSTANCE_LEAF_VALUE_NODE, false, "0");
+        validateDataNode(it.next().getValue(), "leaf4", LNS,
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, false, "1");
+        validateDataNode(it.next().getValue(), "leaf4", LNS,
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, false, "2");
+        validateDataNode(it.next().getValue(), "leaf4", LNS,
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, false, "3");
+        validateDataNode(it.next().getValue(), "leaf4", LNS,
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, false, null);
+        walkINTree(dBlr.build(), EXPECTED);
+    }
+}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/serializerhelper/AddToDataNodeListSubModuleTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/serializerhelper/AddToDataNodeListSubModuleTest.java
new file mode 100644
index 0000000..fcd249d
--- /dev/null
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/serializerhelper/AddToDataNodeListSubModuleTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2017-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.yang.runtime.impl.serializerhelper;
+
+import org.junit.Test;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.InnerNode;
+import org.onosproject.yang.model.KeyLeaf;
+import org.onosproject.yang.model.ListKey;
+import org.onosproject.yang.model.NodeKey;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.HelperContext;
+import org.onosproject.yang.runtime.impl.TestYangSerializerContext;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+
+import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_LEAF_VALUE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_LEAF_VALUE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_NODE;
+import static org.onosproject.yang.runtime.SerializerHelper.addDataNode;
+import static org.onosproject.yang.runtime.SerializerHelper.exitDataNode;
+import static org.onosproject.yang.runtime.SerializerHelper.getResourceId;
+import static org.onosproject.yang.runtime.SerializerHelper.initializeDataNode;
+import static org.onosproject.yang.runtime.impl.TestUtils.LNS;
+import static org.onosproject.yang.runtime.impl.TestUtils.L_NAME;
+import static org.onosproject.yang.runtime.impl.TestUtils.validateDataNode;
+import static org.onosproject.yang.runtime.impl.TestUtils.validateLeafDataNode;
+import static org.onosproject.yang.runtime.impl.TestUtils.validateResourceId;
+import static org.onosproject.yang.runtime.impl.TestUtils.walkINTree;
+
+/**
+ * Tests the serializer helper methods for submodule handling.
+ */
+public class AddToDataNodeListSubModuleTest {
+
+    TestYangSerializerContext context = new TestYangSerializerContext();
+
+    /*
+     * Reference for data node info.
+     */
+    HelperContext info;
+
+    /*
+     * Reference for data node builder.
+     */
+    DataNode.Builder dBlr;
+
+    /*
+     * Reference for resource id.
+     */
+    ResourceId id;
+
+    /*
+     * Reference for the value.
+     */
+    String value;
+
+    /*
+     * Reference for string array to used for resource id testing.
+     */
+    String[] nA;
+    String[] nsA;
+    String[] valA;
+
+    private static final String[] EXPECTED = {
+            "Entry Node is /.",
+            "Entry Node is l2.",
+            "Entry Node is k1.",
+            "Exit Node is k1.",
+            "Entry Node is c1.",
+            "Entry Node is leaf_c1.",
+            "Exit Node is leaf_c1.",
+            "Exit Node is c1.",
+            "Exit Node is l2.",
+            "Entry Node is leaf2.",
+            "Exit Node is leaf2.",
+            "Entry Node is leaf2.",
+            "Exit Node is leaf2.",
+            "Entry Node is leaf2.",
+            "Exit Node is leaf2.",
+            "Entry Node is leaf2.",
+            "Exit Node is leaf2.",
+            "Exit Node is /."
+    };
+
+    /**
+     * Test add to data node builder.
+     */
+    @Test
+    public void addToDataListTest() throws IOException {
+        ResourceId id;
+        dBlr = initializeDataNode(context);
+        dBlr = addDataNode(dBlr, "l2", L_NAME, value, null);
+        value = "1";
+        dBlr = addDataNode(dBlr, "k1", null, value, null);
+        dBlr = exitDataNode(dBlr);
+        dBlr = addDataNode(dBlr, "c1", null, null, null);
+        value = "0";
+        dBlr = addDataNode(dBlr, "leaf_c1", null, value, null);
+
+        info = (HelperContext) dBlr.appInfo();
+        id = getResourceId(dBlr);
+        dBlr = exitDataNode(dBlr);
+
+        ResourceId id1 = getResourceId(dBlr);
+        dBlr = exitDataNode(dBlr);
+
+        info = (HelperContext) dBlr.appInfo();
+        ResourceId id2 = getResourceId(dBlr);
+
+        dBlr = exitDataNode(dBlr);
+
+        // Checking leaf list
+        value = "1";
+        dBlr = addDataNode(dBlr, "leaf2", L_NAME, value, null);
+        dBlr = exitDataNode(dBlr);
+        value = "2";
+        dBlr = addDataNode(dBlr, "leaf2", L_NAME, value, null);
+        dBlr = exitDataNode(dBlr);
+        value = "3";
+        dBlr = addDataNode(dBlr, "leaf2", L_NAME, value, null);
+        dBlr = exitDataNode(dBlr);
+        value = null;
+        dBlr = addDataNode(dBlr, "leaf2", L_NAME, value, null);
+        ResourceId id3 = getResourceId(dBlr);
+        dBlr = exitDataNode(dBlr);
+
+        //Tree validation
+        nA = new String[]{"/", "l2", "k1", "c1", "leaf_c1"};
+        nsA = new String[]{null, LNS, LNS, LNS, LNS};
+        valA = new String[]{"1", "2", "3", "0"};
+        validateResourceId(nA, nsA, valA, id);
+
+        nA = new String[]{"/", "l2", "k1", "c1"};
+        nsA = new String[]{null, LNS, LNS, LNS};
+        valA = new String[]{"1", "2", "3"};
+        validateResourceId(nA, nsA, valA, id1);
+
+        nA = new String[]{"/", "l2", "k1"};
+        nsA = new String[]{null, LNS, LNS};
+        valA = new String[]{"1", "2", "3"};
+        validateResourceId(nA, nsA, valA, id2);
+
+        nA = new String[]{"/", "leaf2"};
+        nsA = new String[]{null, LNS};
+        valA = new String[]{null};
+        validateResourceId(nA, nsA, valA, id3);
+
+        // Validating the data node.
+        DataNode node = dBlr.build();
+        validateDataNode(node, "/", null, SINGLE_INSTANCE_NODE, true, null);
+
+        Map<NodeKey, DataNode> childMap = ((InnerNode) node).childNodes();
+        Iterator<Map.Entry<NodeKey, DataNode>> it = childMap.entrySet().iterator();
+        Map.Entry<NodeKey, DataNode> n = it.next();
+        validateDataNode(n.getValue(), "l2", LNS, MULTI_INSTANCE_NODE,
+                         true, null);
+
+        Iterator<KeyLeaf> keyIt = ((ListKey) n.getKey()).keyLeafs().iterator();
+
+        validateLeafDataNode(keyIt.next(), "k1", LNS, "1");
+
+        Iterator<Map.Entry<NodeKey, DataNode>> it1;
+        it1 = ((InnerNode) n.getValue()).childNodes().entrySet().iterator();
+        validateDataNode(it1.next().getValue(), "k1", LNS,
+                         SINGLE_INSTANCE_LEAF_VALUE_NODE, false, "1");
+        DataNode n1 = it1.next().getValue();
+        validateDataNode(n1, "c1", LNS,
+                         SINGLE_INSTANCE_NODE, true, null);
+
+        Iterator<Map.Entry<NodeKey, DataNode>> it2;
+        it2 = ((InnerNode) n1).childNodes().entrySet().iterator();
+        validateDataNode(it2.next().getValue(), "leaf_c1", LNS,
+                         SINGLE_INSTANCE_LEAF_VALUE_NODE, false, "0");
+        validateDataNode(it.next().getValue(), "leaf2", LNS,
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, false, "1");
+        validateDataNode(it.next().getValue(), "leaf2", LNS,
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, false, "2");
+        validateDataNode(it.next().getValue(), "leaf2", LNS,
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, false, "3");
+        validateDataNode(it.next().getValue(), "leaf2", LNS,
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, false, null);
+        walkINTree(dBlr.build(), EXPECTED);
+    }
+}
diff --git a/runtime/src/test/resources/schemaProviderTestYangFiles/list.yang b/runtime/src/test/resources/schemaProviderTestYangFiles/list.yang
index 2ff07dc..c0a1b69 100644
--- a/runtime/src/test/resources/schemaProviderTestYangFiles/list.yang
+++ b/runtime/src/test/resources/schemaProviderTestYangFiles/list.yang
@@ -5,6 +5,9 @@
     namespace "yrt:list";
 
     prefix "l";
+    include list2;
+    include list3;
+    include list4;
 
     organization "ON-LAB";
 
diff --git a/runtime/src/test/resources/schemaProviderTestYangFiles/suBlist.yang b/runtime/src/test/resources/schemaProviderTestYangFiles/suBlist.yang
new file mode 100644
index 0000000..5f31db7
--- /dev/null
+++ b/runtime/src/test/resources/schemaProviderTestYangFiles/suBlist.yang
@@ -0,0 +1,32 @@
+submodule list2 {
+
+    yang-version 1;
+    belongs-to "list"{
+        prefix l1;
+    }
+    include list3;
+    organization "ON-LAB";
+
+    description "This module defines for list.";
+
+    revision "2016-06-24" {
+        description "Initial revision.";
+    }
+
+    list l2 {
+        key "k1";
+            leaf k1 {
+               type string;
+            }
+
+            container c1 {
+                leaf leaf_c1 {
+                  type string;
+                }
+            }
+    }
+
+    leaf-list leaf2 {
+        type string;
+    }
+}
\ No newline at end of file
diff --git a/runtime/src/test/resources/schemaProviderTestYangFiles/suBlist1.yang b/runtime/src/test/resources/schemaProviderTestYangFiles/suBlist1.yang
new file mode 100644
index 0000000..2a9a99d
--- /dev/null
+++ b/runtime/src/test/resources/schemaProviderTestYangFiles/suBlist1.yang
@@ -0,0 +1,18 @@
+submodule list3 {
+
+    yang-version 1;
+    belongs-to "list"{
+        prefix l;
+    }
+    include list4;
+    organization "ON-LAB";
+
+    description "This module defines for list.";
+
+    revision "2016-06-24" {
+        description "Initial revision.";
+    }
+    leaf-list leaf3 {
+        type string;
+    }
+}
\ No newline at end of file
diff --git a/runtime/src/test/resources/schemaProviderTestYangFiles/suBlist2.yang b/runtime/src/test/resources/schemaProviderTestYangFiles/suBlist2.yang
new file mode 100644
index 0000000..12674f2
--- /dev/null
+++ b/runtime/src/test/resources/schemaProviderTestYangFiles/suBlist2.yang
@@ -0,0 +1,30 @@
+submodule list4 {
+
+    yang-version 1;
+    belongs-to "list"{
+        prefix l;
+    }
+    organization "ON-LAB";
+
+    description "This module defines for list.";
+
+    revision "2016-06-24" {
+        description "Initial revision.";
+    }
+
+    list l4 {
+        key "k1";
+            leaf k1 {
+               type string;
+            }
+
+            container c1 {
+                leaf leaf_c1 {
+                  type string;
+                }
+            }
+    }
+    leaf-list leaf4 {
+        type string;
+    }
+}
\ No newline at end of file