[ONOS-4350] Inter file linking implementation and inter-jar linking framework

Change-Id: I71a26ba3e0b9d17261e78a9313fe7f047195932e
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/ResolutionType.java b/src/main/java/org/onosproject/yangutils/datamodel/ResolutionType.java
deleted file mode 100644
index e69492a..0000000
--- a/src/main/java/org/onosproject/yangutils/datamodel/ResolutionType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.yangutils.datamodel;
-
-/**
- * Represents ENUM to identify the YANG resolution type.
- */
-public enum ResolutionType {
-    /**
-     * Identifies that resolution is for typedef.
-     */
-    TYPEDEF_RESOLUTION,
-
-    /**
-     * Identifies that resolution is for grouping.
-     */
-    GROUPING_RESOLUTION
-}
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java b/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java
deleted file mode 100644
index e05f4a9..0000000
--- a/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.yangutils.datamodel;
-
-import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
-
-/**
- * Abstraction of YANG resolvable information. Abstracted to obtain the
- * information required for linking resolution.
- */
-public interface Resolvable {
-
-    /**
-     * Returns the status of resolution. If completely resolved returns enum
-     * value "RESOLVED", if not returns "UNRESOLVED", in case reference of
-     * grouping/typedef is added to uses/type but it's not resolved
-     * "INTRA_FILE_RESOLVED" is returned.
-     *
-     * @return status of resolution
-     */
-    ResolvableStatus getResolvableStatus();
-
-    /**
-     * Set the status of type/uses resolution. If completely resolved set enum
-     * value "RESOLVED", if not set it to "UNRESOLVED", in case reference of
-     * grouping/typedef is added to uses/type but it's not resolved
-     * "INTRA_FILE_RESOLVED" should be set.
-     *
-     * @param resolvableStatus status of resolution
-     */
-    void setResolvableStatus(ResolvableStatus resolvableStatus);
-
-    /**
-     * Resolves the linking.
-     *
-     * @throws DataModelException data model error
-     */
-    void resolve()
-            throws DataModelException;
-}
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/ResolvableStatus.java b/src/main/java/org/onosproject/yangutils/datamodel/ResolvableStatus.java
deleted file mode 100644
index d1cacb4..0000000
--- a/src/main/java/org/onosproject/yangutils/datamodel/ResolvableStatus.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.yangutils.datamodel;
-
-/**
- * Represents the status of resolvable entity.
- */
-public enum ResolvableStatus {
-
-    /**
-     * Identifies that resolvable entity is unresolved.
-     */
-    UNRESOLVED,
-
-    /**
-     * Identifies that resolvable entity's reference is linked.
-     */
-    LINKED,
-
-    /**
-     * Identifies that resolvable entity is IntraFile resolved (i.e. complete
-     * linking with in the intra file).
-     */
-    INTRA_FILE_RESOLVED,
-
-    /**
-     * Identifies that resolvable entity is resolved.
-     */
-    RESOLVED
-
-}
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangBelongsTo.java b/src/main/java/org/onosproject/yangutils/datamodel/YangBelongsTo.java
index 417e07e..694df32 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangBelongsTo.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangBelongsTo.java
@@ -15,10 +15,14 @@
  */
 package org.onosproject.yangutils.datamodel;
 
+import java.util.Set;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.parser.Parsable;
+import org.onosproject.yangutils.plugin.manager.YangFileInfo;
 import org.onosproject.yangutils.utils.YangConstructType;
 
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.findReferredNode;
+
 /*-
  *   Reference 6020.
  *
@@ -46,7 +50,7 @@
 /**
  * Represents the belongs-to data type information.
  */
-public class YangBelongsTo implements Parsable {
+public class YangBelongsTo implements Parsable, LocationInfo {
 
     /**
      * Reference RFC 6020.
@@ -70,6 +74,12 @@
      */
     private String prefix;
 
+    // Error Line number.
+    private int lineNumber;
+
+    // Error character position.
+    private int charPosition;
+
     /**
      * Create a belongs to object.
      */
@@ -90,7 +100,6 @@
      * Sets the belongs to module name.
      *
      * @param belongsToModuleName the belongs to module name to set
-     *
      */
     public void setBelongsToModuleName(String belongsToModuleName) {
         this.belongsToModuleName = belongsToModuleName;
@@ -161,4 +170,47 @@
     public void validateDataOnExit() throws DataModelException {
         // TODO auto-generated method stub, to be implemented by parser
     }
+
+    @Override
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    @Override
+    public int getCharPosition() {
+        return charPosition;
+    }
+
+    @Override
+    public void setLineNumber(int lineNumber) {
+        this.lineNumber = lineNumber;
+    }
+
+    @Override
+    public void setCharPosition(int charPositionInLine) {
+        this.charPosition = charPositionInLine;
+    }
+
+    /**
+     * Links the belongs to with a module.
+     *
+     * @param yangFileInfoSet YANG file information set
+     * @throws DataModelException a violation in data model rule
+     */
+    public void linkWithModule(Set<YangFileInfo> yangFileInfoSet)
+            throws DataModelException {
+        String belongsToModuleName = getBelongsToModuleName();
+        YangNode moduleNode = findReferredNode(yangFileInfoSet, belongsToModuleName);
+        if (moduleNode != null) {
+            if (moduleNode instanceof YangModule) {
+                setModuleNode(moduleNode);
+                return;
+            }
+        }
+        DataModelException exception = new DataModelException("YANG file error : Module " + belongsToModuleName +
+                "to which sub-module belongs to is not found.");
+        exception.setLine(getLineNumber());
+        exception.setCharPosition(getCharPosition());
+        throw exception;
+    }
 }
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java b/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java
index 8c94d7d..e1d0e68 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java
@@ -17,10 +17,10 @@
 package org.onosproject.yangutils.datamodel;
 
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.linker.impl.ResolvableStatus;
 import com.google.common.base.Strings;
 
-import static org.onosproject.yangutils.datamodel.ResolvableStatus.INTRA_FILE_RESOLVED;
-import static org.onosproject.yangutils.datamodel.ResolvableStatus.RESOLVED;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.BINARY;
 import static org.onosproject.yangutils.datamodel.YangDataTypes.BITS;
 import static org.onosproject.yangutils.datamodel.YangDataTypes.BOOLEAN;
 import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
@@ -30,6 +30,8 @@
 import static org.onosproject.yangutils.datamodel.YangDataTypes.LEAFREF;
 import static org.onosproject.yangutils.datamodel.YangDataTypes.STRING;
 import static org.onosproject.yangutils.datamodel.YangDataTypes.UNION;
+import static org.onosproject.yangutils.linker.impl.ResolvableStatus.INTRA_FILE_RESOLVED;
+import static org.onosproject.yangutils.linker.impl.ResolvableStatus.RESOLVED;
 import static org.onosproject.yangutils.utils.RestrictionResolver.isOfRangeRestrictedType;
 import static org.onosproject.yangutils.utils.RestrictionResolver.processLengthRestriction;
 import static org.onosproject.yangutils.utils.RestrictionResolver.processRangeRestriction;
@@ -236,7 +238,7 @@
              * Check whether the referred typedef is resolved.
              */
             if (baseType.getResolvableStatus() != INTRA_FILE_RESOLVED && baseType.getResolvableStatus() != RESOLVED) {
-                throw new DataModelException("Linker Error: Referred typedef is not resolved.");
+                throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
             }
 
             /*
@@ -301,6 +303,28 @@
                      */
                     return RESOLVED;
                 }
+            } else if (getEffectiveBuiltInType() == BINARY) {
+                if (refDerivedInfo.getResolvedExtendedInfo() == null) {
+                    resolveLengthRestriction(null);
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve length restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                } else {
+                    if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangRangeRestriction)) {
+                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
+                                "type.");
+                    }
+                    resolveLengthRestriction((YangRangeRestriction) refDerivedInfo.getResolvedExtendedInfo());
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve length restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                }
             }
         } else {
             setEffectiveBuiltInType((baseType.getDataType()));
@@ -356,6 +380,28 @@
                      */
                     return RESOLVED;
                 }
