diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/ChoiceCaseTranslatorTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/ChoiceCaseTranslatorTest.java
new file mode 100644
index 0000000..b872ab6
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/ChoiceCaseTranslatorTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.plugin.manager;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
+import org.onosproject.yangutils.utils.io.impl.YangPluginConfig;
+
+import static org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorUtil.generateJavaCode;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
+
+/**
+ * Unit tests for choice-case translator.
+ */
+public final class ChoiceCaseTranslatorTest {
+
+    private final YangUtilsParserManager manager = new YangUtilsParserManager();
+
+    /**
+     * Checks choice-case translation should not result in any exception.
+     */
+    @Test
+    public void processChoiceCaseTranslator() throws IOException, ParserException {
+
+        String userDir = System.getProperty("user.dir");
+        YangNode node = manager.getDataModel("src/test/resources/ChoiceCaseTranslator.yang");
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(userDir + "/target/ChoiceCaseTestGenFile/");
+
+        generateJavaCode(node, yangPluginConfig);
+
+        deleteDirectory(userDir + "/target/ChoiceCaseTestGenFile/");
+    }
+    // TODO enhance the test cases, after having a framework of translator test.
+}
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/EnumTranslatorTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/EnumTranslatorTest.java
new file mode 100644
index 0000000..6956851
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/EnumTranslatorTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.plugin.manager;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
+import org.onosproject.yangutils.utils.io.impl.YangPluginConfig;
+
+import static org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorUtil.generateJavaCode;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
+
+/**
+ * Unit test case for enum translator.
+ */
+public final class EnumTranslatorTest {
+
+    private final YangUtilsParserManager manager = new YangUtilsParserManager();
+
+    /**
+     * Checks enum translation should not result in any exception.
+     */
+    @Test
+    public void processEnumTranslator()
+            throws IOException, ParserException {
+
+        String userDir = System.getProperty("user.dir");
+        YangNode node = manager.getDataModel("src/test/resources/EnumTranslator.yang");
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(userDir + "/target/EnumTestGenFile/");
+
+        generateJavaCode(node, yangPluginConfig);
+
+        deleteDirectory(userDir + "/target/EnumTestGenFile/");
+    }
+    // TODO enhance the test cases, after having a framework of translator test.
+}
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileLinkingTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileLinkingTest.java
new file mode 100644
index 0000000..51c7f7c
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileLinkingTest.java
@@ -0,0 +1,729 @@
+/*
+ * 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.plugin.manager;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ListIterator;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangDataTypes;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
+import org.onosproject.yangutils.datamodel.YangGrouping;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeType;
+import org.onosproject.yangutils.datamodel.YangTypeDef;
+import org.onosproject.yangutils.datamodel.YangUses;
+import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
+import org.onosproject.yangutils.linker.impl.YangLinkerManager;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.utils.io.impl.YangFileScanner;
+import org.onosproject.yangutils.utils.io.impl.YangPluginConfig;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.STRING;
+import static org.onosproject.yangutils.datamodel.YangNodeType.MODULE_NODE;
+import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
+
+/**
+ * Test cases for testing inter file linking.
+ */
+public class InterFileLinkingTest {
+
+    private final YangUtilManager utilManager = new YangUtilManager();
+    private final YangLinkerManager yangLinkerManager = new YangLinkerManager();
+
+    /**
+     * Checks inter file type linking.
+     */
+    @Test
+    public void processInterFileTypeLinking()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/interfiletype";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+
+        YangNode refNode = null;
+        YangNode selfNode = null;
+
+        // Create YANG node set
+        yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
+
+        // Add references to import list.
+        yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
+
+        Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
+
+        YangNode rootNode = yangNodeIterator.next();
+
+        if (rootNode.getName().equals("module1")) {
+            selfNode = rootNode;
+            refNode = yangNodeIterator.next();
+        } else {
+            refNode = rootNode;
+            selfNode = yangNodeIterator.next();
+        }
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(selfNode instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) selfNode;
+        assertThat(yangNode.getName(), is("module1"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) refNode.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks inter file uses linking.
+     */
+    @Test
+    public void processInterFileUsesLinking()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/interfileuses";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+
+        YangNode refNode = null;
+        YangNode selfNode = null;
+
+        // Create YANG node set
+        yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
+
+        // Add references to import list.
+        yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
+
+        Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
+
+        YangNode rootNode = yangNodeIterator.next();
+
+        if (rootNode.getName().equals("module1")) {
+            selfNode = rootNode;
+            refNode = yangNodeIterator.next();
+        } else {
+            refNode = rootNode;
+            selfNode = yangNodeIterator.next();
+        }
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((selfNode instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) selfNode;
+        assertThat(yangNode.getName(), is("module1"));
+
+        ListIterator<YangLeaf> leafIterator;
+        YangLeaf leafInfo;
+
+        // Check whether grouping is the sibling of module's child.
+        assertThat((refNode.getChild() instanceof YangGrouping), is(true));
+
+        YangGrouping grouping = (YangGrouping) refNode.getChild();
+        leafIterator = grouping.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under grouping.
+        assertThat(leafInfo.getName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+        // Check whether uses is module's child.
+        assertThat((yangNode.getChild() instanceof YangUses), is(true));
+        YangUses uses = (YangUses) yangNode.getChild();
+
+        // Check whether uses get resolved.
+        assertThat(uses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+    }
+
+    /**
+     * Checks inter file type linking with include list.
+     */
+    @Test
+    public void processInterFileTypeLinkingWithIncludeList()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/interfiletypewithinclude";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+
+        YangNode refNode = null;
+        YangNode selfNode = null;
+
+        // Create YANG node set
+        yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
+
+        // Carry out linking of sub module with module.
+        yangLinkerManager.linkSubModulesToParentModule(utilManager.getYangNodeSet());
+
+        // Add reference to include list.
+        yangLinkerManager.addRefToYangFilesIncludeList(utilManager.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
+
+        Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
+
+        YangNode rootNode = yangNodeIterator.next();
+
+        if (rootNode.getName().equals("module1")) {
+            selfNode = rootNode;
+            refNode = yangNodeIterator.next();
+        } else {
+            refNode = rootNode;
+            selfNode = yangNodeIterator.next();
+        }
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(selfNode instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) selfNode;
+        assertThat(yangNode.getName(), is("module1"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) refNode.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks inter file uses linking with include list.
+     */
+    @Test
+    public void processInterFileUsesLinkingWithInclude()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/interfileuseswithinclude";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+
+        YangNode refNode = null;
+        YangNode selfNode = null;
+
+        // Create YANG node set
+        yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
+
+        // Carry out linking of sub module with module.
+        yangLinkerManager.linkSubModulesToParentModule(utilManager.getYangNodeSet());
+
+        // Add reference to include list.
+        yangLinkerManager.addRefToYangFilesIncludeList(utilManager.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
+
+        Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
+
+        YangNode rootNode = yangNodeIterator.next();
+
+        if (rootNode.getName().equals("module1")) {
+            selfNode = rootNode;
+            refNode = yangNodeIterator.next();
+        } else {
+            refNode = rootNode;
+            selfNode = yangNodeIterator.next();
+        }
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((selfNode instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) selfNode;
+        assertThat(yangNode.getName(), is("module1"));
+
+        ListIterator<YangLeaf> leafIterator;
+        YangLeaf leafInfo;
+
+        // Check whether grouping is the sibling of module's child.
+        assertThat((refNode.getChild() instanceof YangGrouping), is(true));
+
+        YangGrouping grouping = (YangGrouping) refNode.getChild();
+        leafIterator = grouping.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under grouping.
+        assertThat(leafInfo.getName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+        // Check whether uses is module's child.
+        assertThat((yangNode.getChild() instanceof YangUses), is(true));
+        YangUses uses = (YangUses) yangNode.getChild();
+
+        // Check whether uses get resolved.
+        assertThat(uses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+    }
+
+    /**
+     * Checks inter file type linking with revision.
+     */
+    @Test
+    public void processInterFileTypeLinkingWithRevision()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/interfiletypewithrevision";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+
+        YangNode refNode = null;
+        YangNode selfNode = null;
+
+        // Create YANG node set
+        yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
+
+        // Add references to import list.
+        yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
+
+        Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
+
+        YangNode rootNode = yangNodeIterator.next();
+
+        if (rootNode.getName().equals("module1")) {
+            selfNode = rootNode;
+            refNode = yangNodeIterator.next();
+        } else {
+            refNode = rootNode;
+            selfNode = yangNodeIterator.next();
+        }
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(selfNode instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) selfNode;
+        assertThat(yangNode.getName(), is("module1"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) refNode.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks inter file type linking with revision in name.
+     */
+    @Test
+    public void processInterFileTypeLinkingWithRevisionInName()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/interfiletypewithrevisioninname";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+
+        YangNode refNode = null;
+        YangNode selfNode = null;
+
+        // Create YANG node set
+        yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
+
+        // Add references to import list.
+        yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
+
+        Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
+
+        YangNode rootNode = yangNodeIterator.next();
+
+        if (rootNode.getName().equals("module1")) {
+            selfNode = rootNode;
+            refNode = yangNodeIterator.next();
+        } else {
+            refNode = rootNode;
+            selfNode = yangNodeIterator.next();
+        }
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(selfNode instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) selfNode;
+        assertThat(yangNode.getName(), is("module1"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) refNode.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks hierarchical inter file type linking.
+     */
+    @Test
+    public void processHierarchicalInterFileTypeLinking()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/hierarchicalinterfiletype";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+
+        YangNode refNode1 = null;
+        YangNode refNode2 = null;
+        YangNode selfNode = null;
+
+        // Create YANG node set
+        yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
+
+        // Add references to import list.
+        yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
+
+        for (YangNode rootNode : utilManager.getYangNodeSet()) {
+            if (rootNode.getName().equals("ietf-network-topology")) {
+                selfNode = rootNode;
+            } else if (rootNode.getName().equals("ietf-network")) {
+                refNode1 = rootNode;
+            } else {
+                refNode2 = rootNode;
+            }
+        }
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(selfNode instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) selfNode;
+        assertThat(yangNode.getName(), is("ietf-network-topology"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("source-node"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("node-id"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) refNode1.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks hierarchical intra with inter file type linking.
+     */
+    @Test
+    public void processHierarchicalIntraWithInterFileTypeLinking()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/hierarchicalintrawithinterfiletype";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+
+        YangNode refNode1 = null;
+        YangNode selfNode = null;
+
+        // Create YANG node set
+        yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
+
+        // Add references to import list.
+        yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
+
+        for (YangNode rootNode : utilManager.getYangNodeSet()) {
+            if (rootNode.getName().equals("ietf-network")) {
+                selfNode = rootNode;
+            } else if (rootNode.getName().equals("ietf-inet-types")) {
+                refNode1 = rootNode;
+            }
+        }
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(selfNode instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) selfNode;
+        assertThat(yangNode.getName(), is("ietf-network"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("node-ref"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("node-id"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) selfNode.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks hierarchical intra with inter file type linking.
+     */
+    @Test
+    public void interFileWithUsesReferringType()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/interfilewithusesreferringtype";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.resolveDependenciesUsingLinker();
+
+        String userDir = System.getProperty("user.dir");
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir("target/interfilewithusesreferringtype/");
+
+        utilManager.translateToJava(utilManager.getYangFileInfoSet(), yangPluginConfig);
+
+        deleteDirectory(userDir + "/target/interfilewithusesreferringtype/");
+
+    }
+
+    /**
+     * Checks hierarchical intra with inter file type linking.
+     */
+    @Test
+    public void file1UsesFile2TypeDefFile3Type()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/file1UsesFile2TypeDefFile3Type";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.resolveDependenciesUsingLinker();
+
+        String userDir = System.getProperty("user.dir");
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir("target/file1UsesFile2TypeDefFile3Type/");
+
+        utilManager.translateToJava(utilManager.getYangFileInfoSet(), yangPluginConfig);
+
+        deleteDirectory(userDir + "/target/file1UsesFile2TypeDefFile3Type/");
+
+    }
+
+
+    /**
+     * Checks hierarchical intra with inter file type linking.
+     */
+    @Test
+    public void interFileIetf()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/interfileietf";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.resolveDependenciesUsingLinker();
+
+        String userDir = System.getProperty("user.dir");
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir("target/interfileietf/");
+
+        utilManager.translateToJava(utilManager.getYangFileInfoSet(), yangPluginConfig);
+
+        deleteDirectory(userDir + "/target/interfileietf/");
+
+    }
+
+
+    /**
+     * Checks hierarchical intra with inter file type linking.
+     */
+    @Test
+    public void usesInContainer()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/usesInContainer";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.resolveDependenciesUsingLinker();
+
+        String userDir = System.getProperty("user.dir");
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir("target/usesInContainer/");
+
+        utilManager.translateToJava(utilManager.getYangFileInfoSet(), yangPluginConfig);
+
+        deleteDirectory(userDir + "/target/usesInContainer/");
+
+    }
+
+
+    /**
+     * Checks hierarchical intra with inter file type linking.
+     */
+    @Test
+    public void groupingNodeSameAsModule()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/groupingNodeSameAsModule";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.resolveDependenciesUsingLinker();
+
+        String userDir = System.getProperty("user.dir");
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir("target/groupingNodeSameAsModule/");
+
+        utilManager.translateToJava(utilManager.getYangFileInfoSet(), yangPluginConfig);
+
+        deleteDirectory(userDir + "/target/groupingNodeSameAsModule/");
+
+    }
+}
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileTypeLinkingTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileTypeLinkingTest.java
new file mode 100644
index 0000000..fdf3c2c
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileTypeLinkingTest.java
@@ -0,0 +1,565 @@
+/*
+ * 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.plugin.manager;
+
+import java.io.IOException;
+import java.util.ListIterator;
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangContainer;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangTypeDef;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.BINARY;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.INT32;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.STRING;
+import static org.onosproject.yangutils.datamodel.YangNodeType.MODULE_NODE;
+import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
+import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
+
+/**
+ * Test cases for testing "type" intra file linking.
+ */
+public class IntraFileTypeLinkingTest {
+
+    private final YangUtilsParserManager manager = new YangUtilsParserManager();
+
+    /**
+     * Checks self resolution when typedef and leaf using type are siblings.
+     */
+    @Test
+    public void processSelfResolutionWhenTypeAndTypedefAtRootLevel()
+            throws IOException, ParserException {
+
+        YangNode node = manager.getDataModel("src/test/resources/SelfResolutionWhenTypeAndTypedefAtRootLevel.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks self resolution when typedef and leaf using type are at different
+     * level where typedef is at the root.
+     */
+    @Test
+    public void processSelfFileLinkingTypedefAtRootTypeTwoLevelInHierarchy()
+            throws IOException, ParserException {
+
+        YangNode node =
+                manager.getDataModel("src/test/resources/SelfFileLinkingTypedefAtRootTypeTwoLevelInHierarchy.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        YangContainer yangContainer = (YangContainer) node.getChild().getNextSibling();
+
+        YangList yangList = (YangList) yangContainer.getChild();
+
+        ListIterator<YangLeaf> leafIterator = yangList.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks self resolution when typedef and leaf using type are at different
+     * level where typedef is at the root and defined after parent holder
+     * of type.
+     */
+    @Test
+    public void processSelfFileLinkingTypedefAtRootIsAfterContainerHavingType()
+            throws IOException, ParserException {
+
+        YangNode node =
+                manager.getDataModel("src/test/resources/SelfFileLinkingTypedefAtRootIsAfterContainerHavingType.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        YangContainer yangContainer = (YangContainer) node.getChild();
+
+        YangList yangList = (YangList) yangContainer.getChild();
+
+        ListIterator<YangLeaf> leafIterator = yangList.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild().getNextSibling()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks self resolution when typedef and leaf using type are at different
+     * level where typedef is at the level of root+1 and defined after parent
+     * holder of type.
+     */
+    @Test
+    public void processSelfFileLinkingTypedefAtMiddleLevelAfterParentHolder()
+            throws IOException, ParserException {
+
+        YangNode node =
+                manager.getDataModel("src/test/resources/SelfFileLinkingTypedefAtMiddleLevelAfterParentHolder.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        YangContainer yangContainer = (YangContainer) node.getChild();
+
+        YangList yangList = (YangList) yangContainer.getChild();
+
+        ListIterator<YangLeaf> leafIterator = yangList.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) yangContainer.getChild().getNextSibling()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks self resolution when typedef hierarchical references are present.
+     */
+    @Test
+    public void processSelfFileLinkingWithTypdefHierarchicalReference()
+            throws IOException, ParserException {
+
+        YangNode node =
+                manager.getDataModel("src/test/resources/SelfFileLinkingWithTypdefHierarchicalReference.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        YangContainer yangContainer = (YangContainer) node.getChild().getNextSibling();
+
+        YangList yangList = (YangList) yangContainer.getChild();
+
+        ListIterator<YangLeaf> leafIterator = yangList.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("FirstClass"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) yangList.getChild()));
+        assertThat(leafInfo.getDataType().getResolvableStatus(),
+                is(RESOLVED));
+
+        YangTypeDef typeDef1 = (YangTypeDef) yangList.getChild();
+
+        assertThat(((YangDerivedInfo<?>) typeDef1.getTypeDefBaseType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) yangContainer.getChild().getNextSibling()));
+        assertThat(typeDef1.getTypeDefBaseType().getResolvableStatus(),
+                is(RESOLVED));
+
+        YangTypeDef typeDef2 = (YangTypeDef) yangContainer.getChild().getNextSibling();
+
+        assertThat(((YangDerivedInfo<?>) typeDef2.getTypeDefBaseType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+        assertThat(typeDef2.getTypeDefBaseType().getResolvableStatus(),
+                is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(INT32));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks self resolution when typedef hierarchical references are present
+     * with last type is unresolved.
+     */
+    @Test
+    public void processSelfFileLinkingWithTypdefHierarchicalRefUnresolved()
+            throws IOException, ParserException {
+
+        YangNode node =
+                manager.getDataModel("src/test/resources/SelfFileLinkingWithTypdefHierarchicalRefUnresolved.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        YangContainer yangContainer = (YangContainer) node.getChild().getNextSibling();
+
+        YangList yangList = (YangList) yangContainer.getChild();
+
+        ListIterator<YangLeaf> leafIterator = yangList.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("FirstClass"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) yangList.getChild()));
+        assertThat(leafInfo.getDataType().getResolvableStatus(),
+                is(INTRA_FILE_RESOLVED));
+
+        YangTypeDef typeDef1 = (YangTypeDef) yangList.getChild();
+
+        assertThat(((YangDerivedInfo<?>) typeDef1.getTypeDefBaseType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) yangContainer.getChild().getNextSibling()));
+        assertThat(typeDef1.getTypeDefBaseType().getResolvableStatus(),
+                is(INTRA_FILE_RESOLVED));
+
+        YangTypeDef typeDef2 = (YangTypeDef) yangContainer.getChild().getNextSibling();
+
+        assertThat(((YangDerivedInfo<?>) typeDef2.getTypeDefBaseType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+        assertThat(typeDef2.getTypeDefBaseType().getResolvableStatus(),
+                is(INTRA_FILE_RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(nullValue()));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks self resolution when type uses prefix of self module.
+     */
+    @Test
+    public void processSelfFileLinkingWithTypeWithSelfModulePrefix()
+            throws IOException, ParserException {
+
+        YangNode node =
+                manager.getDataModel("src/test/resources/SelfFileLinkingWithTypeWithSelfModulePrefix.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        YangContainer yangContainer = (YangContainer) node.getChild().getNextSibling();
+
+        YangList yangList = (YangList) yangContainer.getChild();
+
+        ListIterator<YangLeaf> leafIterator = yangList.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("FirstClass"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) yangList.getChild()));
+        assertThat(leafInfo.getDataType().getResolvableStatus(),
+                is(RESOLVED));
+
+        YangTypeDef typeDef1 = (YangTypeDef) yangList.getChild();
+
+        assertThat(((YangDerivedInfo<?>) typeDef1.getTypeDefBaseType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) yangContainer.getChild().getNextSibling()));
+        assertThat(typeDef1.getTypeDefBaseType().getResolvableStatus(),
+                is(RESOLVED));
+
+        YangTypeDef typeDef2 = (YangTypeDef) yangContainer.getChild().getNextSibling();
+
+        assertThat(((YangDerivedInfo<?>) typeDef2.getTypeDefBaseType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+        assertThat(typeDef2.getTypeDefBaseType().getResolvableStatus(),
+                is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(INT32));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Checks self resolution when some type uses prefix of self module
+     * some uses external prefix.
+     */
+    @Test
+    public void processSelfFileLinkingWithTypeWithSelfAndExternalPrefixMix()
+            throws IOException, ParserException {
+
+        YangNode node =
+                manager.getDataModel("src/test/resources/SelfFileLinkingWithTypeWithSelfAndExternalPrefixMix.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        YangContainer yangContainer = (YangContainer) node.getChild().getNextSibling();
+
+        YangList yangList = (YangList) yangContainer.getChild();
+
+        ListIterator<YangLeaf> leafIterator = yangList.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("FirstClass"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) yangList.getChild()));
+        assertThat(leafInfo.getDataType().getResolvableStatus(),
+                is(INTRA_FILE_RESOLVED));
+
+        YangTypeDef typeDef1 = (YangTypeDef) yangList.getChild();
+
+        YangTypeDef typeDef2 = (YangTypeDef) yangContainer.getChild().getNextSibling();
+
+        assertThat(((YangDerivedInfo<?>) typeDef2.getTypeDefBaseType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+        assertThat(typeDef2.getTypeDefBaseType().getResolvableStatus(),
+                is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(nullValue()));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+
+    /**
+     * Check self resolution when type referred typedef is not available in
+     * file.
+     */
+    @Test(expected = LinkerException.class)
+    public void processSelfResolutionWhenTypeReferredTypedefNotDefined()
+            throws IOException, LinkerException {
+
+        YangNode node =
+                manager.getDataModel("src/test/resources/SelfResolutionWhenTypeReferredTypedefNotDefined.yang");
+    }
+
+    /**
+     * Checks self resolution when typedef and leaf using type are at different
+     * level where typedef is is not an ancestor of type.
+     */
+    @Test(expected = LinkerException.class)
+    public void processSelfFileLinkingTypedefNotFound()
+            throws IOException, LinkerException {
+
+        YangNode node = manager.getDataModel("src/test/resources/SelfFileLinkingTypedefNotFound.yang");
+    }
+
+    /**
+     * Checks hierarchical self resolution with self resolution failure scenario.
+     */
+    @Test(expected = LinkerException.class)
+    public void processSelfFileLinkingWithHierarchicalTypeFailureScenario()
+            throws IOException, LinkerException {
+
+        YangNode node =
+                manager.getDataModel("src/test/resources/SelfFileLinkingWithHierarchicalTypeFailureScenario.yang");
+    }
+
+    /**
+     * Checks self resolution when typedef and leaf using type are siblings for binary type.
+     */
+    @Test
+    public void processSelfResolutionWhenTypeAndTypedefAtRootLevelForBinary()
+            throws IOException, ParserException {
+
+        YangNode node
+                = manager.getDataModel("src/test/resources/SelfResolutionWhenTypeAndTypedefAtRootLevelForBinary.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("ospf"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("typedef14"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("type14"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(BINARY));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(nullValue()));
+    }
+}
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileUsesLinkingTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileUsesLinkingTest.java
new file mode 100644
index 0000000..c264979
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileUsesLinkingTest.java
@@ -0,0 +1,790 @@
+/*
+ * 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.plugin.manager;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ListIterator;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onosproject.yangutils.datamodel.YangContainer;
+import org.onosproject.yangutils.datamodel.YangDataTypes;
+import org.onosproject.yangutils.datamodel.YangGrouping;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeType;
+import org.onosproject.yangutils.datamodel.YangTypeDef;
+import org.onosproject.yangutils.datamodel.YangUses;
+import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+/**
+ * Test cases for testing uses intra file linking.
+ */
+public class IntraFileUsesLinkingTest {
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    private final YangUtilsParserManager manager = new YangUtilsParserManager();
+
+    /**
+     * Checks self resolution when grouping and uses are siblings.
+     * Grouping followed by uses.
+     */
+    @Test
+    public void processSelfResolutionWhenUsesAndGroupingAtRootLevel()
+            throws IOException, ParserException {
+
+        YangNode node = manager.getDataModel("src/test/resources/SelfResolutionWhenUsesAndGroupingAtRootLevel.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator;
+        YangLeaf leafInfo;
+
+        // Check whether grouping is the sibling of module's child.
+        assertThat((yangNode.getChild().getNextSibling() instanceof YangGrouping), is(true));
+
+        YangGrouping grouping = (YangGrouping) yangNode.getChild().getNextSibling();
+        leafIterator = grouping.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under grouping.
+        assertThat(leafInfo.getName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+        // Check whether uses is module's child.
+        assertThat((yangNode.getChild() instanceof YangUses), is(true));
+        YangUses uses = (YangUses) yangNode.getChild();
+
+        // Check whether uses get resolved.
+        assertThat(uses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        ListIterator<List<YangLeaf>> leafIterator1 = uses.getUsesResolvedLeavesList().listIterator();
+        List<YangLeaf> leafInfo1 = leafIterator1.next();
+        ListIterator<YangLeaf> leafIterator2 = leafInfo1.listIterator();
+        YangLeaf leafInfo2 = leafIterator2.next();
+
+        // Check whether the information in the leaf is correct under module.
+        assertThat(leafInfo2.getName(), is("hello"));
+        assertThat(leafInfo2.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo2.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+    }
+
+    /**
+     * Checks self resolution when grouping and uses are siblings.
+     * Grouping has a child node.
+     */
+    @Test
+    public void processSelfResolutionWhenUsesAndGroupingAtRootLevelGroupingWithChild()
+            throws IOException, ParserException {
+
+        YangNode node = manager.getDataModel(
+                "src/test/resources/SelfResolutionWhenUsesAndGroupingAtRootLevelGroupingWithChild.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator;
+        YangLeaf leafInfo;
+
+        // Check whether grouping is the sibling of module's child.
+        assertThat((yangNode.getChild().getNextSibling() instanceof YangGrouping), is(true));
+
+        YangGrouping grouping = (YangGrouping) yangNode.getChild().getNextSibling();
+        leafIterator = grouping.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under grouping.
+        assertThat(leafInfo.getName(), is("treat"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+        // Check whether container is the child of grouping.
+        assertThat((grouping.getChild() instanceof YangContainer), is(true));
+        YangContainer container = (YangContainer) grouping.getChild();
+
+        // Check whether the container name is set correctly which is under grouping.
+        assertThat(container.getName(), is("test"));
+
+        leafIterator = container.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under container which is under grouping.
+        assertThat(leafInfo.getName(), is("leaf2"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+        // Check whether uses is module's child.
+        assertThat((yangNode.getChild() instanceof YangUses), is(true));
+        YangUses uses = (YangUses) yangNode.getChild();
+
+        // Check whether uses get resolved.
+        assertThat(uses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        ListIterator<List<YangLeaf>> leafIterator1 = uses.getUsesResolvedLeavesList().listIterator();
+        List<YangLeaf> leafInfo1 = leafIterator1.next();
+        ListIterator<YangLeaf> leafIterator2 = leafInfo1.listIterator();
+        YangLeaf leafInfo2 = leafIterator2.next();
+
+        // Check whether the information in the leaf is correct under module.
+        assertThat(leafInfo2.getName(), is("treat"));
+        assertThat(leafInfo2.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo2.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+        ListIterator<YangNode> usesChildren = uses.getUsesResolvedNodeList().listIterator();
+        YangNode usesChild = usesChildren.next();
+        // Check whether container is the child of module.
+        assertThat((usesChild instanceof YangContainer), is(true));
+        container = (YangContainer) usesChild;
+
+        // Check whether the container name is set correctly which is under module.
+        assertThat(container.getName(), is("test"));
+
+        leafIterator = container.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under container which is under module.
+        assertThat(leafInfo.getName(), is("leaf2"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+    }
+
+    /**
+     * Checks self resolution when grouping in rpc and uses in output of the same rpc.
+     * Uses is followed by grouping.
+     */
+    @Test
+    public void processSelfResolutionGroupingInRpcAndUsesInOutput()
+            throws IOException, ParserException {
+
+        YangNode node = manager
+                .getDataModel("src/test/resources/SelfResolutionGroupingInRpcAndUsesInOutput.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("rock"));
+
+        ListIterator<YangLeaf> leafIterator;
+        YangLeaf leafInfo;
+
+        // Check whether grouping is the child of rpc.
+        assertThat((yangNode.getChild().getChild() instanceof YangGrouping), is(true));
+        YangGrouping grouping = (YangGrouping) yangNode.getChild().getChild();
+
+        // Check whether the grouping name is set correctly.
+        assertThat(grouping.getName(), is("hello"));
+
+        // Check whether list is the child of grouping.
+        assertThat((grouping.getChild() instanceof YangList), is(true));
+        YangList yangListNode = (YangList) grouping.getChild();
+
+        // Check whether the list name is set correctly.
+        assertThat(yangListNode.getName(), is("valid"));
+
+        leafIterator = yangListNode.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under list which is under grouping.
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("uint16"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.UINT16));
+        assertThat(leafInfo.getUnits(), is("\"seconds\""));
+        assertThat(leafInfo.getReference(), is("\"RFC 6020\""));
+
+        // Check whether uses is input's child.
+        assertThat((yangNode.getChild().getChild().getNextSibling().getChild() instanceof YangUses), is(true));
+        YangUses uses = (YangUses) yangNode.getChild().getChild().getNextSibling().getChild();
+
+        // Check whether uses get resolved.
+        assertThat(uses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        ListIterator<YangNode> usesChildren = uses.getUsesResolvedNodeList().listIterator();
+        YangNode usesChild = usesChildren.next();
+
+        // Check whether list is the sibling of uses which has been deep copied from grouping.
+        assertThat((usesChild instanceof YangList), is(true));
+
+        YangList yangList = (YangList) usesChild;
+
+        // Check whether the list name is set correctly.
+        assertThat(yangList.getName(), is("valid"));
+
+        leafIterator = yangList.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under list which is deep copied.
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("uint16"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.UINT16));
+        assertThat(leafInfo.getUnits(), is("\"seconds\""));
+        assertThat(leafInfo.getReference(), is("\"RFC 6020\""));
+
+        // Check whether uses is output's child.
+        assertThat((yangNode.getChild().getChild().getNextSibling().getNextSibling().getChild() instanceof YangUses),
+                is(true));
+        YangUses usesInOuput = (YangUses) yangNode.getChild().getChild().getNextSibling().getNextSibling().getChild();
+
+        // Check whether uses get resolved.
+        assertThat(usesInOuput.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        ListIterator<YangNode> usesInOuputChildren = usesInOuput.getUsesResolvedNodeList().listIterator();
+        YangNode usesInOuputChild = usesInOuputChildren.next();
+
+        // Check whether list is the sibling of uses which has been deep copied from grouping.
+        assertThat((usesInOuputChild instanceof YangList), is(true));
+
+        YangList yangListInOutput = (YangList) usesInOuputChild;
+
+        // Check whether the list name is set correctly.
+        assertThat(yangListInOutput.getName(), is("valid"));
+
+        leafIterator = yangListInOutput.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under list which is deep copied.
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("uint16"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.UINT16));
+        assertThat(leafInfo.getUnits(), is("\"seconds\""));
+        assertThat(leafInfo.getReference(), is("\"RFC 6020\""));
+    }
+
+    /**
+     * Checks the failure scenario when uses is referring to its own grouping directly.
+     */
+    @Test
+    public void processSelfResolutionGroupingReferencingItselfFailureScenerio()
+            throws IOException {
+
+        thrown.expect(LinkerException.class);
+        thrown.expectMessage(
+                "YANG file error: Duplicate input identifier detected, same as leaf \"zip-code\"");
+        YangNode node = manager
+                .getDataModel("src/test/resources/SelfResolutionGroupingReferencingItselfFailureScenerio.yang");
+
+    }
+
+    /**
+     * Checks the when multiple uses are present and are referred to the grouping at different levels.
+     */
+    @Test
+    public void processSelfResolutionGroupingWithMultipleUses()
+            throws IOException, ParserException {
+
+        YangNode node = manager
+                .getDataModel("src/test/resources/SelfResolutionGroupingWithMultipleUses.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator;
+        YangLeaf leafInfo;
+
+        // Check whether grouping is the child of container.
+        assertThat((yangNode.getChild().getChild() instanceof YangGrouping), is(true));
+        YangGrouping grouping = (YangGrouping) yangNode.getChild().getChild();
+
+        // Check whether the grouping name is set correctly.
+        assertThat(grouping.getName(), is("endpoint"));
+
+        // Check whether uses is endpoint-grouping's child.
+        assertThat((grouping.getChild() instanceof YangUses), is(true));
+        YangUses firstUses = (YangUses) grouping.getChild();
+
+        // Check whether uses get resolved.
+        assertThat(firstUses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        ListIterator<YangNode> firstUsesChildren = firstUses.getUsesResolvedNodeList().listIterator();
+        YangNode firstUsesChild = firstUsesChildren.next();
+
+        // Check whether list is the sibling of uses.
+        assertThat((firstUsesChild instanceof YangList), is(true));
+        YangList yangList = (YangList) firstUsesChild;
+        assertThat(yangList.getName(), is("valid"));
+
+        leafIterator = yangList.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under list which has been deep copied from grouping.
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("uint16"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.UINT16));
+        assertThat(leafInfo.getUnits(), is("\"seconds\""));
+        assertThat(leafInfo.getReference(), is("\"RFC 6020\""));
+
+        // Check whether container is the sibling of uses.
+        assertThat((firstUses.getNextSibling() instanceof YangContainer), is(true));
+        YangContainer yangContainer = (YangContainer) firstUses.getNextSibling();
+
+        // Check whether the container name is set correctly.
+        assertThat(yangContainer.getName(), is("design"));
+
+        // Check whether uses is design-container's child.
+        assertThat((yangContainer.getChild() instanceof YangUses), is(true));
+        YangUses secondUses = (YangUses) yangContainer.getChild();
+
+        // Check whether uses get resolved.
+        assertThat(secondUses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        ListIterator<List<YangLeaf>> leafIterator1 = secondUses.getUsesResolvedLeavesList().listIterator();
+        List<YangLeaf> leafInfo1 = leafIterator1.next();
+        ListIterator<YangLeaf> leafIterator2 = leafInfo1.listIterator();
+        YangLeaf leafInfo2 = leafIterator2.next();
+
+        // Check whether the information in the leaf is correct under design-container.
+        assertThat(leafInfo2.getName(), is("ink"));
+        assertThat(leafInfo2.getDataType().getDataTypeName(), is("int32"));
+        assertThat(leafInfo2.getDataType().getDataType(), is(YangDataTypes.INT32));
+
+        // Check whether container is the sibling of uses.
+        assertThat((secondUses.getNextSibling() instanceof YangContainer), is(true));
+        YangContainer yangContainer2 = (YangContainer) secondUses.getNextSibling();
+        assertThat(yangContainer2.getName(), is("correct"));
+
+        leafIterator = yangContainer2.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under correct-container.
+        assertThat(leafInfo.getName(), is("newone"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+        // Check whether uses is correct container's child.
+        assertThat((yangContainer2.getChild() instanceof YangUses), is(true));
+        YangUses thirdUses = (YangUses) yangContainer2.getChild();
+
+        // Check whether uses get resolved.
+        assertThat(thirdUses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        ListIterator<YangNode> thirdUsesChildren = thirdUses.getUsesResolvedNodeList().listIterator();
+        YangNode thirdUsesChild = thirdUsesChildren.next();
+
+        // Check whether container is the child of uses.
+        assertThat((thirdUsesChild instanceof YangContainer), is(true));
+
+        YangContainer yangContainer3 = (YangContainer) thirdUsesChild;
+        assertThat(yangContainer3.getName(), is("value"));
+
+        leafIterator = yangContainer3.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under container
+        // which has been deep copied from grouping.
+        assertThat(leafInfo.getName(), is("zip-code"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+
+        // Check whether uses is the sibling of container-design.
+        assertThat((yangContainer.getNextSibling() instanceof YangUses), is(true));
+        YangUses fourthUses = (YangUses) yangContainer.getNextSibling();
+        assertThat(fourthUses.getName(), is("fourth"));
+        // Check whether uses get resolved.
+        assertThat(fourthUses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        ListIterator<List<YangLeaf>> fourthUsesChildren = fourthUses.getUsesResolvedLeavesList().listIterator();
+        List<YangLeaf> fourthUsesChild = fourthUsesChildren.next();
+        ListIterator<YangLeaf> fourthUsesChildren1 = fourthUsesChild.listIterator();
+        YangLeaf fourthUsesChild1 = fourthUsesChildren1.next();
+
+        // Check whether the information in the leaf is correct under correct-container.
+        assertThat(fourthUsesChild1.getName(), is("correct"));
+        assertThat(fourthUsesChild1.getDataType().getDataTypeName(), is("my-type"));
+        assertThat(fourthUsesChild1.getDataType().getDataType(), is(YangDataTypes.DERIVED));
+
+        // Check whether uses is the sibling of previous uses.
+        assertThat((fourthUses.getNextSibling() instanceof YangUses), is(true));
+        YangUses fifthUses = (YangUses) fourthUses.getNextSibling();
+        assertThat(fifthUses.getName(), is("fifth"));
+
+        // Check whether uses get resolved.
+        assertThat(fifthUses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        ListIterator<List<YangLeaf>> fifthUsesChildren = fifthUses.getUsesResolvedLeavesList().listIterator();
+        List<YangLeaf> fifthUsesChild = fifthUsesChildren.next();
+        ListIterator<YangLeaf> fifthUsesChildren1 = fifthUsesChild.listIterator();
+        YangLeaf fifthUsesChild1 = fifthUsesChildren1.next();
+
+        //Check whether the information in the leaf is correct under correct-container.
+        assertThat(fifthUsesChild1.getName(), is("abc"));
+        assertThat(fifthUsesChild1.getDataType().getDataTypeName(), is("string"));
+        assertThat(fifthUsesChild1.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+        //Check whether uses is endpoint-grouping's sibling.
+        assertThat((grouping.getNextSibling() instanceof YangUses), is(true));
+        YangUses endpointUses = (YangUses) grouping.getNextSibling();
+
+        // Check whether uses get resolved.
+        assertThat(endpointUses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+        assertThat(endpointUses.getName(), is("endpoint"));
+
+        ListIterator<YangNode> endpointUsesUsesChildren = endpointUses.getUsesResolvedNodeList().listIterator();
+        YangNode endpointUsesUsesChild = endpointUsesUsesChildren.next();
+
+        // Check whether list is the sibling of uses.
+        assertThat((endpointUsesUsesChild instanceof YangList), is(true));
+        YangList yangList1 = (YangList) firstUsesChild;
+        assertThat(yangList1.getName(), is("valid"));
+
+        leafIterator = yangList1.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under list which has been deep copied from grouping.
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("uint16"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.UINT16));
+        assertThat(leafInfo.getUnits(), is("\"seconds\""));
+        assertThat(leafInfo.getReference(), is("\"RFC 6020\""));
+    }
+
+    /**
+     * Checks the failure scenario when uses is present under the same node many times.
+     */
+    @Test
+    public void processSelfResolutionGroupingHavingSameUsesManyTimes()
+            throws IOException, ParserException {
+
+        thrown.expect(ParserException.class);
+        thrown.expectMessage(
+                "YANG file error: Duplicate input identifier detected, same as uses \"failure\"");
+        YangNode node = manager
+                .getDataModel("src/test/resources/SelfResolutionGroupingHavingSameUsesManyTimes.yang");
+    }
+
+    /**
+     * Checks the rpc having both typedef and grouping.
+     * It also checks that the grouping under different nodes will not give any problem in resolving uses.
+     */
+    @Test
+    public void processSelfResolutionRpcWithOneTypedefAndTwoGroupingUnderDifferentNode()
+            throws IOException, ParserException {
+
+        YangNode node = manager
+                .getDataModel(
+                        "src/test/resources/SelfResolutionRpcWithOneTypedefAndTwoGroupingUnderDifferentNode.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("rock"));
+
+        ListIterator<YangLeaf> leafIterator;
+        YangLeaf leafInfo;
+
+        // Check whether grouping is the child of input.
+        assertThat((yangNode.getChild().getChild().getChild() instanceof YangGrouping), is(true));
+        YangGrouping groupingUnderInput = (YangGrouping) yangNode.getChild().getChild().getChild();
+
+        // Check whether the grouping name is set correctly.
+        assertThat(groupingUnderInput.getName(), is("creative"));
+
+        leafIterator = groupingUnderInput.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under grouping.
+        assertThat(leafInfo.getName(), is("carry"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+        // Check whether grouping is the child of output.
+        assertThat((yangNode.getChild().getChild().getNextSibling().getChild() instanceof YangGrouping), is(true));
+        YangGrouping grouping = (YangGrouping) yangNode.getChild().getChild().getNextSibling().getChild();
+        assertThat(grouping.getName(), is("creative"));
+
+        // Check whether typedef is the sibling of grouping.
+        assertThat((grouping.getNextSibling() instanceof YangTypeDef), is(true));
+
+        YangTypeDef typedef = (YangTypeDef) grouping.getNextSibling();
+        assertThat(typedef.getName(), is("my-type"));
+
+        // Check whether uses is the sibling of typedef.
+        assertThat((typedef.getNextSibling() instanceof YangUses), is(true));
+
+        // Check whether uses get resolved.
+        YangUses uses = (YangUses) typedef.getNextSibling();
+        assertThat(uses.getName(), is("creative"));
+        assertThat(uses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+    }
+
+    /**
+     * Checks the failure scenario when uses is cannot resolve its grouping.
+     */
+    @Test
+    public void processSelfResolutionNestedGroupingWithUnresolvedUses()
+            throws IOException, LinkerException {
+
+        thrown.expect(LinkerException.class);
+        thrown.expectMessage(
+                "YANG file error: Unable to find base grouping for given uses");
+
+        YangNode node = manager
+                .getDataModel("src/test/resources/SelfResolutionNestedGroupingWithUnresolvedUses.yang");
+    }
+
+    /**
+     * Checks self resolution when typedef hierarchical references are present
+     * with last type is unresolved.
+     */
+    @Test
+    public void processSelfFileLinkingWithGroupingHierarchicalRefUnresolved()
+            throws IOException, ParserException {
+
+        YangNode node = manager
+                .getDataModel("src/test/resources/SelfFileLinkingWithGroupingHierarchicalRefUnresolved.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        // Check whether container is the sibling of grouping.
+        assertThat((yangNode.getChild().getNextSibling() instanceof YangContainer), is(true));
+        YangContainer containerWithUses = (YangContainer) yangNode.getChild().getNextSibling();
+        assertThat(containerWithUses.getName(), is("test"));
+
+        // Check whether uses is the child of container.
+        assertThat((containerWithUses.getChild() instanceof YangUses), is(true));
+        YangUses uses = (YangUses) containerWithUses.getChild();
+        assertThat(uses.getName(), is("create"));
+
+        // Check whether uses is getting resolved.
+        assertThat(uses.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        // Check whether grouping is the child of module.
+        assertThat((yangNode.getChild() instanceof YangGrouping), is(true));
+        YangGrouping groupingWithUses = (YangGrouping) yangNode.getChild();
+        assertThat(groupingWithUses.getName(), is("create"));
+
+        // Check whether uses with prefix from from other file, is the child of grouping.
+        assertThat((groupingWithUses.getChild() instanceof YangUses), is(true));
+        YangUses uses1 = (YangUses) groupingWithUses.getChild();
+        assertThat(uses1.getName(), is("valid"));
+
+        // Check whether this uses is getting intra-file-resolved.
+        assertThat(uses1.getResolvableStatus(),
+                is(ResolvableStatus.INTRA_FILE_RESOLVED));
+    }
+
+    /**
+     * Checks self resolution when uses has prefix of self module.
+     */
+    @Test
+    public void processSelfFileLinkingWithGroupingWithSelfModulePrefix()
+            throws IOException, ParserException {
+
+        YangNode node = manager.getDataModel("src/test/resources/SelfFileLinkingWithGroupingWithSelfModulePrefix.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        // Check whether container is the sibling of grouping.
+        YangContainer yangContainer = (YangContainer) node.getChild().getNextSibling();
+
+        // Check whether list is the child of container.
+        YangList yangList = (YangList) yangContainer.getChild();
+
+        // Check whether uses is the child of list.
+        assertThat((yangList.getChild() instanceof YangUses), is(true));
+        YangUses yangUses1 = (YangUses) yangList.getChild();
+        assertThat(yangUses1.getName(), is("FirstClass"));
+
+        // Check whether uses is getting resolved.
+        assertThat(yangUses1.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        // Check whether grouping is the sibling of uses.
+        YangGrouping yangGrouping1 = (YangGrouping) yangUses1.getNextSibling();
+        assertThat(yangGrouping1.getName(), is("FirstClass"));
+
+        // Check whether uses is the child of grouping.
+        YangUses yangUses2 = (YangUses) yangGrouping1.getChild();
+        assertThat(yangUses2.getName(), is("PassingClass"));
+
+        // Check the uses gets resolved.
+        assertThat(yangUses2.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        // Check whether grouping is the sibling of list.
+        YangGrouping yangGrouping2 = (YangGrouping) yangList.getNextSibling();
+        assertThat(yangGrouping2.getName(), is("PassingClass"));
+
+        // Check uses is the child of that grouping which has prefix of the same module.
+        YangUses yangUses3 = (YangUses) yangGrouping2.getChild();
+        assertThat(yangUses3.getName(), is("Percentage"));
+
+        // Check uses is getting resolved.
+        assertThat(yangUses3.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        // Check grouping is the child of module.
+        YangGrouping yangGrouping3 = (YangGrouping) node.getChild();
+
+        ListIterator<YangLeaf> leafIterator;
+        YangLeaf leafInfo;
+        leafIterator = yangGrouping3.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under grouping.
+        assertThat(leafInfo.getName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+
+    }
+
+    /**
+     * Checks self resolution when some type uses prefix of self module
+     * some uses external prefix.
+     */
+    @Test
+    public void processSelfFileLinkingWithGroupingWithSelfAndExternalPrefixMix()
+            throws IOException, ParserException {
+
+        YangNode node = manager
+                .getDataModel("src/test/resources/SelfFileLinkingWithGroupingWithSelfAndExternalPrefixMix.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat((node instanceof YangModule), is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        // Check whether container is the sibling of grouping.
+        YangContainer yangContainer = (YangContainer) node.getChild().getNextSibling();
+
+        // Check whether list is the child of container.
+        YangList yangList = (YangList) yangContainer.getChild();
+
+        // Check whether uses is the child of list.
+        assertThat((yangList.getChild() instanceof YangUses), is(true));
+        YangUses yangUses1 = (YangUses) yangList.getChild();
+        assertThat(yangUses1.getName(), is("FirstClass"));
+
+        // Check whether uses is getting resolved.
+        assertThat(yangUses1.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        // Check whether grouping is the sibling of uses.
+        YangGrouping yangGrouping1 = (YangGrouping) yangUses1.getNextSibling();
+        assertThat(yangGrouping1.getName(), is("FirstClass"));
+
+        // Check whether uses is the child of grouping which has prefix from other module.
+        YangUses yangUses2 = (YangUses) yangGrouping1.getChild();
+        assertThat(yangUses2.getName(), is("PassingClass"));
+
+        // Check whether uses gets intra-file-resolved.
+        assertThat(yangUses2.getResolvableStatus(),
+                is(ResolvableStatus.INTRA_FILE_RESOLVED));
+
+        // Check whether grouping is the sibling of list.
+        YangGrouping yangGrouping2 = (YangGrouping) yangList.getNextSibling();
+        assertThat(yangGrouping2.getName(), is("PassingClass"));
+
+        // Check uses is the child of that grouping which has prefix of the same module.
+        YangUses yangUses3 = (YangUses) yangGrouping2.getChild();
+        assertThat(yangUses3.getName(), is("Percentage"));
+
+        // Check uses is getting resolved.
+        assertThat(yangUses3.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        // Check grouping is the child of module.
+        YangGrouping yangGrouping3 = (YangGrouping) node.getChild();
+        ListIterator<YangLeaf> leafIterator;
+        YangLeaf leafInfo;
+        leafIterator = yangGrouping3.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct under grouping.
+        assertThat(leafInfo.getName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
+    }
+
+}
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/NotificationTranslatorTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/NotificationTranslatorTest.java
new file mode 100644
index 0000000..2801adf
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/NotificationTranslatorTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.plugin.manager;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
+import org.onosproject.yangutils.utils.io.impl.YangPluginConfig;
+
+import static org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorUtil.generateJavaCode;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
+
+/**
+ * Unit tests for union translator.
+ */
+public final class NotificationTranslatorTest {
+
+    private final YangUtilsParserManager manager = new YangUtilsParserManager();
+
+    /**
+     * Checks union translation should not result in any exception.
+     */
+    @Test
+    public void processUnionTranslator()
+            throws IOException, ParserException {
+
+        String userDir = System.getProperty("user.dir");
+        YangNode node = manager.getDataModel("src/test/resources/NotificationTest.yang");
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(userDir + "/target/NotificationTest/");
+
+        generateJavaCode(node, yangPluginConfig);
+
+        deleteDirectory(userDir + "/target/NotificationTest/");
+    }
+
+    // TODO enhance the test cases, after having a framework of translator test.
+}
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/RestrictionResolutionTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/RestrictionResolutionTest.java
new file mode 100644
index 0000000..9f27b06
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/RestrictionResolutionTest.java
@@ -0,0 +1,835 @@
+/*
+ * 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.plugin.manager;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.ListIterator;
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangPatternRestriction;
+import org.onosproject.yangutils.datamodel.YangRangeInterval;
+import org.onosproject.yangutils.datamodel.YangRangeRestriction;
+import org.onosproject.yangutils.datamodel.YangStringRestriction;
+import org.onosproject.yangutils.datamodel.YangTypeDef;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangInt32;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangUint64;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.INT32;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.STRING;
+import static org.onosproject.yangutils.datamodel.YangNodeType.MODULE_NODE;
+import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
+
+/**
+ * Test cases for testing restriction resolution.
+ */
+public final class RestrictionResolutionTest {
+
+    private final YangUtilsParserManager manager = new YangUtilsParserManager();
+
+    /**
+     * Checks length restriction in typedef.
+     */
+    @Test
+    public void processLengthRestrictionInTypedef()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/LengthRestrictionInTypedef.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangStringRestriction stringRestriction = (YangStringRestriction) derivedInfo.getResolvedExtendedInfo();
+        YangRangeRestriction lengthRestriction = stringRestriction.getLengthRestriction();
+
+        ListIterator<YangRangeInterval> lengthListIterator = lengthRestriction.getAscendingRangeIntervals()
+                .listIterator();
+
+        YangRangeInterval rangeInterval = lengthListIterator.next();
+
+        assertThat(((YangUint64) rangeInterval.getStartValue()).getValue(), is(BigInteger.valueOf(0)));
+        assertThat(((YangUint64) rangeInterval.getEndValue()).getValue(), is(BigInteger.valueOf(100)));
+    }
+
+    /**
+     * Checks length restriction in referred type.
+     */
+    @Test
+    public void processLengthRestrictionInRefType()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/LengthRestrictionInRefType.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(notNullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangStringRestriction stringRestriction = (YangStringRestriction) derivedInfo.getResolvedExtendedInfo();
+        YangRangeRestriction lengthRestriction = stringRestriction.getLengthRestriction();
+
+        ListIterator<YangRangeInterval> lengthListIterator = lengthRestriction.getAscendingRangeIntervals()
+                .listIterator();
+
+        YangRangeInterval rangeInterval = lengthListIterator.next();
+
+        assertThat(((YangUint64) rangeInterval.getStartValue()).getValue(), is(BigInteger.valueOf(0)));
+        assertThat(((YangUint64) rangeInterval.getEndValue()).getValue(), is(BigInteger.valueOf(100)));
+    }
+
+    /**
+     * Checks length restriction in typedef and in type with stricter value.
+     */
+    @Test
+    public void processLengthRestrictionInTypedefAndTypeValid()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/LengthRestrictionInTypedefAndTypeValid.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(notNullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangStringRestriction stringRestriction = (YangStringRestriction) derivedInfo.getResolvedExtendedInfo();
+        YangRangeRestriction lengthRestriction = stringRestriction.getLengthRestriction();
+
+        ListIterator<YangRangeInterval> lengthListIterator = lengthRestriction.getAscendingRangeIntervals()
+                .listIterator();
+
+        YangRangeInterval rangeInterval1 = lengthListIterator.next();
+
+        assertThat(((YangUint64) rangeInterval1.getStartValue()).getValue(), is(BigInteger.valueOf(0)));
+        assertThat(((YangUint64) rangeInterval1.getEndValue()).getValue(), is(BigInteger.valueOf(20)));
+
+        YangRangeInterval rangeInterval2 = lengthListIterator.next();
+
+        assertThat(((YangUint64) rangeInterval2.getStartValue()).getValue(), is(BigInteger.valueOf(201)));
+        assertThat(((YangUint64) rangeInterval2.getEndValue()).getValue(), is(BigInteger.valueOf(300)));
+    }
+
+    /**
+     * Checks length restriction in typedef and in type with not stricter value.
+     */
+    @Test(expected = LinkerException.class)
+    public void processLengthRestrictionInTypedefAndTypeInValid()
+            throws IOException, DataModelException {
+        YangNode node = manager.getDataModel("src/test/resources/LengthRestrictionInTypedefAndTypeInValid.yang");
+    }
+
+    /**
+     * Checks range restriction in typedef.
+     */
+    @Test
+    public void processRangeRestrictionInTypedef()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/RangeRestrictionInTypedef.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(INT32));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangRangeRestriction rangeRestriction = (YangRangeRestriction) derivedInfo.getResolvedExtendedInfo();
+
+        ListIterator<YangRangeInterval> rangeListIterator = rangeRestriction.getAscendingRangeIntervals()
+                .listIterator();
+
+        YangRangeInterval rangeInterval1 = rangeListIterator.next();
+
+        assertThat(((YangInt32) rangeInterval1.getStartValue()).getValue(), is(1));
+        assertThat(((YangInt32) rangeInterval1.getEndValue()).getValue(), is(4));
+
+        YangRangeInterval rangeInterval2 = rangeListIterator.next();
+
+        assertThat(((YangInt32) rangeInterval2.getStartValue()).getValue(), is(10));
+        assertThat(((YangInt32) rangeInterval2.getEndValue()).getValue(), is(20));
+    }
+
+    /**
+     * Checks range restriction in referred type.
+     */
+    @Test
+    public void processRangeRestrictionInRefType()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/RangeRestrictionInRefType.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(INT32));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(notNullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangRangeRestriction rangeRestriction = (YangRangeRestriction) derivedInfo.getResolvedExtendedInfo();
+
+        ListIterator<YangRangeInterval> rangeListIterator = rangeRestriction.getAscendingRangeIntervals()
+                .listIterator();
+
+        YangRangeInterval rangeInterval1 = rangeListIterator.next();
+
+        assertThat(((YangInt32) rangeInterval1.getStartValue()).getValue(), is(1));
+        assertThat(((YangInt32) rangeInterval1.getEndValue()).getValue(), is(4));
+
+        YangRangeInterval rangeInterval2 = rangeListIterator.next();
+
+        assertThat(((YangInt32) rangeInterval2.getStartValue()).getValue(), is(10));
+        assertThat(((YangInt32) rangeInterval2.getEndValue()).getValue(), is(20));
+    }
+
+    /**
+     * Checks range restriction in typedef and stricter in referred type.
+     */
+    @Test
+    public void processRangeRestrictionInRefTypeAndTypedefValid()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/RangeRestrictionInRefTypeAndTypedefValid.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(INT32));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(notNullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangRangeRestriction rangeRestriction = (YangRangeRestriction) derivedInfo.getResolvedExtendedInfo();
+
+        ListIterator<YangRangeInterval> rangeListIterator = rangeRestriction.getAscendingRangeIntervals()
+                .listIterator();
+
+        YangRangeInterval rangeInterval1 = rangeListIterator.next();
+
+        assertThat(((YangInt32) rangeInterval1.getStartValue()).getValue(), is(1));
+        assertThat(((YangInt32) rangeInterval1.getEndValue()).getValue(), is(4));
+
+        YangRangeInterval rangeInterval2 = rangeListIterator.next();
+
+        assertThat(((YangInt32) rangeInterval2.getStartValue()).getValue(), is(10));
+        assertThat(((YangInt32) rangeInterval2.getEndValue()).getValue(), is(20));
+    }
+
+    /**
+     * Checks range restriction in typedef and not stricter in referred type.
+     */
+    @Test(expected = LinkerException.class)
+    public void processRangeRestrictionInRefTypeAndTypedefInValid()
+            throws IOException, ParserException, DataModelException {
+        YangNode node = manager.getDataModel("src/test/resources/RangeRestrictionInRefTypeAndTypedefInValid.yang");
+    }
+
+    /**
+     * Checks range restriction for string.
+     */
+    @Test(expected = ParserException.class)
+    public void processRangeRestrictionInString()
+            throws IOException, ParserException, DataModelException {
+        YangNode node = manager.getDataModel("src/test/resources/RangeRestrictionInString.yang");
+    }
+
+    /**
+     * Checks range restriction for string in referred type.
+     */
+    @Test(expected = LinkerException.class)
+    public void processRangeRestrictionInStringInRefType()
+            throws IOException, DataModelException {
+        YangNode node = manager.getDataModel("src/test/resources/RangeRestrictionInStringInRefType.yang");
+    }
+
+    /**
+     * Checks pattern restriction in typedef.
+     */
+    @Test
+    public void processPatternRestrictionInTypedef()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/PatternRestrictionInTypedef.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(nullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangStringRestriction stringRestriction = (YangStringRestriction) derivedInfo.getResolvedExtendedInfo();
+        YangPatternRestriction patternRestriction = stringRestriction.getPatternRestriction();
+
+        ListIterator<String> patternListIterator = patternRestriction.getPatternList().listIterator();
+        String pattern1 = patternListIterator.next();
+
+        assertThat(pattern1, is("[a-zA-Z]"));
+    }
+
+    /**
+     * Checks pattern restriction in referred type.
+     */
+    @Test
+    public void processPatternRestrictionInRefType()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/PatternRestrictionInRefType.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(notNullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangStringRestriction stringRestriction = (YangStringRestriction) derivedInfo.getResolvedExtendedInfo();
+        YangPatternRestriction patternRestriction = stringRestriction.getPatternRestriction();
+
+        ListIterator<String> patternListIterator = patternRestriction.getPatternList().listIterator();
+        String pattern1 = patternListIterator.next();
+
+        assertThat(pattern1, is("[a-zA-Z]"));
+    }
+
+    /**
+     * Checks pattern restriction in referred type and typedef.
+     */
+    @Test
+    public void processPatternRestrictionInRefTypeAndTypedef()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/PatternRestrictionInRefTypeAndTypedef.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(notNullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangStringRestriction stringRestriction = (YangStringRestriction) derivedInfo.getResolvedExtendedInfo();
+        YangPatternRestriction patternRestriction = stringRestriction.getPatternRestriction();
+
+        ListIterator<String> patternListIterator = patternRestriction.getPatternList().listIterator();
+        String pattern1 = patternListIterator.next();
+
+        assertThat(pattern1, is("[a-zA-Z]"));
+
+        String pattern2 = patternListIterator.next();
+
+        assertThat(pattern2, is("[0-9]"));
+    }
+
+    /**
+     * Checks multiple pattern restriction in referred type and typedef.
+     */
+    @Test
+    public void processMultiplePatternRestriction()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/MultiplePatternRestrictionInRefTypeAndTypedef.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(notNullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangStringRestriction stringRestriction = (YangStringRestriction) derivedInfo.getResolvedExtendedInfo();
+        YangPatternRestriction patternRestriction = stringRestriction.getPatternRestriction();
+
+        ListIterator<String> patternListIterator = patternRestriction.getPatternList().listIterator();
+        String pattern1 = patternListIterator.next();
+
+        assertThat(pattern1, is("[a-z]"));
+
+        String pattern2 = patternListIterator.next();
+
+        assertThat(pattern2, is("[A-Z]"));
+
+        String pattern3 = patternListIterator.next();
+
+        assertThat(pattern3, is("[0-9]"));
+
+        String pattern4 = patternListIterator.next();
+
+        assertThat(pattern4, is("[\\n]"));
+    }
+
+    /**
+     * Checks multiple pattern and length restriction in referred type and
+     * typedef.
+     */
+    @Test
+    public void processMultiplePatternAndLengthRestriction()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/MultiplePatternAndLengthRestriction.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(notNullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(notNullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangStringRestriction stringRestriction = (YangStringRestriction) derivedInfo.getResolvedExtendedInfo();
+
+        // Check for pattern restriction.
+        YangPatternRestriction patternRestriction = stringRestriction.getPatternRestriction();
+        ListIterator<String> patternListIterator = patternRestriction.getPatternList().listIterator();
+        String pattern1 = patternListIterator.next();
+
+        assertThat(pattern1, is("[a-z]"));
+
+        String pattern2 = patternListIterator.next();
+
+        assertThat(pattern2, is("[A-Z]"));
+
+        String pattern3 = patternListIterator.next();
+
+        assertThat(pattern3, is("[0-9]"));
+
+        String pattern4 = patternListIterator.next();
+
+        assertThat(pattern4, is("[\\n]"));
+
+        // Check for length restriction.
+        YangRangeRestriction lengthRestriction = stringRestriction.getLengthRestriction();
+        ListIterator<YangRangeInterval> lengthListIterator = lengthRestriction.getAscendingRangeIntervals()
+                .listIterator();
+
+        YangRangeInterval rangeInterval1 = lengthListIterator.next();
+
+        assertThat(((YangUint64) rangeInterval1.getStartValue()).getValue(), is(BigInteger.valueOf(0)));
+        assertThat(((YangUint64) rangeInterval1.getEndValue()).getValue(), is(BigInteger.valueOf(20)));
+
+        YangRangeInterval rangeInterval2 = lengthListIterator.next();
+
+        assertThat(((YangUint64) rangeInterval2.getStartValue()).getValue(), is(BigInteger.valueOf(201)));
+        assertThat(((YangUint64) rangeInterval2.getEndValue()).getValue(), is(BigInteger.valueOf(300)));
+    }
+
+    /**
+     * Checks multiple pattern and length restriction in referred type and
+     * typedef.
+     */
+    @Test
+    public void processMultiplePatternAndLengthRestrictionValid()
+            throws IOException, ParserException, DataModelException {
+
+        YangNode node = manager.getDataModel("src/test/resources/MultiplePatternAndLengthRestrictionValid.yang");
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(node instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(node.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) node;
+        assertThat(yangNode.getName(), is("Test"));
+
+        ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("invalid-interval"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("hello"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef(),
+                is((YangTypeDef) node.getChild()));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        // Check for the restriction.
+        assertThat(derivedInfo.getLengthRestrictionString(), is(notNullValue()));
+        assertThat(derivedInfo.getRangeRestrictionString(), is(nullValue()));
+        assertThat(derivedInfo.getPatternRestriction(), is(notNullValue()));
+        assertThat(derivedInfo.getResolvedExtendedInfo(), is(notNullValue()));
+
+        // Check for the restriction value.
+        YangStringRestriction stringRestriction = (YangStringRestriction) derivedInfo.getResolvedExtendedInfo();
+
+        // Check for pattern restriction.
+        YangPatternRestriction patternRestriction = stringRestriction.getPatternRestriction();
+        ListIterator<String> patternListIterator = patternRestriction.getPatternList().listIterator();
+        String pattern1 = patternListIterator.next();
+
+        assertThat(pattern1, is("[a-z]"));
+
+        String pattern2 = patternListIterator.next();
+
+        assertThat(pattern2, is("[A-Z]"));
+
+        String pattern3 = patternListIterator.next();
+
+        assertThat(pattern3, is("[0-9]"));
+
+        String pattern4 = patternListIterator.next();
+
+        assertThat(pattern4, is("[\\n]"));
+
+        // Check for length restriction.
+        YangRangeRestriction lengthRestriction = stringRestriction.getLengthRestriction();
+        ListIterator<YangRangeInterval> lengthListIterator = lengthRestriction.getAscendingRangeIntervals()
+                .listIterator();
+
+        YangRangeInterval rangeInterval1 = lengthListIterator.next();
+
+        assertThat(((YangUint64) rangeInterval1.getStartValue()).getValue(), is(BigInteger.valueOf(0)));
+        assertThat(((YangUint64) rangeInterval1.getEndValue()).getValue(), is(BigInteger.valueOf(20)));
+
+        YangRangeInterval rangeInterval2 = lengthListIterator.next();
+
+        assertThat(((YangUint64) rangeInterval2.getStartValue()).getValue(), is(BigInteger.valueOf(100)));
+        assertThat(((YangUint64) rangeInterval2.getEndValue()).getValue(),
+                is(new BigInteger("18446744073709551615")));
+    }
+
+    /**
+     * Checks multiple pattern and length restriction in referred type and
+     * typedef invalid scenario.
+     */
+    @Test(expected = LinkerException.class)
+    public void processMultiplePatternAndLengthRestrictionInValid()
+            throws IOException, DataModelException {
+        YangNode node = manager.getDataModel("src/test/resources/MultiplePatternAndLengthRestrictionInValid.yang");
+    }
+}
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/RpcTranslatorTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/RpcTranslatorTest.java
new file mode 100644
index 0000000..8f8b157
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/RpcTranslatorTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.plugin.manager;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
+import org.onosproject.yangutils.utils.io.impl.YangPluginConfig;
+
+import static org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorUtil.generateJavaCode;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
+
+/**
+ * Unit tests for rpc translator.
+ */
+public final class RpcTranslatorTest {
+
+    private final YangUtilsParserManager manager = new YangUtilsParserManager();
+
+    /**
+     * Checks rpc translation should not result in any exception.
+     */
+    @Test
+    public void processRpcTranslator()
+            throws IOException, ParserException {
+
+        String userDir = System.getProperty("user.dir");
+        YangNode node = manager.getDataModel("src/test/resources/RpcTranslator.yang");
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(userDir + "/target/RpcTestGenFile/");
+
+        generateJavaCode(node, yangPluginConfig);
+
+        deleteDirectory(userDir + "/target/RpcTestGenFile/");
+    }
+    // TODO enhance the test cases, after having a framework of translator test.
+}
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/UnionTranslatorTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/UnionTranslatorTest.java
new file mode 100644
index 0000000..7682d19
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/UnionTranslatorTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.plugin.manager;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
+import org.onosproject.yangutils.utils.io.impl.YangPluginConfig;
+
+import static org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorUtil.generateJavaCode;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
+
+/**
+ * Unit tests for union translator.
+ */
+public final class UnionTranslatorTest {
+
+    private final YangUtilsParserManager manager = new YangUtilsParserManager();
+
+    /**
+     * Checks union translation should not result in any exception.
+     */
+    @Test
+    public void processUnionTranslator()
+            throws IOException, ParserException {
+
+        String userDir = System.getProperty("user.dir");
+        YangNode node = manager.getDataModel("src/test/resources/UnionTranslator.yang");
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir("target/UnionTestGenFile/");
+
+        generateJavaCode(node, yangPluginConfig);
+
+        deleteDirectory(userDir + "/target/UnionTestGenFile/");
+    }
+
+    // TODO enhance the test cases, after having a framework of translator test.
+}
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/YangPluginUtilsTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/YangPluginUtilsTest.java
new file mode 100644
index 0000000..a6e2e08
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/YangPluginUtilsTest.java
@@ -0,0 +1,33 @@
+package org.onosproject.yangutils.plugin.manager;
+
+import java.io.File;
+import java.io.IOException;
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.project.MavenProject;
+import org.junit.Test;
+import org.sonatype.plexus.build.incremental.BuildContext;
+import org.sonatype.plexus.build.incremental.DefaultBuildContext;
+
+import static org.onosproject.yangutils.plugin.manager.YangPluginUtils.addToCompilationRoot;
+
+/**
+ * Created by root1 on 16/6/16.
+ */
+public class YangPluginUtilsTest {
+
+    private static final String BASE_DIR = "target/UnitTestCase";
+
+    /**
+     * This test case checks whether the source is getting added.
+     */
+    @Test
+    public void testForAddSource() throws IOException {
+
+        MavenProject project = new MavenProject();
+        BuildContext context = new DefaultBuildContext();
+        File sourceDir = new File(BASE_DIR + File.separator + "yang");
+        sourceDir.mkdirs();
+        addToCompilationRoot(sourceDir.toString(), project, context);
+        FileUtils.deleteDirectory(sourceDir);
+    }
+}
