diff --git a/src/main/java/org/onosproject/yangutils/utils/io/impl/FileSystemUtil.java b/src/main/java/org/onosproject/yangutils/utils/io/impl/FileSystemUtil.java
index f7e3556..58dfb69 100644
--- a/src/main/java/org/onosproject/yangutils/utils/io/impl/FileSystemUtil.java
+++ b/src/main/java/org/onosproject/yangutils/utils/io/impl/FileSystemUtil.java
@@ -45,13 +45,16 @@
      * @param pkg Package to check if it is created.
      * @return existence status of package.
      */
-    public static boolean doesPackageExist(File pkg) {
-        if (pkg.exists()) {
+    public static boolean doesPackageExist(String pkg) {
+        File pkgDir = new File(pkg.replace(UtilConstants.PERIOD, UtilConstants.SLASH));
+        File pkgWithFile = new File(pkgDir + File.separator + "package-info.java");
+        if (pkgDir.exists() && pkgWithFile.isFile()) {
             return true;
         }
         return false;
     }
 
+
     /**
      * Create a package structure with package info java file if not present.
      *
@@ -60,7 +63,7 @@
      * @throws IOException any IO exception
      */
     public static void createPackage(String pkg, String pkgInfo) throws IOException {
-        if (!doesPackageExist(new File(pkg))) {
+        if (!doesPackageExist(pkg)) {
             try {
                 File pack = YangIoUtils
                         .createDirectories(pkg.replace(UtilConstants.PERIOD, UtilConstants.SLASH));
@@ -82,9 +85,6 @@
      */
     public static CachedFileHandle createSourceFiles(String pkg, String yangName, GeneratedFileType types)
             throws IOException {
-        //if (!doesPackageExist(new File(pkg))) {
-        //    throw new IOException("package does not exist.");
-        //}
         yangName = JavaIdentifierSyntax.getCamelCase(yangName);
         CachedFileHandle handler = new CachedJavaFileHandle(pkg, yangName, types);
 
@@ -104,7 +104,6 @@
     public static void appendFileContents(File toAppend, File srcFile) throws IOException {
 
         insertStringInFile(srcFile, UtilConstants.NEW_LINE + readAppendFile(toAppend.toString()));
-        //TODO: read the contents from src file and append its contents to append file.
         return;
     }
 
diff --git a/src/main/java/org/onosproject/yangutils/utils/io/impl/JavaDocGen.java b/src/main/java/org/onosproject/yangutils/utils/io/impl/JavaDocGen.java
index 826eb7b..19a130e 100644
--- a/src/main/java/org/onosproject/yangutils/utils/io/impl/JavaDocGen.java
+++ b/src/main/java/org/onosproject/yangutils/utils/io/impl/JavaDocGen.java
@@ -114,7 +114,7 @@
             javaDoc = generateForDefaultConstructors();
         } else if (type.equals(JavaDocType.BUILD)) {
             javaDoc = generateForBuild(name);
-        } else if (type.equals(JavaDocType.CONSTRUCTOR)) {
+        } else {
             javaDoc = generateForConstructors(name);
         }
         return javaDoc;
diff --git a/src/main/java/org/onosproject/yangutils/utils/io/impl/SerializedDataStore.java b/src/main/java/org/onosproject/yangutils/utils/io/impl/SerializedDataStore.java
index d9d3732..9ceb50f 100644
--- a/src/main/java/org/onosproject/yangutils/utils/io/impl/SerializedDataStore.java
+++ b/src/main/java/org/onosproject/yangutils/utils/io/impl/SerializedDataStore.java
@@ -19,6 +19,7 @@
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -107,6 +108,11 @@
     private static final String SERIALIZE_FILE_EXTENSION = ".ser";
 
     /**
+     * Directory for generating Serialized files.
+     */
+    private static final String GEN_DIR = "target/";
+
+    /**
      * Buffer size.
      */
     private static final int BUFFER_SIZE = 8 * 1024;
@@ -137,14 +143,12 @@
             fileName = BUILDER_METHOD_FILE_NAME;
         } else if (type.equals(SerializedDataStoreType.IMPL_METHODS)) {
             fileName = IMPL_METHOD_FILE_NAME;
-        } else if (type.equals(SerializedDataStoreType.IMPORT)) {
-            fileName = IMPORT_FILE_NAME;
         } else {
-            throw new IOException("Unresolved file type.");
+            fileName = IMPORT_FILE_NAME;
         }
 
         try {
-            OutputStream file = new FileOutputStream(fileName + SERIALIZE_FILE_EXTENSION);
+            OutputStream file = new FileOutputStream(GEN_DIR + fileName + SERIALIZE_FILE_EXTENSION);
             OutputStream buffer = new BufferedOutputStream(file, BUFFER_SIZE);
 
             ObjectOutput output = new ObjectOutputStream(buffer);
@@ -164,10 +168,11 @@
      * @param type type of serialized data store
      * @return list of attribute info.
      * @throws IOException when fails to read from the file.
-     * @throws ClassNotFoundException when file is missing.
+     * @throws ClassNotFoundException when class is missing.
+     * @throws FileNotFoundException when file is missing.
      */
     public static List<String> getSerializeData(SerializedDataStoreType type)
-            throws IOException, ClassNotFoundException {
+            throws IOException, FileNotFoundException, ClassNotFoundException {
 
         String fileName = "";
         if (type.equals(SerializedDataStoreType.ATTRIBUTE)) {
@@ -180,14 +185,11 @@
             fileName = BUILDER_METHOD_FILE_NAME;
         } else if (type.equals(SerializedDataStoreType.IMPL_METHODS)) {
             fileName = IMPL_METHOD_FILE_NAME;
-        } else if (type.equals(SerializedDataStoreType.IMPORT)) {
-            fileName = IMPORT_FILE_NAME;
         } else {
-            throw new IOException("Unresolved file type.");
+            fileName = IMPORT_FILE_NAME;
         }
-
         try {
-            InputStream file = new FileInputStream(fileName + SERIALIZE_FILE_EXTENSION);
+            InputStream file = new FileInputStream(GEN_DIR + fileName + SERIALIZE_FILE_EXTENSION);
             InputStream buffer = new BufferedInputStream(file);
             ObjectInput input = new ObjectInputStream(buffer);
             try {
@@ -199,6 +201,8 @@
                 input.close();
                 file.close();
             }
+        } catch (FileNotFoundException ex) {
+            throw new FileNotFoundException("No such file or directory.");
         } catch (ClassNotFoundException ex) {
             throw new ClassNotFoundException("failed to fetch the serialized data file.");
         }
diff --git a/src/main/java/org/onosproject/yangutils/utils/io/impl/YangFileScanner.java b/src/main/java/org/onosproject/yangutils/utils/io/impl/YangFileScanner.java
index a9006d2..1f8a159 100644
--- a/src/main/java/org/onosproject/yangutils/utils/io/impl/YangFileScanner.java
+++ b/src/main/java/org/onosproject/yangutils/utils/io/impl/YangFileScanner.java
@@ -33,31 +33,34 @@
     private YangFileScanner() {
     }
 
-    /**
-     * Returns the list of YANG files.
-     *
-     * @param root specified directory
-     * @return list of YANG files.
-     * @throws IOException when files get deleted while performing the
-     *             operations.
-     */
-    public static List<String> getYangFiles(String root) throws IOException {
-        return getFiles(root, ".yang");
-    }
 
     /**
      * Returns the list of java files.
      *
      * @param root specified directory
      * @return list of java files.
+     * @throws NullPointerException when no files are there.
      * @throws IOException when files get deleted while performing the
      *             operations.
      */
-    public static List<String> getJavaFiles(String root) throws IOException {
+    public static List<String> getJavaFiles(String root) throws NullPointerException, IOException {
         return getFiles(root, ".java");
     }
 
     /**
+     * Returns the list of YANG files.
+     *
+     * @param root specified directory
+     * @return list of YANG files.
+     * @throws NullPointerException when no files are there.
+     * @throws IOException when files get deleted while performing the
+     *             operations.
+     */
+    public static List<String> getYangFiles(String root) throws NullPointerException, IOException {
+        return getFiles(root, ".yang");
+    }
+
+    /**
      * Returns the list of required files.
      *
      * @param root specified directory
@@ -66,7 +69,7 @@
      * @throws IOException when files get deleted while performing the
      *             operations.
      */
-    public static List<String> getFiles(String root, String extension) throws IOException {
+    public static List<String> getFiles(String root, String extension) throws  NullPointerException, IOException {
         List<String> store = new LinkedList<>();
         Stack<String> stack = new Stack<>();
         stack.push(root);
@@ -77,7 +80,7 @@
                 root = stack.pop();
                 file = new File(root);
                 filelist = file.listFiles();
-                if (filelist == null) {
+                if (filelist.length == 0) {
                     continue;
                 }
                 for (File current : filelist) {
@@ -92,8 +95,8 @@
                 }
             }
             return store;
-        } catch (IOException e) {
-            throw new IOException("IOException occured");
+        } catch (NullPointerException e) {
+            throw new IOException("NullPointerException occured");
         }
     }
 }
diff --git a/src/main/java/org/onosproject/yangutils/utils/io/impl/YangIoUtils.java b/src/main/java/org/onosproject/yangutils/utils/io/impl/YangIoUtils.java
index 7f394db..8e97a7a 100644
--- a/src/main/java/org/onosproject/yangutils/utils/io/impl/YangIoUtils.java
+++ b/src/main/java/org/onosproject/yangutils/utils/io/impl/YangIoUtils.java
@@ -53,7 +53,7 @@
      */
     public static File createDirectories(String path) {
 
-        File generatedDir = new File(UtilConstants.YANG_GEN_DIR + File.separator + path);
+        File generatedDir = new File(path);
         generatedDir.mkdirs();
         return generatedDir;
     }
@@ -68,21 +68,23 @@
      */
     public static void addPackageInfo(File path, String classInfo, String pack) throws IOException {
 
+        if (pack.contains(UtilConstants.YANG_GEN_DIR)) {
+           String[] strArray = pack.split(UtilConstants.YANG_GEN_DIR + UtilConstants.SLASH);
+           pack = strArray[1];
+       }
+
         try {
 
             File packageInfo = new File(path + File.separator + "package-info.java");
             packageInfo.createNewFile();
-            if (packageInfo.exists()) {
-
-                FileWriter fileWriter = null;
-                BufferedWriter bufferedWriter = null;
-                fileWriter = new FileWriter(packageInfo);
-                bufferedWriter = new BufferedWriter(fileWriter);
-                bufferedWriter.write(CopyrightHeader.getCopyrightHeader());
-                bufferedWriter.write(JavaDocGen.getJavaDoc(JavaDocGen.JavaDocType.PACKAGE_INFO, classInfo));
-                bufferedWriter.write(UtilConstants.PACKAGE + UtilConstants.SPACE + pack + UtilConstants.SEMI_COLAN);
-                bufferedWriter.close();
-            }
+            FileWriter fileWriter = null;
+            BufferedWriter bufferedWriter = null;
+            fileWriter = new FileWriter(packageInfo);
+            bufferedWriter = new BufferedWriter(fileWriter);
+            bufferedWriter.write(CopyrightHeader.getCopyrightHeader());
+            bufferedWriter.write(JavaDocGen.getJavaDoc(JavaDocGen.JavaDocType.PACKAGE_INFO, classInfo));
+            bufferedWriter.write(UtilConstants.PACKAGE + UtilConstants.SPACE + pack + UtilConstants.SEMI_COLAN);
+            bufferedWriter.close();
         } catch (IOException e) {
             throw new IOException("Exception occured while creating package info file.");
         }
diff --git a/src/test/java/org/onosproject/yangutils/utils/UtilConstantsTest.java b/src/test/java/org/onosproject/yangutils/utils/UtilConstantsTest.java
new file mode 100644
index 0000000..347dfdb
--- /dev/null
+++ b/src/test/java/org/onosproject/yangutils/utils/UtilConstantsTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2016 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.utils;
+
+import org.junit.Test;
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Test case for testing the util constants.
+ */
+public final class UtilConstantsTest {
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    /**
+     * A private constructor is tested.
+     *
+     * @throws SecurityException if any security violation is observed.
+     * @throws NoSuchMethodException if when the method is not found.
+     * @throws IllegalArgumentException if there is illegal argument found.
+     * @throws InstantiationException if instantiation is provoked for the private constructor.
+     * @throws IllegalAccessException if instance is provoked or a method is provoked.
+     * @throws InvocationTargetException when an exception occurs by the method or constructor.
+     */
+    @Test
+    public void callPrivateConstructors() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
+    InstantiationException, IllegalAccessException, InvocationTargetException {
+
+        Class<?>[] classesToConstruct = {UtilConstants.class};
+        for (Class<?> clazz : classesToConstruct) {
+            Constructor<?> constructor = clazz.getDeclaredConstructor();
+            constructor.setAccessible(true);
+            assertNotNull(constructor.newInstance());
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/onosproject/yangutils/utils/io/impl/CopyrightHeaderTest.java b/src/test/java/org/onosproject/yangutils/utils/io/impl/CopyrightHeaderTest.java
new file mode 100644
index 0000000..032c483
--- /dev/null
+++ b/src/test/java/org/onosproject/yangutils/utils/io/impl/CopyrightHeaderTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2016 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.utils.io.impl;
+
+import org.junit.Test;
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertNotNull;
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Unit Tests for the CopyrightHeader contents.
+ */
+public final class CopyrightHeaderTest {
+
+    private final Logger log = getLogger(getClass());
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    /**
+     * Unit test for testing private constructor.
+     *
+     * @throws SecurityException if any security violation is observed.
+     * @throws NoSuchMethodException if when the method is not found.
+     * @throws IllegalArgumentException if there is illegal argument found.
+     * @throws InstantiationException if instantiation is provoked for the private constructor.
+     * @throws IllegalAccessException if instance is provoked or a method is provoked.
+     * @throws InvocationTargetException when an exception occurs by the method or constructor.
+     */
+    @Test
+    public void callPrivateConstructors() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
+    InstantiationException, IllegalAccessException, InvocationTargetException {
+
+        Class<?>[] classesToConstruct = {CopyrightHeader.class };
+        for (Class<?> clazz : classesToConstruct) {
+            Constructor<?> constructor = clazz.getDeclaredConstructor();
+            constructor.setAccessible(true);
+            assertNotNull(constructor.newInstance());
+        }
+    }
+
+    /**
+     * This test case checks the received copyright header contents.
+     */
+    @Test
+    public void testGetCopyrightHeader() throws IOException {
+
+        CopyrightHeader.parseCopyrightHeader();
+        String licenseHeader = CopyrightHeader.getCopyrightHeader();
+        ClassLoader classLoader = CopyrightHeaderTest.class.getClassLoader();
+        File test = new File("target/TestCopyrightHeader.txt");
+
+        FileWriter out = new FileWriter(test);
+        out.write(licenseHeader);
+        out.close();
+
+        File temp = new File("target/temp.txt");
+        InputStream stream = classLoader.getResourceAsStream("CopyrightHeader.txt");
+        OutputStream outStream = new FileOutputStream(temp);
+        int i;
+        while ((i = stream.read()) != -1) {
+            outStream.write(i);
+        }
+        outStream.close();
+        stream.close();
+
+        BufferedReader br1 = new BufferedReader(new FileReader(test));
+        BufferedReader br2 = new BufferedReader(new FileReader(temp));
+        while (br1.readLine() != null && br2.readLine() != null) {
+            assertThat(true, is((br1.readLine()).equals(br2.readLine())));
+        }
+        br1.close();
+        br2.close();
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/onosproject/yangutils/utils/io/impl/FileSystemUtilTest.java b/src/test/java/org/onosproject/yangutils/utils/io/impl/FileSystemUtilTest.java
new file mode 100644
index 0000000..531e739
--- /dev/null
+++ b/src/test/java/org/onosproject/yangutils/utils/io/impl/FileSystemUtilTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2016 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.utils.io.impl;
+
+import org.junit.Test;
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+import org.onosproject.yangutils.translator.GeneratedFileType;
+import org.onosproject.yangutils.utils.UtilConstants;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * Tests the file handle utilities.
+ */
+public final class FileSystemUtilTest {
+
+    public static String baseDirPkg = "target.UnitTestCase.";
+    public static String packageInfoContent = "testGeneration6";
+    public static String baseDir = "target/UnitTestCase";
+
+    private final Logger log = getLogger(getClass());
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    /**
+     * A private constructor is tested.
+     *
+     * @throws SecurityException if any security violation is observed.
+     * @throws NoSuchMethodException if when the method is not found.
+     * @throws IllegalArgumentException if there is illegal argument found.
+     * @throws InstantiationException if instantiation is provoked for the private constructor.
+     * @throws IllegalAccessException if instance is provoked or a method is provoked.
+     * @throws InvocationTargetException when an exception occurs by the method or constructor.
+     */
+    @Test
+    public void callPrivateConstructors() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
+    InstantiationException, IllegalAccessException, InvocationTargetException {
+
+        Class<?>[] classesToConstruct = {FileSystemUtil.class};
+        for (Class<?> clazz : classesToConstruct) {
+            Constructor<?> constructor = clazz.getDeclaredConstructor();
+            constructor.setAccessible(true);
+            assertNotNull(constructor.newInstance());
+        }
+    }
+
+    /**
+     * This test case checks the creation of source files.
+     */
+    @Test
+    public void createSourceFilesTest() throws IOException {
+
+        FileSystemUtil.createSourceFiles(baseDirPkg + "srcFile1", packageInfoContent, GeneratedFileType.INTERFACE);
+    }
+
+    /**
+     * This test case checks the contents to be written in the file.
+     */
+    @Test
+    public void insertStringInFileTest() throws IOException {
+        File dir = new File(baseDir + File.separator + "File1");
+        dir.mkdirs();
+        File createFile = new File(dir + "testFile");
+        createFile.createNewFile();
+        File createSourceFile = new File(dir + "sourceTestFile");
+        createSourceFile.createNewFile();
+        FileSystemUtil.insertStringInFile(createFile, "This is to append a text to the file first1\n");
+        FileSystemUtil.insertStringInFile(createFile, "This is next second line\n");
+        FileSystemUtil.insertStringInFile(createFile, "This is next third line in the file");
+        FileSystemUtil.appendFileContents(createFile, createSourceFile);
+    }
+
+    /**
+     * This test  case checks whether the package is existing.
+     */
+    @Test
+    public void packageExistTest() throws IOException {
+        String dirPath = "exist1.exist2.exist3";
+        String strPath = baseDirPkg + dirPath;
+        File createDir = new File(strPath.replace(UtilConstants.PERIOD, UtilConstants.SLASH));
+        createDir.mkdirs();
+        File createFile = new File(createDir + File.separator + "package-info.java");
+        createFile.createNewFile();
+        assertTrue(FileSystemUtil.doesPackageExist(strPath));
+        FileSystemUtil.createPackage(strPath, packageInfoContent);
+        createDir.delete();
+    }
+
+    /**
+     * This test case checks the package does not exist.
+     */
+    @Test
+    public void packageNotExistTest() throws IOException {
+        String dirPath = "notexist1.notexist2";
+        String strPath = baseDirPkg + dirPath;
+        File createDir = new File(strPath.replace(UtilConstants.PERIOD, UtilConstants.SLASH));
+        assertFalse(FileSystemUtil.doesPackageExist(strPath));
+        createDir.mkdirs();
+        assertFalse(FileSystemUtil.doesPackageExist(strPath));
+        CopyrightHeader.parseCopyrightHeader();
+        FileSystemUtil.createPackage(strPath, packageInfoContent);
+        assertTrue(FileSystemUtil.doesPackageExist(strPath));
+        createDir.delete();
+    }
+}
diff --git a/src/test/java/org/onosproject/yangutils/utils/io/impl/JavaDocGenTest.java b/src/test/java/org/onosproject/yangutils/utils/io/impl/JavaDocGenTest.java
new file mode 100644
index 0000000..3e68770
--- /dev/null
+++ b/src/test/java/org/onosproject/yangutils/utils/io/impl/JavaDocGenTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2016 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.utils.io.impl;
+
+import org.junit.Test;
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+import org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Tests the java doc that is generated.
+ */
+public final class JavaDocGenTest {
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    /**
+     * This test case checks the content recieved for the builder class java doc.
+     */
+    @Test
+    public void builderClassGenerationTest() {
+
+        String builderClassJavaDoc = JavaDocGen.getJavaDoc(JavaDocType.BUILDER_CLASS, "testGeneration1");
+        assertTrue(builderClassJavaDoc.contains("Provides the builder implementation of")
+                && builderClassJavaDoc.contains(" */\n"));
+    }
+
+    /**
+     * This test case checks the content recieved for the builder interface ge java doc.
+     */
+    @Test
+    public void builderInterfaceGenerationTest() {
+
+        String builderInterfaceJavaDoc = JavaDocGen.getJavaDoc(JavaDocType.BUILDER_INTERFACE, "testGeneration1");
+        assertTrue(builderInterfaceJavaDoc.contains("Builder for") && builderInterfaceJavaDoc.contains(" */\n"));
+    }
+
+    /**
+     * This test case checks the content recieved for the build  java doc.
+     */
+    @Test
+    public void buildGenerationTest() {
+
+        String buildDoc = JavaDocGen.getJavaDoc(JavaDocType.BUILD, "testGeneration1");
+        assertTrue(buildDoc.contains("Builds object of") && buildDoc.contains(" */\n"));
+    }
+
+    /**
+     * A private constructor is tested.
+     *
+     * @throws SecurityException if any security violation is observed.
+     * @throws NoSuchMethodException if when the method is not found.
+     * @throws IllegalArgumentException if there is illegal argument found.
+     * @throws InstantiationException if instantiation is provoked for the private constructor.
+     * @throws IllegalAccessException if instance is provoked or a method is provoked.
+     * @throws InvocationTargetException when an exception occurs by the method or constructor.
+     */
+    @Test
+    public void callPrivateConstructors() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
+    InstantiationException, IllegalAccessException, InvocationTargetException {
+
+        Class<?>[] classesToConstruct = {JavaDocGen.class };
+        for (Class<?> clazz : classesToConstruct) {
+            Constructor<?> constructor = clazz.getDeclaredConstructor();
+            constructor.setAccessible(true);
+            assertNotNull(constructor.newInstance());
+        }
+    }
+
+    /**
+     * This test case checks the content recieved for the constructor java doc.
+     */
+    @Test
+    public void constructorGenerationTest() {
+
+        String constructorDoc = JavaDocGen.getJavaDoc(JavaDocType.CONSTRUCTOR, "testGeneration1");
+        assertTrue(
+                constructorDoc.contains("Construct the object of") && constructorDoc.contains("builder object of")
+                && constructorDoc.contains("@param") && constructorDoc.contains("*/\n"));
+        JavaDocType.valueOf(JavaDocType.CONSTRUCTOR.toString());
+    }
+
+    /**
+     * This test case checks the content recieved for the default constructor java doc.
+     */
+    @Test
+    public void defaultConstructorGenerationTest() {
+
+        String defaultConstructorDoc = JavaDocGen.getJavaDoc(JavaDocType.DEFAULT_CONSTRUCTOR, "testGeneration1");
+        assertTrue(defaultConstructorDoc.contains("Default Constructor") && defaultConstructorDoc.contains(" */\n"));
+    }
+
+    /**
+     * This test case checks the content recieved for the getter java doc.
+     */
+    @Test
+    public void getterGenerationTest() {
+
+        String getterJavaDoc = JavaDocGen.getJavaDoc(JavaDocType.GETTER, "testGeneration1");
+        assertTrue(getterJavaDoc.contains("Returns the attribute") && getterJavaDoc.contains(" */\n"));
+    }
+
+    /**
+     * This test case checks the content recieved for the impl class java doc.
+     */
+    @Test
+    public void implClassGenerationTest() {
+        String implClassJavaDoc = JavaDocGen.getJavaDoc(JavaDocType.IMPL_CLASS, "testGeneration1");
+        assertTrue(implClassJavaDoc.contains("Provides the implementation of") && implClassJavaDoc.contains(" */\n"));
+    }
+
+    /**
+     * This test case checks the content recieved for the interface java doc.
+     */
+    @Test
+    public void interfaceGenerationTest() {
+
+        String interfaceJavaDoc = JavaDocGen.getJavaDoc(JavaDocType.INTERFACE, "testGeneration1");
+        assertTrue(interfaceJavaDoc.contains("Abstraction of an entity which provides functionalities of")
+                && interfaceJavaDoc.contains(" */\n"));
+    }
+
+    /**
+     * This test case checks the content recieved for the package info  java doc.
+     */
+    @Test
+    public void packageInfoGenerationTest() {
+
+        String packageInfo = JavaDocGen.getJavaDoc(JavaDocType.PACKAGE_INFO, "testGeneration1");
+        assertTrue(packageInfo.contains("Generated java code for the YANG file") && packageInfo.contains(" */\n"));
+    }
+
+    /**
+     * This test case checks the content recieved for the setter java doc.
+     */
+    @Test
+    public void setterGenerationTest() {
+
+        String setterJavaDoc = JavaDocGen.getJavaDoc(JavaDocType.SETTER, "testGeneration1");
+        assertTrue(setterJavaDoc.contains("Returns the builder object of") && setterJavaDoc.contains(" */\n"));
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/onosproject/yangutils/utils/io/impl/SerializedDataStoreTest.java b/src/test/java/org/onosproject/yangutils/utils/io/impl/SerializedDataStoreTest.java
new file mode 100644
index 0000000..154dcdd
--- /dev/null
+++ b/src/test/java/org/onosproject/yangutils/utils/io/impl/SerializedDataStoreTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2016 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.utils.io.impl;
+
+import org.junit.Test;
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+import org.onosproject.yangutils.utils.io.impl.SerializedDataStore.SerializedDataStoreType;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Unit tests for the serialized data store for its contents.
+ */
+public final class SerializedDataStoreTest {
+
+    private final Logger log = getLogger(getClass());
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    /**
+     * A private constructor is tested.
+     *
+     * @throws SecurityException if any security violation is observed.
+     * @throws NoSuchMethodException if when the method is not found.
+     * @throws IllegalArgumentException if there is illegal argument found.
+     * @throws InstantiationException if instantiation is provoked for the private constructor.
+     * @throws IllegalAccessException if instance is provoked or a method is provoked.
+     * @throws InvocationTargetException when an exception occurs by the method or constructor.
+     */
+    @Test
+    public void callPrivateConstructors() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
+    InstantiationException, IllegalAccessException, InvocationTargetException {
+
+        Class<?>[] classesToConstruct = {SerializedDataStore.class };
+        for (Class<?> clazz : classesToConstruct) {
+            Constructor<?> constructor = clazz.getDeclaredConstructor();
+            constructor.setAccessible(true);
+            assertNotNull(constructor.newInstance());
+        }
+    }
+
+    /**
+     * This test case checks the attribute info that is read and put into the list.
+     */
+    @Test
+    public void insertAttributeDataTest() throws IOException, ClassNotFoundException, FileNotFoundException {
+
+        String attributeData = "attribute content lists this";
+        SerializedDataStore.setSerializeData(attributeData, SerializedDataStoreType.ATTRIBUTE);
+        List<String> attributeInfo = SerializedDataStore.getSerializeData(SerializedDataStoreType.ATTRIBUTE);
+        List<String> expectedinfo = new LinkedList<>();
+        expectedinfo.add(attributeData);
+        assertThat(true, is(attributeInfo.equals(expectedinfo)));
+        SerializedDataStoreType.valueOf(SerializedDataStoreType.ATTRIBUTE.toString());
+    }
+
+    /**
+     * This test case checks the builder interface that is read and put into the list.
+     */
+    @Test
+    public void insertBuilderInterfaceMethodsTest() throws IOException, ClassNotFoundException, FileNotFoundException {
+
+        String builderInterfaceMethodsData = "builder interface methods content lists this";
+        SerializedDataStore.setSerializeData(builderInterfaceMethodsData,
+                SerializedDataStoreType.BUILDER_INTERFACE_METHODS);
+        List<String> attributeInfo = SerializedDataStore
+                .getSerializeData(SerializedDataStoreType.BUILDER_INTERFACE_METHODS);
+        List<String> expectedinfo = new LinkedList<>();
+        expectedinfo.add(builderInterfaceMethodsData);
+        assertThat(true, is(attributeInfo.equals(expectedinfo)));
+    }
+
+    /**
+     * This test case checks the builder methods that is read and put into the list.
+     */
+    @Test
+    public void insertBuilderMethodsTest() throws IOException, ClassNotFoundException, FileNotFoundException {
+
+        String builderMethodsData = "builder methods content lists this";
+        SerializedDataStore.setSerializeData(builderMethodsData, SerializedDataStoreType.BUILDER_METHODS);
+        List<String> attributeInfo = SerializedDataStore.getSerializeData(SerializedDataStoreType.BUILDER_METHODS);
+        List<String> expectedinfo = new LinkedList<>();
+        expectedinfo.add(builderMethodsData);
+        assertThat(true, is(attributeInfo.equals(expectedinfo)));
+    }
+
+    /**
+     * This test case checks the impl methods that is read and put into the list.
+     */
+    @Test
+    public void insertImplMethodsTest() throws IOException, ClassNotFoundException, FileNotFoundException {
+
+        String implMethodsData = "impl methods content lists this";
+        SerializedDataStore.setSerializeData(implMethodsData, SerializedDataStoreType.IMPL_METHODS);
+        List<String> attributeInfo = SerializedDataStore.getSerializeData(SerializedDataStoreType.IMPL_METHODS);
+        List<String> expectedinfo = new LinkedList<>();
+        expectedinfo.add(implMethodsData);
+        assertThat(true, is(attributeInfo.equals(expectedinfo)));
+    }
+
+    /**
+     * This test case checks the import methods that is read and put into the list.
+     */
+    @Test
+    public void insertImportTest() throws IOException, ClassNotFoundException, FileNotFoundException {
+
+        String importData = "interface methods content lists this";
+        SerializedDataStore.setSerializeData(importData, SerializedDataStoreType.IMPORT);
+        List<String> attributeInfo = SerializedDataStore.getSerializeData(SerializedDataStoreType.IMPORT);
+        List<String> expectedinfo = new LinkedList<>();
+        expectedinfo.add(importData);
+        assertThat(true, is(attributeInfo.equals(expectedinfo)));
+    }
+
+    /**
+     * This test case checks the interface methods that is read and put into the list.
+     */
+    @Test
+    public void insertInterfaceMethodsTest() throws IOException, ClassNotFoundException, FileNotFoundException {
+
+        String interfaceMethodsData = "interface methods content lists this";
+        SerializedDataStore.setSerializeData(interfaceMethodsData, SerializedDataStoreType.INTERFACE_METHODS);
+        List<String> attributeInfo = SerializedDataStore.getSerializeData(SerializedDataStoreType.INTERFACE_METHODS);
+        List<String> expectedinfo = new LinkedList<>();
+        expectedinfo.add(interfaceMethodsData);
+        assertThat(true, is(attributeInfo.equals(expectedinfo)));
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/onosproject/yangutils/utils/io/impl/YangFileScannerTest.java b/src/test/java/org/onosproject/yangutils/utils/io/impl/YangFileScannerTest.java
index 6ead5e3..6441b19 100644
--- a/src/test/java/org/onosproject/yangutils/utils/io/impl/YangFileScannerTest.java
+++ b/src/test/java/org/onosproject/yangutils/utils/io/impl/YangFileScannerTest.java
@@ -16,189 +16,80 @@
 
 package org.onosproject.yangutils.utils.io.impl;
 
+import org.junit.Test;
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.LinkedList;
+import java.util.List;
 import java.io.IOException;
 
-import org.junit.Test;
-import java.io.File;
-import java.util.List;
 import org.slf4j.Logger;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
- * Unit tests for searching yang files.
+ * Test the file scanner service.
  */
-public class YangFileScannerTest {
+public final class YangFileScannerTest {
 
     private final Logger log = getLogger(getClass());
 
-    private static final String BASEDIR = "target/UnitTestCase";
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    String baseDir = "target/UnitTestCase";
 
     /**
-     * Checks an empty directory.
+     * A private constructor is tested.
+     *
+     * @throws SecurityException if any security violation is observed.
+     * @throws NoSuchMethodException if when the method is not found.
+     * @throws IllegalArgumentException if there is illegal argument found.
+     * @throws InstantiationException if instantiation is provoked for the private constructor.
+     * @throws IllegalAccessException if instance is provoked or a method is provoked.
+     * @throws InvocationTargetException when an exception occurs by the method or constructor.
      */
     @Test
-    public void testWithSingleEmptyDirectoryInRoot() {
-        try {
-            File dir = new File(BASEDIR);
-            dir.mkdirs();
-            List<String> list = YangFileScanner.getYangFiles(BASEDIR.toString());
-        } catch (IOException e) {
-            log.info("IO Exception throwed");
+    public void callPrivateConstructors() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
+    InstantiationException, IllegalAccessException, InvocationTargetException {
+
+        Class<?>[] classesToConstruct = {YangFileScanner.class };
+        for (Class<?> clazz : classesToConstruct) {
+            Constructor<?> constructor = clazz.getDeclaredConstructor();
+            constructor.setAccessible(true);
+            assertNotNull(constructor.newInstance());
         }
     }
 
     /**
-     * Checks multiple empty directories in root directory.
+     * This test case checks for a .java file inside the specified dir.
      */
     @Test
-    public void testWithMultiEmptyDirectoriesInRoot() {
-        try {
-            String dir = "emptyDir";
-            String dir1 = "emptyDir1";
-            String dir2 = "emptyDir2";
-            String dir3 = "emptyDir3";
-            String dir4 = "emptyDir4";
-            File firstpath = createDirectory(dir);
-            File firstpath1 = createDirectory(dir1);
-            File firstpath2 = createDirectory(dir2);
-            File firstpath3 = createDirectory(dir3);
-            File firstpath4 = createDirectory(dir4);
-            List<String> list = YangFileScanner.getYangFiles(BASEDIR.toString());
-        } catch (IOException e) {
-            log.info("IO Exception throwed");
-        }
-    }
+    public void checkJavaFileInsideDirTest() throws IOException {
 
-    /**
-     * Checks one directory with one .yang file.
-     */
-    @Test
-    public void testWithSingleDirectorySingleFileInRoot() {
-        try {
-            String dir1 = "level1";
-            String firstFileName1 = "secondFile.yang";
-            File firstpath1 = createDirectory(dir1);
-            createFile(firstpath1, firstFileName1);
-            List<String> list = YangFileScanner.getYangFiles(BASEDIR.toString());
-        } catch (IOException e) {
-            log.info("IO Exception throwed");
-        }
-    }
-
-    /**
-     * Checks one directory with many .yang file.
-     */
-    @Test
-    public void testWithSingleDirectoryMultiFilesInRoot() {
-        try {
-            String dir2 = "level2";
-            String firstFileName2 = "thirdFile.yang";
-            String firstFileName3 = "fourthFile.yang";
-            String firstFileName4 = "fifthFile.yang";
-            String firstFileName5 = "sixthFile.yang";
-            File firstpath2 = createDirectory(dir2);
-            createFile(firstpath2, firstFileName2);
-            createFile(firstpath2, firstFileName3);
-            createFile(firstpath2, firstFileName4);
-            createFile(firstpath2, firstFileName5);
-            List<String> list = YangFileScanner.getYangFiles(BASEDIR.toString());
-        } catch (IOException e) {
-            log.info("IO Exception throwed");
-        }
-    }
-
-    /**
-     * Checks multi directories with many .yang file.
-     */
-    @Test
-    public void testWithMultiDirectoriesMultiFiles() {
-        try {
-            String dir2 = "newDir1/newDir2/newDir3/newDir4";
-            File dir3 = new File("target/UnitTestCase/newDir1");
-            File dir4 = new File("target/UnitTestCase/newDir1/newDir2");
-            File dir5 = new File("target/UnitTestCase/newDir1/newDir2/newDir3");
-            File dir6 = new File("target/UnitTestCase/newDir1/newDir2/newDir3/newDir4");
-            String firstFileName2 = "thirdFile.yang";
-            String firstFileName3 = "fourthFile.yang";
-            String firstFileName4 = "fifthFile.yang";
-            String firstFileName5 = "sixthFile.yang";
-            File firstpath2 = createDirectory(dir2);
-            createFile(firstpath2, firstFileName2);
-            createFile(firstpath2, firstFileName3);
-            createFile(firstpath2, firstFileName4);
-            createFile(dir3, firstFileName5);
-            createFile(dir3, firstFileName2);
-            createFile(dir3, firstFileName3);
-            createFile(dir3, firstFileName4);
-            createFile(dir3, firstFileName5);
-            createFile(dir4, firstFileName2);
-            createFile(dir4, firstFileName3);
-            createFile(dir4, firstFileName4);
-            createFile(dir4, firstFileName5);
-            createFile(dir5, firstFileName2);
-            createFile(dir5, firstFileName3);
-            createFile(dir5, firstFileName4);
-            createFile(dir5, firstFileName5);
-            createFile(dir6, firstFileName2);
-            createFile(dir6, firstFileName3);
-            createFile(dir6, firstFileName4);
-            createFile(dir6, firstFileName5);
-            List<String> list = YangFileScanner.getYangFiles(BASEDIR.toString());
-        } catch (IOException e) {
-            log.info("IO Exception throwed");
-        }
-    }
-
-    /**
-     * Checks multi directories with many .java file.
-     */
-    @Test
-    public void testWithMultiDirectoriesMultiJavaFiles() {
-        try {
-            String dir2 = "newDir1/newDir2/newDir3/newDir4";
-            File dir3 = new File("target/UnitTestCase/newDir1");
-            File dir4 = new File("target/UnitTestCase/newDir1/newDir2");
-            File dir5 = new File("target/UnitTestCase/newDir1/newDir2/newDir3");
-            File dir6 = new File("target/UnitTestCase/newDir1/newDir2/newDir3/newDir4");
-            String firstFileName2 = "thirdFile.java";
-            String firstFileName3 = "fourthFile.java";
-            String firstFileName4 = "fifthFile.java";
-            String firstFileName5 = "sixthFile.java";
-            File firstpath2 = createDirectory(dir2);
-            createFile(firstpath2, firstFileName2);
-            createFile(firstpath2, firstFileName3);
-            createFile(firstpath2, firstFileName4);
-            createFile(dir3, firstFileName5);
-            createFile(dir3, firstFileName2);
-            createFile(dir3, firstFileName3);
-            createFile(dir3, firstFileName4);
-            createFile(dir3, firstFileName5);
-            createFile(dir4, firstFileName2);
-            createFile(dir4, firstFileName3);
-            createFile(dir4, firstFileName4);
-            createFile(dir4, firstFileName5);
-            createFile(dir5, firstFileName2);
-            createFile(dir5, firstFileName3);
-            createFile(dir5, firstFileName4);
-            createFile(dir5, firstFileName5);
-            createFile(dir6, firstFileName2);
-            createFile(dir6, firstFileName3);
-            createFile(dir6, firstFileName4);
-            createFile(dir6, firstFileName5);
-            List<String> list = YangFileScanner.getJavaFiles(BASEDIR.toString());
-        } catch (IOException e) {
-            log.info("IO Exception throwed");
-        }
+        String dir = baseDir + File.separator + "scanner2";
+        File path = createDirectory(dir);
+        createFile(path, "testScanner.java");
+        List<String> dirContents = YangFileScanner.getJavaFiles(path.toString());
+        List<String> expectedContents = new LinkedList<>();
+        expectedContents.add(path.getCanonicalPath() + File.separator + "testScanner.java");
+        assertEquals(dirContents, expectedContents);
     }
 
     /**
      * Method used for creating multiple directories inside the target file.
      *
-     * @param path directory path
-     * @return directory path
+     * @param path where directories should be created.
+     * @return
      */
     public File createDirectory(String path) {
-        File myDir = new File(BASEDIR + File.separator + path);
+
+        File myDir = new File(path);
         myDir.mkdirs();
         return myDir;
     }
@@ -206,17 +97,71 @@
     /**
      * Method used for creating file inside the specified directory.
      *
-     * @param myDir my current dirctory
-     * @param fileName file name
-     * @throws IOException io exception when fails to create a file.
+     * @param myDir the path where file has to be created inside.
+     * @param fileName the name of the file to be created.
      */
     public void createFile(File myDir, String fileName) throws IOException {
+
         File file = null;
-        try {
-            file = new File(myDir + File.separator + fileName);
-            file.createNewFile();
-        } catch (final IOException e) {
-            throw new IOException("IOException occured");
-        }
+        file = new File(myDir + File.separator + fileName);
+        file.createNewFile();
     }
-}
+
+    /**
+     * This testcase checks for a java file inside an empty directory.
+     */
+    @Test
+    public void emptyDirJavaScannerTest() throws IOException {
+
+        String emptyDir = baseDir + File.separator + "scanner1";
+        File path = createDirectory(emptyDir);
+        List<String> emptyDirContents = YangFileScanner.getJavaFiles(path.toString());
+        List<String> expectedContents = new LinkedList<>();
+        assertEquals(emptyDirContents, expectedContents);
+    }
+
+    /**
+     * This testcase checks for a yang file inside an empty directory.
+     */
+    @Test
+    public void emptyDirYangScannerTest() throws IOException {
+
+        String emptyYangDir = baseDir + File.separator + "scanner1";
+        File path = createDirectory(emptyYangDir);
+        List<String> emptyDirContents = YangFileScanner.getYangFiles(path.toString());
+        List<String> expectedContents = new LinkedList<>();
+        assertEquals(emptyDirContents, expectedContents);
+    }
+
+    /**
+     * This test case checks with the sub directories in the given path for java files.
+     */
+    @Test
+    public void emptySubDirScannerTest() throws IOException {
+
+        String dir = baseDir + File.separator + "scanner3";
+        File path = createDirectory(dir);
+        String subDir = path.toString() + File.separator + "subDir1";
+        createDirectory(subDir);
+        createFile(path, "invalidFile.txt");
+        List<String> emptySubDirContents = YangFileScanner.getJavaFiles(path.toString());
+        List<String> expectedContents = new LinkedList<>();
+        assertEquals(emptySubDirContents, expectedContents);
+    }
+
+    /**
+     * This test case checks with the sub directories in the given path for java files.
+     */
+    @Test
+    public void exceptionHandleTest() throws IOException {
+
+        String dir = baseDir + File.separator + "scanner4";
+        thrown.expect(IOException.class);
+        thrown.expectMessage("NullPointerException occured");
+        List<String> invalidContents = YangFileScanner.getJavaFiles(dir);
+        File path = createDirectory(dir);
+        createFile(path, "except.java");
+        List<String> dirWithFileName = YangFileScanner
+                .getJavaFiles(path + File.separator + "except.java" + File.separator + "scanner5");
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/onosproject/yangutils/utils/io/impl/YangIoUtilsTest.java b/src/test/java/org/onosproject/yangutils/utils/io/impl/YangIoUtilsTest.java
new file mode 100644
index 0000000..a7e9860
--- /dev/null
+++ b/src/test/java/org/onosproject/yangutils/utils/io/impl/YangIoUtilsTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2016 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.utils.io.impl;
+
+import org.junit.Test;
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+import org.onosproject.yangutils.utils.UtilConstants;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.project.MavenProject;
+import org.sonatype.plexus.build.incremental.BuildContext;
+import org.sonatype.plexus.build.incremental.DefaultBuildContext;
+
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertNotNull;
+import static org.hamcrest.core.Is.is;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Unit tests for adding package-info, creating directories, cleaning the folder and to add sources.
+ */
+public final class YangIoUtilsTest {
+
+    public static String baseDir = "target/UnitTestCase";
+
+    public static String createPath = baseDir + File.separator + "dir1/dir2/dir3/dir4/";
+
+    private final Logger log = getLogger(getClass());
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    /**
+     * This test case checks whether the package-info file is created.
+     */
+    @Test
+    public void addPackageInfoTest() throws IOException {
+
+        File dirPath = new File(createPath);
+        dirPath.mkdirs();
+        CopyrightHeader.parseCopyrightHeader();
+        YangIoUtils.addPackageInfo(dirPath, "check1", createPath);
+        File filePath = new File(dirPath + File.separator + "package-info.java");
+        assertThat(filePath.isFile(), is(true));
+    }
+
+    /**
+     * This test case checks whether the package-info file is created when invalid path is given.
+     */
+    @Test
+    public void addPackageInfoWithEmptyPathTest() throws IOException {
+
+        File dirPath = new File("");
+        thrown.expect(IOException.class);
+        thrown.expectMessage("Exception occured while creating package info file.");
+        YangIoUtils.addPackageInfo(dirPath, "check1", createPath);
+        File filePath1 = new File(dirPath + File.separator + "package-info.java");
+        assertThat(filePath1.isFile(), is(false));
+    }
+
+    /**
+     * A private constructor is tested.
+     *
+     * @throws SecurityException if any security violation is observed.
+     * @throws NoSuchMethodException if when the method is not found.
+     * @throws IllegalArgumentException if there is illegal argument found.
+     * @throws InstantiationException if instantiation is provoked for the private constructor.
+     * @throws IllegalAccessException if instance is provoked or a method is provoked.
+     * @throws InvocationTargetException when an exception occurs by the method or constructor.
+     */
+    @Test
+    public void callPrivateConstructors() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
+    InstantiationException, IllegalAccessException, InvocationTargetException {
+
+        Class<?>[] classesToConstruct = {YangIoUtils.class };
+        for (Class<?> clazz : classesToConstruct) {
+            Constructor<?> constructor = clazz.getDeclaredConstructor();
+            constructor.setAccessible(true);
+            assertNotNull(constructor.newInstance());
+        }
+    }
+
+    /**
+     * This test case checks if the directory is cleaned.
+     */
+    @Test
+    public void cleanGeneratedDirTest() throws IOException {
+
+        File baseDirPath = new File(baseDir);
+        File createNewDir = new File(baseDir + File.separator + UtilConstants.YANG_GEN_DIR);
+        createNewDir.mkdirs();
+        File createFile = new File(createNewDir + File.separator + "check1.java");
+        createFile.createNewFile();
+        YangIoUtils.clean(baseDirPath.getAbsolutePath());
+    }
+
+    /**
+     * This test case checks the cleaning method when an invalid path is provided.
+     */
+    @Test
+    public void cleanWithInvalidDirTest() throws IOException {
+
+        File baseDirPath = new File(baseDir + "invalid");
+        YangIoUtils.clean(baseDirPath.getAbsolutePath());
+    }
+
+    /**
+     * This test case tests whether the directories are getting created.
+     */
+    @Test
+    public void createDirectoryTest() {
+
+        File dirPath = YangIoUtils.createDirectories(createPath);
+        assertThat(dirPath.isDirectory(), is(true));
+    }
+
+    /**
+     * This testcase checks whether the source is getting added.
+     */
+    @Test
+    public void testForAddSource() {
+
+        MavenProject project = new MavenProject();
+        BuildContext context = new DefaultBuildContext();
+        File sourceDir = new File(baseDir + File.separator + "yang");
+        sourceDir.mkdirs();
+        YangIoUtils.addToSource(sourceDir.toString(), project, context);
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/CopyrightHeader.txt b/src/test/resources/CopyrightHeader.txt
new file mode 100644
index 0000000..ca214a2
--- /dev/null
+++ b/src/test/resources/CopyrightHeader.txt
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2016 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.
+ */
+