+            } else if (getEffectiveBuiltInType() == BINARY) {
+                if (baseType.getDataTypeExtendedInfo() == null) {
+                    resolveLengthRestriction(null);
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve length restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                } else {
+                    if (!(baseType.getDataTypeExtendedInfo() instanceof YangRangeRestriction)) {
+                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
+                                "type.");
+                    }
+                    resolveLengthRestriction((YangRangeRestriction) baseType.getDataTypeExtendedInfo());
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve length restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                }
             }
         }
 
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangEntityToResolveInfo.java b/src/main/java/org/onosproject/yangutils/datamodel/YangEntityToResolveInfo.java
deleted file mode 100644
index 229625c..0000000
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangEntityToResolveInfo.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.yangutils.datamodel;
-
-import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
-
-/**
- * Represents information about entity being resolved.
- *
- * @param <T> type of entity being resolved, uses / grouping
- */
-public class YangEntityToResolveInfo<T> {
-
-    // Parsable node for which resolution is to be performed.
-    private T entityToResolve;
-
-    // Holder of the YANG construct for which resolution has to be carried out.
-    private YangNode holderOfEntityToResolve;
-
-    /**
-     * Retrieves the entity to be resolved.
-     *
-     * @return entity to be resolved
-     */
-    public T getEntityToResolve() {
-        return entityToResolve;
-    }
-
-    /**
-     * Sets entity to be resolved.
-     *
-     * @param entityToResolve entity to be resolved
-     */
-    public void setEntityToResolve(T entityToResolve) {
-        this.entityToResolve = entityToResolve;
-    }
-
-    /**
-     * Retrieves the parent node which contains the entity to be resolved.
-     *
-     * @return parent node which contains the entity to be resolved
-     */
-    public YangNode getHolderOfEntityToResolve() {
-        return holderOfEntityToResolve;
-    }
-
-    /**
-     * Sets parent node which contains the entity to be resolved.
-     *
-     * @param holderOfEntityToResolve parent node which contains the entity to
-     * be resolved
-     */
-    public void setHolderOfEntityToResolve(YangNode holderOfEntityToResolve) {
-        this.holderOfEntityToResolve = holderOfEntityToResolve;
-    }
-
-    /**
-     * Retrieves the prefix of the entity.
-     *
-     * @return entities prefix
-     * @throws DataModelException data model error
-     */
-    public String getEntityPrefix()
-            throws DataModelException {
-        if (getEntityToResolve() == null) {
-            return null;
-        }
-
-        String prefix;
-        T entityToBeResolved = getEntityToResolve();
-        if (entityToBeResolved instanceof YangType) {
-            prefix = ((YangType<?>) entityToBeResolved).getPrefix();
-        } else if (entityToBeResolved instanceof YangUses) {
-            prefix = ((YangUses) entityToBeResolved).getPrefix();
-        } else {
-            throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
-        }
-        return prefix;
-    }
-}
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangImport.java b/src/main/java/org/onosproject/yangutils/datamodel/YangImport.java
index 4ab3f2a..ef5d25a 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangImport.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangImport.java
@@ -15,10 +15,14 @@
  */
 package org.onosproject.yangutils.datamodel;
 
+import java.util.Set;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.parser.Parsable;
+import org.onosproject.yangutils.plugin.manager.YangFileInfo;
 import org.onosproject.yangutils.utils.YangConstructType;
 
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.findReferredNode;
+
 /*
  *  Reference:RFC 6020.
  *  The "import" statement makes definitions from one module available
@@ -64,7 +68,7 @@
  * Represents the information about the imported modules.
  */
 public class YangImport
-        implements Parsable {
+        implements Parsable, LocationInfo {
 
     /**
      * Name of the module that is being imported.
@@ -78,7 +82,7 @@
 
     /**
      * Reference:RFC 6020.
-     *
+     * <p>
      * The import's "revision-date" statement is used to specify the exact
      * version of the module to import. The "revision-date" statement MUST match
      * the most recent "revision" statement in the imported module. organization
@@ -87,10 +91,20 @@
     private String revision;
 
     /**
+     * Reference to node which is imported.
+     */
+    private YangNode importedNode;
+
+    // Error Line number.
+    private int lineNumber;
+
+    // Error character position.
+    private int charPosition;
+
+    /**
      * Creates a YANG import.
      */
     public YangImport() {
-
     }
 
     /**
@@ -181,4 +195,91 @@
         // TODO auto-generated method stub, to be implemented by parser
 
     }
+
+    /**
+     * Returns imported node.
+     *
+     * @return imported node
+     */
+    public YangNode getImportedNode() {
+        return importedNode;
+    }
+
+    /**
+     * Sets imported node.
+     *
+     * @param importedNode imported node
+     */
+    public void setImportedNode(YangNode importedNode) {
+        this.importedNode = importedNode;
+    }
+
+    @Override
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    @Override
+    public int getCharPosition() {
+        return charPosition;
+    }
+
+    @Override
+    public void setLineNumber(int lineNumber) {
+        this.lineNumber = lineNumber;
+    }
+
+    @Override
+    public void setCharPosition(int charPositionInLine) {
+        this.charPosition = charPositionInLine;
+    }
+
+    /**
+     * Adds reference to an import.
+     *
+     * @param yangFileInfoSet YANG file info set
+     * @throws DataModelException a violation of data model rules
+     */
+    public void addReferenceToImport(Set<YangFileInfo> yangFileInfoSet) throws DataModelException {
+        String importedModuleName = getModuleName();
+        String importedModuleRevision = getRevision();
+        YangNode moduleNode = null;
+        /*
+         * Find the imported module node for a given module name
+         * with a specified revision if revision is not null.
+         */
+        if (importedModuleRevision != null) {
+            String importedModuleNameWithRevision = importedModuleName + "@" + importedModuleRevision;
+            moduleNode = findReferredNode(yangFileInfoSet, importedModuleNameWithRevision);
+        }
+
+        /*
+         * Find the imported module node for a given module name
+         * without revision if can't find with revision.
+         */
+        if (moduleNode == null) {
+            moduleNode = findReferredNode(yangFileInfoSet, importedModuleName);
+        }
+
+        if (moduleNode != null) {
+            if (moduleNode instanceof YangModule) {
+                if (getRevision() == null || getRevision().isEmpty()) {
+                    setImportedNode(moduleNode);
+                    return;
+                }
+                // Match revision if import is with revision.
+                if (((YangModule) moduleNode).getRevision().getRevDate().equals(importedModuleRevision)) {
+                    setImportedNode(moduleNode);
+                    return;
+                }
+            }
+        }
+
+        // Exception if there is no match.
+        DataModelException exception = new DataModelException("YANG file error : Imported module "
+                + importedModuleName + " with revision " + importedModuleRevision + " is not found.");
+        exception.setLine(getLineNumber());
+        exception.setCharPosition(getCharPosition());
+        throw exception;
+    }
 }
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangInclude.java b/src/main/java/org/onosproject/yangutils/datamodel/YangInclude.java
index 4892613..d331a72 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangInclude.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangInclude.java
@@ -15,10 +15,14 @@
  */
 package org.onosproject.yangutils.datamodel;
 
+import java.util.Set;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.parser.Parsable;
+import org.onosproject.yangutils.plugin.manager.YangFileInfo;
 import org.onosproject.yangutils.utils.YangConstructType;
 
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.findReferredNode;
+
 /*
  * Reference:RFC 6020.
  * The "include" statement is used to make content from a submodule
@@ -38,7 +42,7 @@
  * Represents the information about the included sub-modules.
  */
 public class YangInclude
-        implements Parsable {
+        implements Parsable, LocationInfo {
 
     /**
      * Name of the sub-module that is being included.
@@ -52,6 +56,17 @@
     private String revision;
 
     /**
+     * Reference to node which is included.
+     */
+    private YangNode includedNode;
+
+    // Error Line number.
+    private int lineNumber;
+
+    // Error character position.
+    private int charPosition;
+
+    /**
      * Creates a YANG include.
      */
     public YangInclude() {
@@ -127,4 +142,98 @@
 
     }
 
+    public YangNode getIncludedNode() {
+        return includedNode;
+    }
+
+    public void setIncludedNode(YangNode includedNode) {
+        this.includedNode = includedNode;
+    }
+
+    @Override
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    @Override
+    public int getCharPosition() {
+        return charPosition;
+    }
+
+    @Override
+    public void setLineNumber(int lineNumber) {
+        this.lineNumber = lineNumber;
+    }
+
+    @Override
+    public void setCharPosition(int charPositionInLine) {
+        this.charPosition = charPositionInLine;
+    }
+
+    /**
+     * Adds reference to an include.
+     *
+     * @param yangFileInfoSet YANG file info set
+     * @return YANG sub module node
+     * @throws DataModelException a violation of data model rules
+     */
+    public YangSubModule addReferenceToInclude(Set<YangFileInfo> yangFileInfoSet) throws DataModelException {
+        String includedSubModuleName = getSubModuleName();
+        String includedSubModuleRevision = getRevision();
+        YangNode subModuleNode = null;
+
+        /*
+         * Find the included sub-module node for a given module name
+         * with a specified revision if revision is not null.
+         */
+        if (includedSubModuleRevision != null) {
+            String includedSubModuleNameWithRevision = includedSubModuleName + "@" + includedSubModuleRevision;
+            subModuleNode = findReferredNode(yangFileInfoSet, includedSubModuleNameWithRevision);
+        }
+
+        /*
+         * Find the imported sub module node for a given module name
+         * without revision if can't find with revision.
+         */
+        if (subModuleNode == null) {
+            subModuleNode = findReferredNode(yangFileInfoSet, includedSubModuleName);
+        }
+
+        if (subModuleNode != null) {
+            if (subModuleNode instanceof YangSubModule) {
+                if (getRevision() == null || getRevision().isEmpty()) {
+                    setIncludedNode(subModuleNode);
+                    return (YangSubModule) subModuleNode;
+                }
+                // Match revision if inclusion is with revision.
+                if (((YangSubModule) subModuleNode).getRevision().getRevDate().equals(includedSubModuleRevision)) {
+                    setIncludedNode(subModuleNode);
+                    return (YangSubModule) subModuleNode;
+                }
+            }
+        }
+        // Exception if there is no match.
+        DataModelException exception = new DataModelException("YANG file error : Included sub module " +
+                includedSubModuleName + "with a given revision is not found.");
+        exception.setLine(getLineNumber());
+        exception.setCharPosition(getCharPosition());
+        throw exception;
+    }
+
+    /**
+     * Reports an error when included sub-module doesn't meet condition that
+     * "included sub-modules should belong module, as defined by the
+     * "belongs-to" statement or sub-modules are only allowed to include other
+     * sub-modules belonging to the same module.
+     *
+     * @throws DataModelException a violation in data model rule
+     */
+    public void reportIncludeError() throws DataModelException {
+        DataModelException exception = new DataModelException("YANG file error : Included sub-module " +
+                getSubModuleName() + "doesn't belongs to parent module also it doesn't belongs" +
+                "to sub-module belonging to the same parent module.");
+        exception.setLine(getLineNumber());
+        exception.setCharPosition(getCharPosition());
+        throw exception;
+    }
 }
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangLengthRestriction.java b/src/main/java/org/onosproject/yangutils/datamodel/YangLengthRestriction.java
new file mode 100644
index 0000000..8556445
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangLengthRestriction.java
@@ -0,0 +1,217 @@
+/*
+ * 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.yangutils.datamodel;
+
+/*-
+ * Reference RFC 6020.
+ *
+ * Binary can be restricted with "length" statements alone.
+ *
+ */
+
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.parser.Parsable;
+import org.onosproject.yangutils.utils.YangConstructType;
+import org.onosproject.yangutils.utils.builtindatatype.YangUint64;
+
+/**
+ * Represents the restriction for length data type.
+ */
+public class YangLengthRestriction implements YangDesc, YangReference, YangAppErrorInfo, Parsable {
+
+    /*-
+     * Reference RFC 6020.
+     * The length Statement
+     *
+     * The "length" statement, which is an optional sub-statement to the
+     * "type" statement, takes as an argument a length expression string.
+     * It is used to restrict the built-in type "string", or types derived
+     * from "string".
+     * A "length" statement restricts the number of unicode characters in
+     * the string.
+     * A length range consists of an explicit value, or a lower bound, two
+     * consecutive dots "..", and an upper bound.  Multiple values or ranges
+     * can be given, separated by "|".  Length-restricting values MUST NOT
+     * be negative.  If multiple values or ranges are given, they all MUST
+     * be disjoint and MUST be in ascending order.  If a length restriction
+     * is applied to an already length-restricted type, the new restriction
+     * MUST be equal or more limiting, that is, raising the lower bounds,
+     * reducing the upper bounds, removing explicit length values or ranges,
+     * or splitting ranges into multiple ranges with intermediate gaps.  A
+     * length value is a non-negative integer, or one of the special values
+     * "min" or "max". "min" and "max" mean the minimum and maximum length
+     * accepted for the type being restricted, respectively.  An
+     * implementation is not required to support a length value larger than
+     * 18446744073709551615.
+     * The length's sub-statements
+     *
+     *  +---------------+---------+-------------+-----------------+
+     *  | substatement  | section | cardinality | mapped data type|
+     *  +---------------+---------+-------------+-----------------+
+     *  | description   | 7.19.3  | 0..1        | string          |
+     *  | error-app-tag | 7.5.4.2 | 0..1        | string          |
+     *  | error-message | 7.5.4.1 | 0..1        | string          |
+     *  | reference     | 7.19.4  | 0..1        | string          |
+     *  +---------------+---------+-------------+-----------------+
+     */
+
+    /**
+     * Length restriction information.
+     */
+    private YangRangeRestriction<YangUint64> lengthRestriction;
+
+    /**
+     * Textual reference.
+     */
+    private String reference;
+
+    /**
+     * Application's error message, to be used for data error.
+     */
+    private String errorMessage;
+
+    /**
+     * Application's error tag, to be filled in data validation error response.
+     */
+    private String errorAppTag;
+
+    /**
+     * Textual description.
+     */
+    private String description;
+
+    /**
+     * Creates a YANG length restriction object.
+     */
+    public YangLengthRestriction() {
+    }
+
+    /**
+     * Returns the length restriction on the string data.
+     *
+     * @return length restriction on the string data
+     */
+    public YangRangeRestriction<YangUint64> getLengthRestriction() {
+        return lengthRestriction;
+    }
+
+    /**
+     * Sets the length restriction on the string data.
+     *
+     * @param lengthRestriction length restriction on the string data
+     */
+    public void setLengthRestriction(YangRangeRestriction<YangUint64> lengthRestriction) {
+        this.lengthRestriction = lengthRestriction;
+    }
+
+    /**
+     * Returns the textual reference of the length restriction.
+     *
+     * @return textual reference of the length restriction
+     */
+    @Override
+    public String getReference() {
+        return reference;
+    }
+
+    /**
+     * Sets the textual reference of the length restriction.
+     *
+     * @param ref textual reference of the length restriction
+     */
+    @Override
+    public void setReference(String ref) {
+        reference = ref;
+    }
+
+    /**
+     * Returns the description of the length restriction.
+     *
+     * @return description of the length restriction
+     */
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Sets the description of the length restriction.
+     *
+     * @param desc description of the length restriction
+     */
+    @Override
+    public void setDescription(String desc) {
+        description = desc;
+
+    }
+
+    /**
+     * Returns application's error message, to be used for data error.
+     *
+     * @return Application's error message, to be used for data error
+     */
+    @Override
+    public String getGetErrorMessage() {
+        return errorMessage;
+    }
+
+    /**
+     * Sets Application's error message, to be used for data error.
+     *
+     * @param errMsg Application's error message, to be used for data error
+     */
+    @Override
+    public void setErrorMessage(String errMsg) {
+        errorMessage = errMsg;
+
+    }
+
+    /**
+     * Returns application's error tag, to be used for data error.
+     *
+     * @return application's error tag, to be used for data error
+     */
+    @Override
+    public String getGetErrorAppTag() {
+        return errorAppTag;
+    }
+
+    /**
+     * Sets application's error tag, to be used for data error.
+     *
+     * @param errTag application's error tag, to be used for data error.
+     */
+    @Override
+    public void setErrorAppTag(String errTag) {
+        errorAppTag = errTag;
+    }
+
+    @Override
+    public YangConstructType getYangConstructType() {
+        return YangConstructType.PATTERN_DATA;
+    }
+
+    @Override
+    public void validateDataOnEntry() throws DataModelException {
+        //TODO: implement the method.
+    }
+
+    @Override
+    public void validateDataOnExit() throws DataModelException {
+        //TODO: implement the method.
+    }
+}
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java b/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java
index f737e32..2fc88c0 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java
@@ -15,14 +15,20 @@
  */
 package org.onosproject.yangutils.datamodel;
 
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-
+import java.util.Set;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.linker.impl.YangReferenceResolver;
+import org.onosproject.yangutils.linker.impl.YangResolutionInfo;
 import org.onosproject.yangutils.parser.Parsable;
+import org.onosproject.yangutils.plugin.manager.YangFileInfo;
 import org.onosproject.yangutils.utils.YangConstructType;
 
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.linkInterFileReferences;
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveLinkingForResolutionList;
 
 /*-
@@ -79,7 +85,7 @@
 
     /**
      * Reference:RFC 6020.
-     *
+     * <p>
      * The "contact" statement provides contact information for the module. The
      * argument is a string that is used to specify contact information for the
      * person or persons to whom technical queries concerning this module should
@@ -90,7 +96,7 @@
 
     /**
      * Reference:RFC 6020.
-     *
+     * <p>
      * The "description" statement takes as an argument a string that contains a
      * human-readable textual description of this definition. The text is
      * provided in a language (or languages) chosen by the module developer; for
@@ -125,7 +131,7 @@
 
     /**
      * Reference:RFC 6020.
-     *
+     * <p>
      * The "organization" statement defines the party responsible for this
      * module. The argument is a string that is used to specify a textual
      * description of the organization(s) under whose auspices this module was
@@ -408,6 +414,14 @@
         resolveLinkingForResolutionList(resolutionList, this);
     }
 
+    @Override
+    public void resolveInterFileLinking() throws DataModelException {
+        // Get the list to be resolved.
+        List<YangResolutionInfo> resolutionList = getUnresolvedResolutionList();
+        // Resolve linking for a resolution list.
+        linkInterFileReferences(resolutionList, this);
+    }
+
     /**
      * Returns the textual reference.
      *
@@ -525,4 +539,43 @@
     public void setResolutionList(List<YangResolutionInfo> resolutionList) {
         unresolvedResolutionList = resolutionList;
     }
+
+    @Override
+    public void addReferencesToImportList(Set<YangFileInfo> yangFileInfoSet)
+            throws LinkerException {
+        Iterator<YangImport> importInfoIterator = getImportList().iterator();
+        // Run through the imported list to add references.
+        while (importInfoIterator.hasNext()) {
+            YangImport yangImport = importInfoIterator.next();
+            try {
+                yangImport.addReferenceToImport(yangFileInfoSet);
+            } catch (DataModelException e) {
+                throw new LinkerException(e.getMessage());
+            }
+        }
+    }
+
+    @Override
+    public void addReferencesToIncludeList(Set<YangFileInfo> yangFileInfoSet)
+            throws LinkerException {
+        Iterator<YangInclude> includeInfoIterator = getIncludeList().iterator();
+        // Run through the included list to add references.
+        while (includeInfoIterator.hasNext()) {
+            YangInclude yangInclude = includeInfoIterator.next();
+            YangSubModule subModule = null;
+            try {
+                subModule = yangInclude.addReferenceToInclude(yangFileInfoSet);
+            } catch (DataModelException e) {
+                throw new LinkerException(e.getMessage());
+            }
+            // Check if the referred sub-modules parent is self
+            if (!(subModule.getBelongsTo().getModuleNode() == this)) {
+                try {
+                    yangInclude.reportIncludeError();
+                } catch (DataModelException e) {
+                    throw new LinkerException(e.getMessage());
+                }
+            }
+        }
+    }
 }
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangReferenceResolver.java b/src/main/java/org/onosproject/yangutils/datamodel/YangReferenceResolver.java
deleted file mode 100644
index e9ae54d..0000000
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangReferenceResolver.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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.yangutils.datamodel;
-
-import java.util.List;
-import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
-
-/**
- * Abstraction of YANG dependency resolution information. Abstracted to obtain the
- * resolution information.
- */
-public interface YangReferenceResolver {
-
-    /**
-     * Returns unresolved resolution list.
-     *
-     * @return unresolved resolution list
-     */
-    List<YangResolutionInfo> getUnresolvedResolutionList();
-
-    /**
-     * Add to the resolution list.
-     *
-     * @param resolutionInfo resolution information
-     */
-    void addToResolutionList(YangResolutionInfo resolutionInfo);
-
-    /**
-     * Creates resolution list.
-     *
-     * @param resolutionList resolution list
-     */
-    void setResolutionList(List<YangResolutionInfo> resolutionList);
-
-    /**
-     * Returns unresolved imported list.
-     *
-     * @return unresolved imported list
-     */
-    List<YangImport> getImportList();
-
-    /**
-     * Add to the import list.
-     *
-     * @param yangImport import to be added
-     */
-    void addToImportList(YangImport yangImport);
-
-    /**
-     * Create import list.
-     *
-     * @param importList import list
-     */
-    void setImportList(List<YangImport> importList);
-
-    /**
-     * Returns unresolved include list.
-     *
-     * @return unresolved include list
-     */
-    List<YangInclude> getIncludeList();
-
-    /**
-     * Add to the include list.
-     *
-     * @param yangInclude include to be added
-     */
-    void addToIncludeList(YangInclude yangInclude);
-
-    /**
-     * Create include list.
-     *
-     * @param includeList include list
-     */
-    void setIncludeList(List<YangInclude> includeList);
-
-    /**
-     * Returns prefix of resolution root node.
-     *
-     * @return prefix resolution root node prefix
-     */
-    String getPrefix();
-
-    /**
-     * Set prefix of resolution list root node.
-     *
-     * @param prefix resolution root node prefix
-     */
-    void setPrefix(String prefix);
-
-    /**
-     * Resolve self file linking.
-     *
-     * @throws DataModelException a violation in data model rule
-     */
-    void resolveSelfFileLinking() throws DataModelException;
-}
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangResolutionInfo.java b/src/main/java/org/onosproject/yangutils/datamodel/YangResolutionInfo.java
deleted file mode 100644
index ac2d6b3..0000000
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangResolutionInfo.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * 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.yangutils.datamodel;
-
-import java.util.Stack;
-import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
-
-import static org.onosproject.yangutils.datamodel.ResolvableStatus.INTRA_FILE_RESOLVED;
-import static org.onosproject.yangutils.datamodel.ResolvableStatus.LINKED;
-import static org.onosproject.yangutils.datamodel.ResolvableStatus.RESOLVED;
-import static org.onosproject.yangutils.datamodel.ResolvableStatus.UNRESOLVED;
-
-/**
- * Represents resolution object which will be resolved by linker.
- *
- * @param <T> type of resolution entity uses / type
- */
-public class YangResolutionInfo<T> implements LocationInfo {
-
-    /**
-     * Information about the entity that needs to be resolved.
-     */
-    private YangEntityToResolveInfo<T> entityToResolveInfo;
-
-    // Error Line number.
-    private int lineNumber;
-
-    // Error character position.
-    private int charPosition;
-
-    /*
-     * Stack for type/uses is maintained for hierarchical references, this is
-     * used during resolution.
-     */
-    private Stack<YangEntityToResolveInfo<T>> partialResolvedStack;
-
-    // Module/Sub-module prefix.
-    private String resolutionInfoRootNodePrefix;
-
-    /**
-     * It is private to ensure the overloaded method be invoked to create an
-     * object.
-     */
-    @SuppressWarnings("unused")
-    private YangResolutionInfo() {
-
-    }
-
-    /**
-     * Creates a resolution information object with all the inputs.
-     *
-     * @param dataNode           current parsable data node
-     * @param holderNode         parent YANG node
-     * @param lineNumber         error line number
-     * @param charPositionInLine error character position in line
-     */
-    public YangResolutionInfo(T dataNode, YangNode holderNode, int lineNumber, int charPositionInLine) {
-        setEntityToResolveInfo(new YangEntityToResolveInfo<T>());
-        getEntityToResolveInfo().setEntityToResolve(dataNode);
-        getEntityToResolveInfo().setHolderOfEntityToResolve(holderNode);
-        this.setLineNumber(lineNumber);
-        this.setCharPosition(charPositionInLine);
-        setPartialResolvedStack(new Stack<YangEntityToResolveInfo<T>>());
-    }
-
-    /**
-     * Resolve linking with all the ancestors node for a resolution info.
-     *
-     * @param resolutionInfoNodePrefix module/sub-module prefix
-     * @throws DataModelException DataModelException a violation of data model
-     *                            rules
-     */
-    public void resolveLinkingForResolutionInfo(String resolutionInfoNodePrefix)
-            throws DataModelException {
-
-        this.resolutionInfoRootNodePrefix = resolutionInfoNodePrefix;
-
-        // Current node to resolve, it can be a YANG type or YANG uses.
-        T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
-
-        // Check if linking is already done
-        if (entityToResolve instanceof Resolvable) {
-            Resolvable resolvable = (Resolvable) entityToResolve;
-            if (resolvable.getResolvableStatus() == RESOLVED) {
-                /**
-                 * entity is already resolved, so nothing to do
-                 */
-                return;
-            }
-        } else {
-            throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
-        }
-
-        // Push the initial entity to resolve in stack.
-        addInPartialResolvedStack(getEntityToResolveInfo());
-
-        linkAndResolvePartialResolvedStack();
-    }
-
-    /**
-     * Resolves linking with ancestors.
-     *
-     * @throws DataModelException a violation of data model rules
-     */
-    private void linkAndResolvePartialResolvedStack()
-            throws DataModelException {
-
-        while (getPartialResolvedStack().size() != 0) {
-
-            // Current node to resolve, it can be a YANG type or YANG uses.
-            T entityToResolve = getCurrentEntityToResolveFromStack();
-            // Check if linking is already done
-            if (entityToResolve instanceof Resolvable) {
-
-                Resolvable resolvable = (Resolvable) entityToResolve;
-                switch (resolvable.getResolvableStatus()) {
-                    case RESOLVED: {
-                        /*
-                         * If the entity is already resolved in the stack, then
-                         * pop it and continue with the remaining stack elements
-                         * to resolve
-                         */
-                        getPartialResolvedStack().pop();
-                        break;
-                    }
-
-                    case LINKED: {
-                        /*
-                         * If the top of the stack is already linked then
-                         * resolve the references and pop the entity and
-                         * continue with remaining stack elements to resolve
-                         */
-                        resolveTopOfStack();
-                        getPartialResolvedStack().pop();
-                        break;
-                    }
-
-                    case INTRA_FILE_RESOLVED: {
-                        /*
-                         * TODO: this needs to be deleted, when inter-file
-                         * resolution is implmeneted
-                         */
-                        getPartialResolvedStack().pop();
-                        break;
-                    }
-
-                    case UNRESOLVED: {
-                        linkTopOfStackReferenceUpdateStack();
-
-                        if (resolvable.getResolvableStatus() == UNRESOLVED) {
-                            // If current entity is still not resolved, then linking/resolution has failed.
-                            DataModelException dataModelException =
-                                    new DataModelException("YANG file error: Unable to find base "
-                                            + "typedef/grouping for given type/uses");
-                            dataModelException.setLine(getLineNumber());
-                            dataModelException.setCharPosition(getCharPosition());
-                            throw dataModelException;
-                        }
-                        break;
-                    }
-                    default: {
-                        throw new DataModelException("Data Model Exception: Unsupported, linker state");
-                    }
-
-                }
-
-            } else {
-                throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
-            }
-
-        }
-
-    }
-
-    /**
-     * Resolve the current entity in the stack.
-     */
-    private void resolveTopOfStack()
-            throws DataModelException {
-        ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
-        if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus()
-                != INTRA_FILE_RESOLVED) {
-            // Sets the resolution status in inside the type/uses.
-            ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
-        }
-    }
-
-    /**
-     * Resolves linking for a node child and siblings.
-     *
-     * @throws DataModelException data model error
-     */
-    private void linkTopOfStackReferenceUpdateStack()
-            throws DataModelException {
-
-        if (!isSelfFileReference()) {
-            /*
-             * TODO: use mojo utilities to load the referred module/sub-module
-             * and get the reference to the corresponding referred entity
-             */
-
-            ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
-            return;
-        }
-
-        /**
-         * Try to resolve the top of the stack and update partial resolved stack
-         * if there is recursive references
-         */
-        YangNode potentialAncestorWithReferredNode = getPartialResolvedStack().peek()
-                .getHolderOfEntityToResolve();
-
-        /**
-         * Traverse up in the ancestor tree to check if the referred node is
-         * defined
-         */
-        while (potentialAncestorWithReferredNode != null) {
-
-            /**
-             * Check for the referred node defined in a ancestor scope
-             */
-            YangNode potentialReferredNode = potentialAncestorWithReferredNode.getChild();
-            if (isReferredNodeInSiblingListProcessed(potentialReferredNode)) {
-                return;
-            }
-
-            potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
-        }
-    }
-
-    /**
-     * Check if the reference in self file or in external file.
-     *
-     * @return true if self file reference, false otherwise
-     * @throws DataModelException a violation of data model rules
-     */
-    private boolean isSelfFileReference()
-            throws DataModelException {
-        String prefix;
-        if (getCurrentEntityToResolveFromStack() instanceof YangType) {
-            prefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
-        } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
-            prefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
-        } else {
-            throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
-        }
-
-        if (prefix == null) {
-            return true;
-        }
-        return prefix.contentEquals(resolutionInfoRootNodePrefix);
-
-    }
-
-    /**
-     * Check for the referred node defined in a ancestor scope.
-     *
-     * @param potentialReferredNode potential referred node
-     * @return status of resolution and updating the partial resolved stack with
-     * the any recursive references
-     * @throws DataModelException data model errors
-     */
-    private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
-            throws DataModelException {
-        while (potentialReferredNode != null) {
-
-            // Check if the potential referred node is the actual referred node
-            if (isReferredNode(potentialReferredNode)) {
-
-                // Adds reference link of entity to the node under resolution.
-                addReferredEntityLink(potentialReferredNode);
-
-                /**
-                 * resolve the reference and update the partial resolution stack
-                 * with any further recursive references
-                 */
-                addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
-
-                /*
-                 * return true, since the reference is linked and any recursive
-                 * unresolved references is added to the stack
-                 */
-                return true;
-            }
-
-            potentialReferredNode = potentialReferredNode.getNextSibling();
-        }
-        return false;
-    }
-
-    /**
-     * Check if the potential referred node is the actual referred node.
-     *
-     * @param potentialReferredNode typedef/grouping node
-     * @return true if node is of resolve type otherwise false
-     * @throws DataModelException a violation of data model rules
-     */
-    private boolean isReferredNode(YangNode potentialReferredNode)
-            throws DataModelException {
-        if (getCurrentEntityToResolveFromStack() instanceof YangType) {
-            if (potentialReferredNode instanceof YangTypeDef) {
-                /*
-                 * Check if name of node name matches with the entity being
-                 * resolved
-                 */
-                return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
-            }
-        } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
-            if (potentialReferredNode instanceof YangGrouping) {
-                /*
-                 * Check if name of node name matches with the entity being
-                 * resolved
-                 */
-                return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
-            }
-        } else {
-            throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
-        }
-        return false;
-    }
-
-    /**
-     * Check if node name is same as name in resolution info, i.e. name of
-     * typedef/grouping is same as name of type/uses.
-     *
-     * @param node typedef/grouping node
-     * @return true if node name is same as name in resolution info, otherwise
-     * false
-     * @throws DataModelException a violation of data model rules
-     */
-
-    private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
-            throws DataModelException {
-        if (getCurrentEntityToResolveFromStack() instanceof YangType) {
-            if (node.getName().contentEquals(
-                    ((YangType<?>) getCurrentEntityToResolveFromStack())
-                            .getDataTypeName())) {
-                return true;
-            }
-        } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
-            if (node.getName().contentEquals(
-                    ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
-                return true;
-            }
-        } else {
-            throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
-        }
-        return false;
-    }
-
-    /**
-     * Adds reference of grouping/typedef in uses/type.
-     *
-     * @param referredNode grouping/typedef node being referred
-     * @throws DataModelException a violation of data model rules
-     */
-    private void addReferredEntityLink(YangNode referredNode)
-            throws DataModelException {
-        if (getCurrentEntityToResolveFromStack() instanceof YangType) {
-            YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>)
-                    ((YangType<?>) getCurrentEntityToResolveFromStack()).getDataTypeExtendedInfo();
-            derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
-        } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
-            ((YangUses) getCurrentEntityToResolveFromStack())
-                    .setRefGroup((YangGrouping) referredNode);
-        } else {
-            throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
-        }
-
-        // Sets the resolution status in inside the type/uses.
-        ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(LINKED);
-    }
-
-    /**
-     * Checks if type/grouping has further reference to typedef/ unresolved
-     * uses. Add it to the partial resolve stack and return the status of
-     * addition to stack.
-     *
-     * @param referredNode grouping/typedef node
-     * @throws DataModelException a violation of data model rules
-     */
-    private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
-            throws DataModelException {
-        if (getCurrentEntityToResolveFromStack() instanceof YangType) {
-            /*
-             * Checks if typedef type is derived
-             */
-            if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType()
-                    == YangDataTypes.DERIVED) {
-
-                YangEntityToResolveInfo<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfo<YangType<?>>();
-                unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
-                        .getTypeDefBaseType());
-                unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
-                addInPartialResolvedStack((YangEntityToResolveInfo<T>) unResolvedEntityInfo);
-            }
-
-        } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
-            /*
-             * Search if the grouping has any un resolved uses child, if so
-             * return true, else return false.
-             */
-            addUnResolvedUsesToStack(referredNode);
-        } else {
-            throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
-        }
-    }
-
-    /**
-     * Return if there is any unresolved uses in grouping.
-     *
-     * @param node grouping/typedef node
-     */
-    private void addUnResolvedUsesToStack(YangNode node) {
-
-        /**
-         * Search the grouping node's children for presence of uses node.
-         */
-        YangNode curNode = node.getChild();
-        while (curNode != null) {
-            if (curNode instanceof YangUses) {
-                ResolvableStatus curResolveStatus = ((Resolvable) curNode).getResolvableStatus();
-                if (curResolveStatus == UNRESOLVED) {
-                    /**
-                     * The current uses is not resolved, add it to partial
-                     * resolved stack
-                     */
-                    YangEntityToResolveInfo<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfo<YangUses>();
-                    unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
-                    unResolvedEntityInfo.setHolderOfEntityToResolve(node);
-                    addInPartialResolvedStack((YangEntityToResolveInfo<T>) unResolvedEntityInfo);
-
-                }
-            }
-            curNode = curNode.getNextSibling();
-        }
-    }
-
-    /**
-     * Returns stack of YANG type with partially resolved YANG construct
-     * hierarchy.
-     *
-     * @return partial resolved YANG construct stack
-     */
-    private Stack<YangEntityToResolveInfo<T>> getPartialResolvedStack() {
-        return partialResolvedStack;
-    }
-
-    /**
-     * Sets stack of YANG type with partially resolved YANG construct hierarchy.
-     *
-     * @param partialResolvedStack partial resolved YANG construct stack
-     */
-    private void setPartialResolvedStack(Stack<YangEntityToResolveInfo<T>> partialResolvedStack) {
-        this.partialResolvedStack = partialResolvedStack;
-    }
-
-    /**
-     * Sets stack of YANG type with partially resolved YANG construct hierarchy.
-     *
-     * @param partialResolvedInfo partial resolved YANG construct stack
-     */
-    private void addInPartialResolvedStack(YangEntityToResolveInfo<T> partialResolvedInfo) {
-        getPartialResolvedStack().push(partialResolvedInfo);
-    }
-
-    /**
-     * Retrieves the next entity in the stack that needs to be resolved. It is
-     * assumed that the caller ensures that the stack is not empty.
-     *
-     * @return next entity in the stack that needs to be resolved
-     */
-    private T getCurrentEntityToResolveFromStack() {
-        return getPartialResolvedStack().peek().getEntityToResolve();
-    }
-
-    /**
-     * Retrieves information about the entity that needs to be resolved.
-     *
-     * @return information about the entity that needs to be resolved
-     */
-    public YangEntityToResolveInfo<T> getEntityToResolveInfo() {
-        return entityToResolveInfo;
-    }
-
-    /**
-     * Sets information about the entity that needs to be resolved.
-     *
-     * @param entityToResolveInfo information about the entity that needs to be
-     *                            resolved
-     */
-    public void setEntityToResolveInfo(YangEntityToResolveInfo<T> entityToResolveInfo) {
-        this.entityToResolveInfo = entityToResolveInfo;
-    }
-
-    @Override
-    public int getLineNumber() {
-        return lineNumber;
-    }
-
-    @Override
-    public int getCharPosition() {
-        return charPosition;
-    }
-
-    @Override
-    public void setLineNumber(int lineNumber) {
-        this.lineNumber = lineNumber;
-    }
-
-    @Override
-    public void setCharPosition(int charPositionInLine) {
-        this.charPosition = charPositionInLine;
-    }
-}
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangSubModule.java b/src/main/java/org/onosproject/yangutils/datamodel/YangSubModule.java
index d762151..bf442a1 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangSubModule.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangSubModule.java
@@ -15,14 +15,20 @@
  */
 package org.onosproject.yangutils.datamodel;
 
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-
+import java.util.Set;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.linker.impl.YangReferenceResolver;
+import org.onosproject.yangutils.linker.impl.YangResolutionInfo;
 import org.onosproject.yangutils.parser.Parsable;
+import org.onosproject.yangutils.plugin.manager.YangFileInfo;
 import org.onosproject.yangutils.utils.YangConstructType;
 
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.linkInterFileReferences;
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveLinkingForResolutionList;
 
 /*
@@ -92,7 +98,7 @@
 
     /**
      * Reference RFC 6020.
-     *
+     * <p>
      * The "contact" statement provides contact information for the module. The
      * argument is a string that is used to specify contact information for the
      * person or persons to whom technical queries concerning this module should
@@ -338,6 +344,14 @@
         resolveLinkingForResolutionList(resolutionList, this);
     }
 
+    @Override
+    public void resolveInterFileLinking() throws DataModelException {
+        // Get the list to be resolved.
+        List<YangResolutionInfo> resolutionList = getUnresolvedResolutionList();
+        // Resolve linking for a resolution list.
+        linkInterFileReferences(resolutionList, this);
+    }
+
     /**
      * Returns the list of leaves.
      *
@@ -507,4 +521,54 @@
     public void setResolutionList(List<YangResolutionInfo> resolutionList) {
         this.unresolvedResolutionList = resolutionList;
     }
+
+    /**
+     * Links the sub-module with module.
+     *
+     * @param yangFileInfoSet YANG file information set
+     * @throws DataModelException a violation in data model rule
+     */
+    public void linkWithModule(Set<YangFileInfo> yangFileInfoSet)
+            throws DataModelException {
+        getBelongsTo().linkWithModule(yangFileInfoSet);
+    }
+
+    @Override
+    public void addReferencesToIncludeList(Set<YangFileInfo> yangFileInfoSet)
+            throws LinkerException {
+        Iterator<YangInclude> includeInfoIterator = getIncludeList().iterator();
+        // Run through the included list to add references.
+        while (includeInfoIterator.hasNext()) {
+            YangInclude yangInclude = includeInfoIterator.next();
+            YangSubModule subModule = null;
+            try {
+                subModule = yangInclude.addReferenceToInclude(yangFileInfoSet);
+            } catch (DataModelException e) {
+                throw new LinkerException(e.getMessage());
+            }
+            // Check if the referred sub-modules parent is self
+            if (!(subModule.getBelongsTo().getModuleNode() == getBelongsTo().getModuleNode())) {
+                try {
+                    yangInclude.reportIncludeError();
+                } catch (DataModelException e) {
+                    throw new LinkerException(e.getMessage());
+                }
+            }
+        }
+    }
+
+    @Override
+    public void addReferencesToImportList(Set<YangFileInfo> yangFileInfoSet)
+            throws LinkerException {
+        Iterator<YangImport> importInfoIterator = getImportList().iterator();
+        // Run through the imported list to add references.
+        while (importInfoIterator.hasNext()) {
+            YangImport yangImport = importInfoIterator.next();
+            try {
+                yangImport.addReferenceToImport(yangFileInfoSet);
+            } catch (DataModelException e) {
+                throw new LinkerException(e.getMessage());
+            }
+        }
+    }
 }
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangType.java b/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
index d37a8c7..4421619 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
@@ -17,6 +17,9 @@
 package org.onosproject.yangutils.datamodel;
 
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.linker.impl.Resolvable;
+import org.onosproject.yangutils.linker.impl.ResolvableStatus;
 import org.onosproject.yangutils.parser.Parsable;
 import org.onosproject.yangutils.utils.YangConstructType;
 
@@ -244,21 +247,25 @@
     }
 
     @Override
-    public void resolve() throws DataModelException {
+    public void resolve() throws LinkerException {
        /*
         * Check whether the data type is derived.
         */
         if (getDataType() != DERIVED) {
-            throw new DataModelException("Linker Error: Resolve should only be called for derived data types.");
+            throw new LinkerException("Linker Error: Resolve should only be called for derived data types.");
         }
 
         // Check if the derived info is present.
         YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) getDataTypeExtendedInfo();
         if (derivedInfo == null) {
-            throw new DataModelException("Linker Error: Derived information is missing.");
+            throw new LinkerException("Linker Error: Derived information is missing.");
         }
 
         // Initiate the resolution
-        setResolvableStatus(derivedInfo.resolve());
+        try {
+            setResolvableStatus(derivedInfo.resolve());
+        } catch (DataModelException e) {
+            throw new LinkerException(e.getMessage());
+        }
     }
 }
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java b/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
index 55fbaf4..f6a5e6b 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
@@ -16,6 +16,9 @@
 package org.onosproject.yangutils.datamodel;
 
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.linker.impl.Resolvable;
+import org.onosproject.yangutils.linker.impl.ResolvableStatus;
 import org.onosproject.yangutils.parser.Parsable;
 import org.onosproject.yangutils.utils.YangConstructType;
 
@@ -259,37 +262,49 @@
 
     @Override
     public void resolve()
-            throws DataModelException {
+            throws LinkerException {
 
         YangGrouping referredGrouping = getRefGroup();
 
         if (referredGrouping == null) {
-            throw new DataModelException("YANG uses linker error, cannot resolve uses");
+            throw new LinkerException("Linker Exception: YANG uses linker error, cannot resolve uses");
         }
 
         YangNode usesParentNode = getParentNodeInGenCode(this);
         if ((!(usesParentNode instanceof YangLeavesHolder))
                 || (!(usesParentNode instanceof CollisionDetector))) {
-            throw new DataModelException("YANG uses holder construct is wrong");
+            throw new LinkerException("Linker Exception: YANG uses holder construct is wrong");
         }
 
         YangLeavesHolder usesParentLeavesHolder = (YangLeavesHolder) usesParentNode;
         if (referredGrouping.getListOfLeaf() != null) {
             for (YangLeaf leaf : referredGrouping.getListOfLeaf()) {
-                ((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leaf.getName(),
-                        YangConstructType.LEAF_DATA);
+                try {
+                    ((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leaf.getName(),
+                            YangConstructType.LEAF_DATA);
+                } catch (DataModelException e) {
+                    throw new LinkerException(e.getMessage());
+                }
                 usesParentLeavesHolder.addLeaf(leaf);
             }
         }
         if (referredGrouping.getListOfLeafList() != null) {
             for (YangLeafList leafList : referredGrouping.getListOfLeafList()) {
-                ((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leafList.getName(),
-                        YangConstructType.LEAF_LIST_DATA);
+                try {
+                    ((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leafList.getName(),
+                            YangConstructType.LEAF_LIST_DATA);
+                } catch (DataModelException e) {
+                    throw new LinkerException(e.getMessage());
+                }
                 usesParentLeavesHolder.addLeafList(leafList);
             }
         }
 
-        YangNode.cloneSubTree(getRefGroup(), usesParentNode);
+        try {
+            YangNode.cloneSubTree(getRefGroup(), usesParentNode);
+        } catch (DataModelException e) {
+            throw new LinkerException(e.getMessage());
+        }
     }
 
     @Override
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java b/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
index e243d5e..93eb417 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
@@ -16,17 +16,15 @@
 
 package org.onosproject.yangutils.datamodel.utils;
 
-import java.util.Iterator;
 import java.util.List;
-
+import java.util.Set;
 import org.onosproject.yangutils.datamodel.CollisionDetector;
-import org.onosproject.yangutils.datamodel.YangImport;
 import org.onosproject.yangutils.datamodel.YangLeaf;
 import org.onosproject.yangutils.datamodel.YangLeafList;
 import org.onosproject.yangutils.datamodel.YangLeavesHolder;
 import org.onosproject.yangutils.datamodel.YangNode;
-import org.onosproject.yangutils.datamodel.YangReferenceResolver;
-import org.onosproject.yangutils.datamodel.YangResolutionInfo;
+import org.onosproject.yangutils.linker.impl.YangReferenceResolver;
+import org.onosproject.yangutils.linker.impl.YangResolutionInfo;
 import org.onosproject.yangutils.datamodel.YangRpc;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.parser.Parsable;
@@ -48,14 +46,13 @@
      * Detects the colliding identifier name in a given YANG node and its child.
      *
      * @param identifierName name for which collision detection is to be
-     * checked
-     * @param dataType type of YANG node asking for detecting collision
-     * @param node instance of calling node
+     *                       checked
+     * @param dataType       type of YANG node asking for detecting collision
+     * @param node           instance of calling node
      * @throws DataModelException a violation of data model rules
      */
     public static void detectCollidingChildUtil(String identifierName, YangConstructType dataType, YangNode node)
             throws DataModelException {
-
         if (dataType == YangConstructType.USES_DATA || dataType == YangConstructType.GROUPING_DATA) {
             detectCollidingForUsesGrouping(identifierName, dataType, node);
         } else {
@@ -81,9 +78,9 @@
      * Detects colliding of uses and grouping only with uses and grouping respectively.
      *
      * @param identifierName name for which collision detection is to be
-     * checked
-     * @param dataType type of YANG node asking for detecting collision
-     * @param node node instance of calling node
+     *                       checked
+     * @param dataType       type of YANG node asking for detecting collision
+     * @param node           node instance of calling node
      * @throws DataModelException a violation of data model rules
      */
     public static void detectCollidingForUsesGrouping(String identifierName, YangConstructType dataType, YangNode node)
@@ -103,9 +100,9 @@
     /**
      * Detects the colliding identifier name in a given leaf node.
      *
-     * @param listOfLeaf List of leaves to detect collision
+     * @param listOfLeaf     List of leaves to detect collision
      * @param identifierName name for which collision detection is to be
-     * checked
+     *                       checked
      * @throws DataModelException a violation of data model rules
      */
     private static void detectCollidingLeaf(List<YangLeaf> listOfLeaf, String identifierName)
@@ -127,7 +124,7 @@
      *
      * @param listOfLeafList list of leaf-lists to detect collision
      * @param identifierName name for which collision detection is to be
-     * checked
+     *                       checked
      * @throws DataModelException a violation of data model rules
      */
     private static void detectCollidingLeafList(List<YangLeafList> listOfLeafList, String identifierName)
@@ -148,7 +145,7 @@
      * Add a resolution information.
      *
      * @param resolutionInfo information about the YANG construct which has to
-     * be resolved
+     *                       be resolved
      * @throws DataModelException a violation of data model rules
      */
     public static void addResolutionInfo(YangResolutionInfo resolutionInfo)
@@ -165,64 +162,41 @@
         }
         YangReferenceResolver resolutionNode = (YangReferenceResolver) curNode;
 
-        if (!isPrefixValid(resolutionInfo.getEntityToResolveInfo().getEntityPrefix(),
-                resolutionNode)) {
-            throw new DataModelException("The prefix used is not valid");
-        }
         resolutionNode.addToResolutionList(resolutionInfo);
     }
 
     /**
-     * Evaluates whether the prefix in uses/type is valid.
-     *
-     * @param entityPrefix prefix in the current module/sub-module
-     * @param resolutionNode uses/type node which has the prefix with it
-     * @return whether prefix is valid or not
-     */
-    private static boolean isPrefixValid(String entityPrefix, YangReferenceResolver resolutionNode) {
-        if (entityPrefix == null) {
-            return true;
-        }
-
-        if (resolutionNode.getPrefix().contentEquals(entityPrefix)) {
-            return true;
-        }
-
-        if (resolutionNode.getImportList() != null) {
-            for (YangImport importedInfo : resolutionNode.getImportList()) {
-                if (importedInfo.getPrefixId().contentEquals(entityPrefix)) {
-                    return true;
-                }
-            }
-        }
-
-        if (resolutionNode.getIncludeList() != null) {
-            /**
-             * TODO: check if the prefix matches with the imported data
-
-             for (YangInclude includedInfo : resolutionNode.getIncludeList()) {
-             if (includedInfo.contentEquals(prefix)) {
-             return true;
-             }
-             }*/
-        }
-
-        return false;
-    }
-
-    /**
      * Resolve linking for a resolution list.
      *
-     * @param resolutionList resolution list for which linking to be done
+     * @param resolutionList    resolution list for which linking to be done
      * @param dataModelRootNode module/sub-module node
      * @throws DataModelException a violation of data model rules
      */
     public static void resolveLinkingForResolutionList(List<YangResolutionInfo> resolutionList,
-            YangReferenceResolver dataModelRootNode)
+                                                       YangReferenceResolver dataModelRootNode)
             throws DataModelException {
 
         for (YangResolutionInfo resolutionInfo : resolutionList) {
-            resolutionInfo.resolveLinkingForResolutionInfo(dataModelRootNode.getPrefix());
+            resolutionInfo.resolveLinkingForResolutionInfo(dataModelRootNode);
+        }
+    }
+
+    /**
+     * Links type/uses referring to typedef/uses of inter YANG file.
+     *
+     * @param resolutionList    resolution list for which linking to be done
+     * @param dataModelRootNode module/sub-module node
+     * @throws DataModelException a violation of data model rules
+     */
+    public static void linkInterFileReferences(List<YangResolutionInfo> resolutionList,
+                                               YangReferenceResolver dataModelRootNode)
+            throws DataModelException {
+        /*
+         * Run through the resolution list, find type/uses referring to
+         * inter file typedef/grouping, ask for linking.
+         */
+        for (YangResolutionInfo resolutionInfo : resolutionList) {
+            resolutionInfo.linkInterFile(dataModelRootNode);
         }
     }
 
@@ -244,24 +218,23 @@
     }
 
     /**
-     * Returns module's data model node to which sub-module belongs to.
+     * Returns referred node in a given set.
      *
-     * @param yangFileInfo YANG file information
-     * @param belongsToModuleName name of the module to which sub-module belongs to
-     * @return module node to which sub-module belongs to
-     * @throws DataModelException when belongs to module node is not found
+     * @param yangFileInfoSet YANG file info set
+     * @param refNodeName     name of the node which is referred
+     * @return referred node's reference
      */
-    public static YangNode findBelongsToModuleNode(List<YangFileInfo> yangFileInfo,
-                String belongsToModuleName) throws DataModelException {
-        Iterator<YangFileInfo> yangFileIterator = yangFileInfo.iterator();
-        while (yangFileIterator.hasNext()) {
-            YangFileInfo yangFile = yangFileIterator.next();
-            YangNode yangNode = yangFile.getRootNode();
-            if (yangNode.getName().equals(belongsToModuleName)) {
-                return yangNode;
+    public static YangNode findReferredNode(Set<YangFileInfo> yangFileInfoSet, String refNodeName) {
+        /*
+         * Run through the YANG files to see which YANG file matches the
+         * referred node name.
+         */
+        for (YangFileInfo yangFileInfo : yangFileInfoSet) {
+            YangNode yangNode = yangFileInfo.getRootNode();
+            if (yangNode.getName().equals(refNodeName)) {
+                return yangFileInfo.getRootNode();
             }
         }
-        throw new DataModelException("YANG file error : Module " + belongsToModuleName + " to which sub-module " +
-                "belongs to is not found.");
+        return null;
     }
 }