Extending the compiler to include the case where we can have multiple driver classes...
[iot2.git] / iotjava / iotpolicy / IoTCompiler.java
index d3db3f82a18065164fdcd698390e8831d35118f9..bdf6a416db89061f4f444483f4d151a56c7dc2e7 100644 (file)
@@ -49,7 +49,7 @@ public class IoTCompiler {
        private Map<String,DeclarationHandler> mapIntDeclHand;
        private Map<String,Map<String,Set<String>>> mapInt2NewInts;
        private Map<String,String> mapInt2NewIntName;
-       private Map<String,String> mapInt2Drv;
+       private Map<String,List<String>> mapInt2Drv;
        // Data structure to store our types (primitives and non-primitives) for compilation
        private Map<String,String> mapPrimitives;
        private Map<String,String> mapNonPrimitivesJava;
@@ -71,6 +71,8 @@ public class IoTCompiler {
         * Class constants
         */
        private final static String OUTPUT_DIRECTORY = "output_files";
+       private final static String INTERFACES_DIRECTORY = "interfaces";
+       private final static String VIRTUALS_DIRECTORY = "virtuals";
        private final static String CODE_PREFIX = "iotcode";
        private final static String INTERFACE_PACKAGE = "iotcode.interfaces";
 
@@ -94,7 +96,7 @@ public class IoTCompiler {
                mapIntDeclHand = new HashMap<String,DeclarationHandler>();
                mapInt2NewInts = new HashMap<String,Map<String,Set<String>>>();
                mapInt2NewIntName = new HashMap<String,String>();
-               mapInt2Drv = new HashMap<String,String>();
+               mapInt2Drv = new HashMap<String,List<String>>();
                mapIntfaceObjId = new HashMap<String,Integer>();
                mapNewIntfaceObjId = new HashMap<String,Integer>();
                mapPrimitives = new HashMap<String,String>();
@@ -115,20 +117,16 @@ public class IoTCompiler {
        /**
         * setDriverClass() sets the name of the driver class.
         */
-       public void setDriverClass(String _driverClass, String _intface) {
+       public void setDriverClass(String intface, String driverClass) {
                
-               mapInt2Drv.put(_driverClass, _intface);
+               List<String> drvList = mapInt2Drv.get(intface);
+               if(drvList == null)
+                       drvList = new ArrayList<String>();
+               drvList.add(driverClass);
+               mapInt2Drv.put(intface, drvList);
        }
        
-       /**
-        * getDriverClass() sets the name of the driver class.
-        */
-       public String getDriverClass(String _intface) {
-               
-               return mapInt2Drv.get(_intface);
-       }
-
-
+       
        /**
         * setControllerClass() sets the name of the controller class.
         */
@@ -292,6 +290,7 @@ public class IoTCompiler {
 
                // Create a new directory
                createDirectory(dir);
+               String path = createDirectories(dir, INTERFACES_DIRECTORY);
                for (String intface : mapIntfacePTH.keySet()) {
                        // Get the right EnumDecl
                        DeclarationHandler decHandler = mapIntDeclHand.get(intface);
@@ -300,8 +299,9 @@ public class IoTCompiler {
                        // Iterate over enum declarations
                        for (String enType : enumTypes) {
                                // Open a new file to write into
-                               FileWriter fw = new FileWriter(dir + "/" + enType + ".java");
+                               FileWriter fw = new FileWriter(path + "/" + enType + ".java");
                                pw = new PrintWriter(new BufferedWriter(fw));
+                               println("package " + INTERFACE_PACKAGE + ";\n");
                                println("public enum " + enType + " {");
                                List<String> enumMembers = enumDecl.getMembers(enType);
                                for (int i = 0; i < enumMembers.size(); i++) {
@@ -329,6 +329,7 @@ public class IoTCompiler {
 
                // Create a new directory
                createDirectory(dir);
+               String path = createDirectories(dir, INTERFACES_DIRECTORY);
                for (String intface : mapIntfacePTH.keySet()) {
                        // Get the right StructDecl
                        DeclarationHandler decHandler = mapIntDeclHand.get(intface);
@@ -337,8 +338,9 @@ public class IoTCompiler {
                        // Iterate over enum declarations
                        for (String stType : structTypes) {
                                // Open a new file to write into
-                               FileWriter fw = new FileWriter(dir + "/" + stType + ".java");
+                               FileWriter fw = new FileWriter(path + "/" + stType + ".java");
                                pw = new PrintWriter(new BufferedWriter(fw));
+                               println("package " + INTERFACE_PACKAGE + ";\n");
                                println("public class " + stType + " {");
                                List<String> structMemberTypes = structDecl.getMemberTypes(stType);
                                List<String> structMembers = structDecl.getMembers(stType);
@@ -368,9 +370,10 @@ public class IoTCompiler {
 
                // Create a new directory
                createDirectory(dir);
+               String path = createDirectories(dir, INTERFACES_DIRECTORY);
                for (String intface : mapIntfacePTH.keySet()) {
                        // Open a new file to write into
-                       FileWriter fw = new FileWriter(dir + "/" + intface + ".java");
+                       FileWriter fw = new FileWriter(path + "/" + intface + ".java");
                        pw = new PrintWriter(new BufferedWriter(fw));
                        // Pass in set of methods and get import classes
                        DeclarationHandler decHandler = mapIntDeclHand.get(intface);
@@ -411,6 +414,7 @@ public class IoTCompiler {
 
                // Create a new directory
                String path = createDirectories(dir, subdir);
+               path = createDirectories(dir + "/" + subdir, INTERFACES_DIRECTORY);
                for (String intface : mapIntfacePTH.keySet()) {
 
                        Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
@@ -1144,44 +1148,55 @@ public class IoTCompiler {
                String path = createDirectories(dir, subdir);
                for (String intface : mapIntfacePTH.keySet()) {
 
-                       Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
-                       for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
-
-                               // Open a new file to write into
-                               String newIntface = intMeth.getKey();
-                               String newStubClass = newIntface + "_Stub";
-                               FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
-                               pw = new PrintWriter(new BufferedWriter(fw));
-                               DeclarationHandler decHandler = mapIntDeclHand.get(intface);
-                               InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
-                               // Pass in set of methods and get import classes
-                               Set<String> methods = intMeth.getValue();
-                               Set<String> importClasses = getImportClasses(methods, intDecl);
-                               List<String> stdImportClasses = getStandardJavaImportClasses();
-                               List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
-                               // Find out if there are callback objects
-                               Set<String> callbackClasses = getCallbackClasses(methods, intDecl);                     
-                               boolean callbackExist = !callbackClasses.isEmpty();
-                               // Check if this interface is a callback class
-                               if(isCallbackClass(intface))
-                                       println("package " + CODE_PREFIX + "." + mapInt2Drv.get(intface) + ";\n");
-                               else
-                                       println("package " + controllerClass + ";\n");
-                               printImportStatements(allImportClasses); 
-                               println("\nimport " + INTERFACE_PACKAGE + ".*;\n");
-                               // Write class header
-                               println("public class " + newStubClass + " implements " + newIntface + " {\n");
-                               // Write properties
-                               writePropertiesJavaStub(intface, intMeth.getValue(), intDecl);
-                               // Write constructor
-                               writeConstructorJavaStub(intface, newStubClass, intMeth.getValue(), intDecl);
-                               // Write callback constructor (used if this stub is treated as a callback stub)
-                               writeCallbackConstructorJavaStub(intface, newStubClass, intMeth.getValue(), intDecl);
-                               // Write methods
-                               writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses, newStubClass);
-                               println("}");
-                               pw.close();
-                               System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".java...");
+                       // Check if there is more than 1 class that uses the same interface
+                       List<String> drvList = mapInt2Drv.get(intface);
+                       for(int i = 0; i < drvList.size(); i++) {
+
+                               String driverClass = drvList.get(i);
+                               Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
+                               for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
+
+                                       // Open a new file to write into
+                                       String newIntface = intMeth.getKey();
+                                       String newStubClass = newIntface + "_Stub";
+                                       String packageClass = null;
+                                       // Check if this interface is a callback class
+                                       if(isCallbackClass(intface)) {
+                                               packageClass = CODE_PREFIX + "." + driverClass;
+                                               path = createDirectories(dir + "/" + subdir, driverClass);
+                                       } else {
+                                               packageClass = controllerClass;
+                                               path = createDirectories(dir + "/" + subdir, controllerClass);
+                                       }
+                                       FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
+                                       pw = new PrintWriter(new BufferedWriter(fw));
+                                       DeclarationHandler decHandler = mapIntDeclHand.get(intface);
+                                       InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+                                       // Pass in set of methods and get import classes
+                                       Set<String> methods = intMeth.getValue();
+                                       Set<String> importClasses = getImportClasses(methods, intDecl);
+                                       List<String> stdImportClasses = getStandardJavaImportClasses();
+                                       List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
+                                       // Find out if there are callback objects
+                                       Set<String> callbackClasses = getCallbackClasses(methods, intDecl);                     
+                                       boolean callbackExist = !callbackClasses.isEmpty();
+                                       println("package " + packageClass + ";\n");
+                                       printImportStatements(allImportClasses); 
+                                       println("\nimport " + INTERFACE_PACKAGE + ".*;\n");
+                                       // Write class header
+                                       println("public class " + newStubClass + " implements " + newIntface + " {\n");
+                                       // Write properties
+                                       writePropertiesJavaStub(intface, intMeth.getValue(), intDecl);
+                                       // Write constructor
+                                       writeConstructorJavaStub(intface, newStubClass, intMeth.getValue(), intDecl);
+                                       // Write callback constructor (used if this stub is treated as a callback stub)
+                                       writeCallbackConstructorJavaStub(intface, newStubClass, intMeth.getValue(), intDecl);
+                                       // Write methods
+                                       writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses, newStubClass);
+                                       println("}");
+                                       pw.close();
+                                       System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".java...");
+                               }
                        }
                }
        }
@@ -2265,45 +2280,59 @@ public class IoTCompiler {
                // Create a new directory
                String path = createDirectories(dir, subdir);
                for (String intface : mapIntfacePTH.keySet()) {
-                       // Open a new file to write into
-                       String newSkelClass = intface + "_Skeleton";
-                       FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
-                       pw = new PrintWriter(new BufferedWriter(fw));
-                       // Pass in set of methods and get import classes
-                       DeclarationHandler decHandler = mapIntDeclHand.get(intface);
-                       InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
-                       List<String> methods = intDecl.getMethods();
-                       Set<String> importClasses = getImportClasses(methods, intDecl);
-                       List<String> stdImportClasses = getStandardJavaImportClasses();
-                       List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
-                       // Find out if there are callback objects
-                       Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
-                       boolean callbackExist = !callbackClasses.isEmpty();
-                       if(isCallbackClass(intface))
-                               println("package " + controllerClass + ";\n");
-                       else
-                               println("package " + CODE_PREFIX + "." + mapInt2Drv.get(intface) + ";\n");
-                       printImportStatements(allImportClasses);
-                       println("\nimport " + INTERFACE_PACKAGE + ".*;\n");
-                       // Write class header
-                       println("public class " + newSkelClass  + " implements " + intface + " {\n");
-                       // Write properties
-                       writePropertiesJavaSkeleton(intface, intDecl);
-                       // Write constructor
-                       writeConstructorJavaSkeleton(newSkelClass, intface, intDecl, methods, callbackExist);
-                       // Write constructor that is called when this object is a callback object
-                       writeCallbackConstructorJavaSkeleton(newSkelClass, intface, intDecl, methods, callbackExist);
-                       // Write function to return didAlreadyInitWaitInvoke
-                       writeReturnDidAlreadyInitWaitInvoke();
-                       // Write methods
-                       writeMethodJavaSkeleton(methods, intDecl);
-                       // Write method helper
-                       writeMethodHelperJavaSkeleton(methods, intDecl, callbackClasses);
-                       // Write waitRequestInvokeMethod() - main loop
-                       writeJavaWaitRequestInvokeMethod(methods, intDecl, intface);
-                       println("}");
-                       pw.close();
-                       System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".java...");
+               
+                       // Check if there is more than 1 class that uses the same interface
+                       List<String> drvList = mapInt2Drv.get(intface);
+                       for(int i = 0; i < drvList.size(); i++) {
+
+                               // Get driver class
+                               String driverClass = drvList.get(i);
+                               // Open a new file to write into
+                               String newSkelClass = intface + "_Skeleton";
+                               String packageClass = null;
+                               // Check if this interface is a callback class
+                               if(isCallbackClass(intface)) {
+                                       packageClass = controllerClass;
+                                       path = createDirectories(dir + "/" + subdir, controllerClass);
+                               } else {
+                                       packageClass = CODE_PREFIX + "." + driverClass;
+                                       path = createDirectories(dir + "/" + subdir, driverClass);
+                               }
+                               FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
+                               pw = new PrintWriter(new BufferedWriter(fw));
+                               // Pass in set of methods and get import classes
+                               DeclarationHandler decHandler = mapIntDeclHand.get(intface);
+                               InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+                               List<String> methods = intDecl.getMethods();
+                               Set<String> importClasses = getImportClasses(methods, intDecl);
+                               List<String> stdImportClasses = getStandardJavaImportClasses();
+                               List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
+                               // Find out if there are callback objects
+                               Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+                               boolean callbackExist = !callbackClasses.isEmpty();
+                               println("package " + packageClass + ";\n");
+                               printImportStatements(allImportClasses);
+                               println("\nimport " + INTERFACE_PACKAGE + ".*;\n");
+                               // Write class header
+                               println("public class " + newSkelClass  + " implements " + intface + " {\n");
+                               // Write properties
+                               writePropertiesJavaSkeleton(intface, intDecl);
+                               // Write constructor
+                               writeConstructorJavaSkeleton(newSkelClass, intface, intDecl, methods, callbackExist);
+                               // Write constructor that is called when this object is a callback object
+                               writeCallbackConstructorJavaSkeleton(newSkelClass, intface, intDecl, methods, callbackExist);
+                               // Write function to return didAlreadyInitWaitInvoke
+                               writeReturnDidAlreadyInitWaitInvoke();
+                               // Write methods
+                               writeMethodJavaSkeleton(methods, intDecl);
+                               // Write method helper
+                               writeMethodHelperJavaSkeleton(methods, intDecl, callbackClasses);
+                               // Write waitRequestInvokeMethod() - main loop
+                               writeJavaWaitRequestInvokeMethod(methods, intDecl, intface);
+                               println("}");
+                               pw.close();
+                               System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".java...");
+                       }
                }
        }
 
@@ -2379,6 +2408,7 @@ public class IoTCompiler {
 
                // Create a new directory
                createDirectory(dir);
+               String path = createDirectories(dir, VIRTUALS_DIRECTORY);
                for (String intface : mapIntfacePTH.keySet()) {
                        // Get the right StructDecl
                        DeclarationHandler decHandler = mapIntDeclHand.get(intface);
@@ -2387,7 +2417,7 @@ public class IoTCompiler {
                        // Iterate over enum declarations
                        for (String enType : enumTypes) {
                                // Open a new file to write into
-                               FileWriter fw = new FileWriter(dir + "/" + enType + ".hpp");
+                               FileWriter fw = new FileWriter(path + "/" + enType + ".hpp");
                                pw = new PrintWriter(new BufferedWriter(fw));
                                // Write file headers
                                println("#ifndef _" + enType.toUpperCase() + "_HPP__");
@@ -2420,6 +2450,7 @@ public class IoTCompiler {
 
                // Create a new directory
                createDirectory(dir);
+               String path = createDirectories(dir, VIRTUALS_DIRECTORY);
                for (String intface : mapIntfacePTH.keySet()) {
                        // Get the right StructDecl
                        DeclarationHandler decHandler = mapIntDeclHand.get(intface);
@@ -2428,7 +2459,7 @@ public class IoTCompiler {
                        // Iterate over enum declarations
                        for (String stType : structTypes) {
                                // Open a new file to write into
-                               FileWriter fw = new FileWriter(dir + "/" + stType + ".hpp");
+                               FileWriter fw = new FileWriter(path + "/" + stType + ".hpp");
                                pw = new PrintWriter(new BufferedWriter(fw));
                                // Write file headers
                                println("#ifndef _" + stType.toUpperCase() + "_HPP__");
@@ -2466,9 +2497,10 @@ public class IoTCompiler {
 
                // Create a new directory
                createDirectory(dir);
+               String path = createDirectories(dir, VIRTUALS_DIRECTORY);
                for (String intface : mapIntfacePTH.keySet()) {
                        // Open a new file to write into
-                       FileWriter fw = new FileWriter(dir + "/" + intface + ".hpp");
+                       FileWriter fw = new FileWriter(path + "/" + intface + ".hpp");
                        pw = new PrintWriter(new BufferedWriter(fw));
                        // Write file headers
                        println("#ifndef _" + intface.toUpperCase() + "_HPP__");
@@ -2532,6 +2564,7 @@ public class IoTCompiler {
 
                // Create a new directory
                String path = createDirectories(dir, subdir);
+               path = createDirectories(dir + "/" + subdir, VIRTUALS_DIRECTORY);
                for (String intface : mapIntfacePTH.keySet()) {
 
                        Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
@@ -3161,45 +3194,56 @@ public class IoTCompiler {
                String path = createDirectories(dir, subdir);
                for (String intface : mapIntfacePTH.keySet()) {
 
-                       Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
-                       for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
-                               // Open a new file to write into
-                               String newIntface = intMeth.getKey();
-                               String newStubClass = newIntface + "_Stub";
-                               FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
-                               pw = new PrintWriter(new BufferedWriter(fw));
-                               // Write file headers
-                               println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
-                               println("#define _" + newStubClass.toUpperCase() + "_HPP__");
-                               println("#include <iostream>");
-                               // Find out if there are callback objects
-                               Set<String> methods = intMeth.getValue();
-                               DeclarationHandler decHandler = mapIntDeclHand.get(intface);
-                               InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
-                               Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
-                               boolean callbackExist = !callbackClasses.isEmpty();
-                               println("#include <thread>");
-                               println("#include <mutex>");
-                               List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
-                               printIncludeStatements(stdIncludeClasses); println("");
-                               println("#include \"" + newIntface + ".hpp\""); println("");            
-                               println("using namespace std;"); println("");
-                               println("class " + newStubClass + " : public " + newIntface); println("{");
-                               println("private:\n");
-                               writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses, methods, intDecl);
-                               println("public:\n");
-                               // Add default constructor and destructor
-                               println(newStubClass + "();");
-                               // Declarations
-                               println(newStubClass + "(int _portSend, int _portRecv, const char* _skeletonAddress, int _rev, bool* _bResult);");
-                               println(newStubClass + "(IoTRMIComm* _rmiComm, int _objectId);");
-                               println("~" + newStubClass + "();");
-                               // Write methods
-                               writeMethodDeclCplusStub(methods, intDecl);
-                               print("}"); println(";");
-                               println("#endif");
-                               pw.close();
-                               System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
+                       // Check if there is more than 1 class that uses the same interface
+                       List<String> drvList = mapInt2Drv.get(intface);
+                       for(int i = 0; i < drvList.size(); i++) {
+
+                               String driverClass = drvList.get(i);
+                               Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
+                               for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
+                                       // Open a new file to write into
+                                       String newIntface = intMeth.getKey();
+                                       String newStubClass = newIntface + "_Stub";
+                                       // Check if this interface is a callback class
+                                       if(isCallbackClass(intface))
+                                               path = createDirectories(dir + "/" + subdir, driverClass);
+                                       else
+                                               path = createDirectories(dir + "/" + subdir, controllerClass);
+                                       FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
+                                       pw = new PrintWriter(new BufferedWriter(fw));
+                                       // Write file headers
+                                       println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
+                                       println("#define _" + newStubClass.toUpperCase() + "_HPP__");
+                                       println("#include <iostream>");
+                                       // Find out if there are callback objects
+                                       Set<String> methods = intMeth.getValue();
+                                       DeclarationHandler decHandler = mapIntDeclHand.get(intface);
+                                       InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+                                       Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+                                       boolean callbackExist = !callbackClasses.isEmpty();
+                                       println("#include <thread>");
+                                       println("#include <mutex>");
+                                       List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
+                                       printIncludeStatements(stdIncludeClasses); println("");
+                                       println("#include \"" + newIntface + ".hpp\""); println("");            
+                                       println("using namespace std;"); println("");
+                                       println("class " + newStubClass + " : public " + newIntface); println("{");
+                                       println("private:\n");
+                                       writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses, methods, intDecl);
+                                       println("public:\n");
+                                       // Add default constructor and destructor
+                                       println(newStubClass + "();");
+                                       // Declarations
+                                       println(newStubClass + "(int _portSend, int _portRecv, const char* _skeletonAddress, int _rev, bool* _bResult);");
+                                       println(newStubClass + "(IoTRMIComm* _rmiComm, int _objectId);");
+                                       println("~" + newStubClass + "();");
+                                       // Write methods
+                                       writeMethodDeclCplusStub(methods, intDecl);
+                                       print("}"); println(";");
+                                       println("#endif");
+                                       pw.close();
+                                       System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
+                               }
                        }
                }
        }
@@ -3233,45 +3277,56 @@ public class IoTCompiler {
                String path = createDirectories(dir, subdir);
                for (String intface : mapIntfacePTH.keySet()) {
 
-                       Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
-                       for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
-                               // Open a new file to write into
-                               String newIntface = intMeth.getKey();
-                               String newStubClass = newIntface + "_Stub";
-                               FileWriter fw = new FileWriter(path + "/" + newStubClass + ".cpp");
-                               pw = new PrintWriter(new BufferedWriter(fw));
-                               // Write file headers
-                               println("#include <iostream>");
-                               // Find out if there are callback objects
-                               Set<String> methods = intMeth.getValue();
-                               DeclarationHandler decHandler = mapIntDeclHand.get(intface);
-                               InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
-                               Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
-                               boolean callbackExist = !callbackClasses.isEmpty();
-                               println("#include \"" + newStubClass + ".hpp\""); println("");
-                               for(String str: callbackClasses) {
-                                       if (intface.equals(mainClass))
-                                               println("#include \"" + str + "_Skeleton.cpp\"\n");
+                       // Check if there is more than 1 class that uses the same interface
+                       List<String> drvList = mapInt2Drv.get(intface);
+                       for(int i = 0; i < drvList.size(); i++) {
+
+                               String driverClass = drvList.get(i);
+                               Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
+                               for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
+                                       // Open a new file to write into
+                                       String newIntface = intMeth.getKey();
+                                       String newStubClass = newIntface + "_Stub";
+                                       // Check if this interface is a callback class
+                                       if(isCallbackClass(intface))
+                                               path = createDirectories(dir + "/" + subdir, driverClass);
                                        else
-                                               println("#include \"" + str + "_Skeleton.hpp\"\n");
-                               }
-                               println("using namespace std;"); println("");
-                               // Add default constructor and destructor
-                               writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses, methods, intDecl);
-                               writeCallbackConstructorCplusStub(newStubClass, callbackExist, callbackClasses, methods, intDecl);
-                               writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
-                               // Write methods
-                               writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass);
-                               // Write external functions for .so file
-                               writeStubExternalCFunctions(newStubClass);
-                               // TODO: Remove this later
-                               if (intface.equals(mainClass)) {
-                                       println("int main() {");
-                                       println("return 0;");
-                                       println("}");
+                                               path = createDirectories(dir + "/" + subdir, controllerClass);
+                                       FileWriter fw = new FileWriter(path + "/" + newStubClass + ".cpp");
+                                       pw = new PrintWriter(new BufferedWriter(fw));
+                                       // Write file headers
+                                       println("#include <iostream>");
+                                       // Find out if there are callback objects
+                                       Set<String> methods = intMeth.getValue();
+                                       DeclarationHandler decHandler = mapIntDeclHand.get(intface);
+                                       InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+                                       Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+                                       boolean callbackExist = !callbackClasses.isEmpty();
+                                       println("#include \"" + newStubClass + ".hpp\""); println("");
+                                       for(String str: callbackClasses) {
+                                               if (intface.equals(mainClass))
+                                                       println("#include \"" + str + "_Skeleton.cpp\"\n");
+                                               else
+                                                       println("#include \"" + str + "_Skeleton.hpp\"\n");
+                                       }
+                                       println("using namespace std;"); println("");
+                                       // Add default constructor and destructor
+                                       writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses, methods, intDecl);
+                                       writeCallbackConstructorCplusStub(newStubClass, callbackExist, callbackClasses, methods, intDecl);
+                                       writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
+                                       // Write methods
+                                       writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass);
+                                       // Write external functions for .so file
+                                       writeStubExternalCFunctions(newStubClass);
+                                       // TODO: Remove this later
+                                       if (intface.equals(mainClass)) {
+                                               println("int main() {");
+                                               println("return 0;");
+                                               println("}");
+                                       }
+                                       pw.close();
+                                       System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".cpp...");
                                }
-                               pw.close();
-                               System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".cpp...");
                        }
                }
        }
@@ -4246,49 +4301,62 @@ public class IoTCompiler {
                // Create a new directory
                String path = createDirectories(dir, subdir);
                for (String intface : mapIntfacePTH.keySet()) {
-                       // Open a new file to write into
-                       String newSkelClass = intface + "_Skeleton";
-                       FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
-                       pw = new PrintWriter(new BufferedWriter(fw));
-                       // Write file headers
-                       println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
-                       println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
-                       println("#include <iostream>");
-                       println("#include \"" + intface + ".hpp\"\n");
-                       // Pass in set of methods and get import classes
-                       DeclarationHandler decHandler = mapIntDeclHand.get(intface);
-                       InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
-                       List<String> methods = intDecl.getMethods();
-                       List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
-                       printIncludeStatements(stdIncludeClasses); println("");
-                       println("using namespace std;\n");
-                       // Find out if there are callback objects
-                       Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
-                       boolean callbackExist = !callbackClasses.isEmpty();
-                       // Write class header
-                       println("class " + newSkelClass + " : public " + intface); println("{");
-                       println("private:\n");
-                       // Write properties
-                       writePropertiesCplusSkeleton(intface, callbackExist, callbackClasses);
-                       println("public:\n");
-                       // Write constructors
-                       println(newSkelClass + "();");
-                       println(newSkelClass + "(" + intface + "*_mainObj, int _portSend, int _portRecv);");
-                       println(newSkelClass + "(" + intface + "*_mainObj, IoTRMIComm *rmiComm, int _objectId);");
-                       // Write deconstructor
-                       println("~" + newSkelClass + "();");
-                       // Write method declarations
-                       println("bool didInitWaitInvoke();");
-                       writeMethodDeclCplusSkeleton(methods, intDecl, callbackClasses);
-                       // Write method helper declarations
-                       writeMethodHelperDeclCplusSkeleton(methods, intDecl, newSkelClass);
-                       // Write waitRequestInvokeMethod() declaration - main loop
-                       println("void ___waitRequestInvokeMethod(" + newSkelClass + "* skel);");
-                       println("};");
-                       writePermissionInitializationCplus(intface, newSkelClass, intDecl);
-                       println("#endif");
-                       pw.close();
-                       System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp...");
+               
+                       // Check if there is more than 1 class that uses the same interface
+                       List<String> drvList = mapInt2Drv.get(intface);
+                       for(int i = 0; i < drvList.size(); i++) {
+
+                               // Open a new file to write into
+                               String newSkelClass = intface + "_Skeleton";
+                               // Get driver class
+                               String driverClass = drvList.get(i);
+                               // Check if this interface is a callback class
+                               if(isCallbackClass(intface))
+                                       path = createDirectories(dir + "/" + subdir, controllerClass);
+                               else
+                                       path = createDirectories(dir + "/" + subdir, driverClass);
+                               FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
+                               pw = new PrintWriter(new BufferedWriter(fw));
+                               // Write file headers
+                               println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
+                               println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
+                               println("#include <iostream>");
+                               println("#include \"" + intface + ".hpp\"\n");
+                               // Pass in set of methods and get import classes
+                               DeclarationHandler decHandler = mapIntDeclHand.get(intface);
+                               InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+                               List<String> methods = intDecl.getMethods();
+                               List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
+                               printIncludeStatements(stdIncludeClasses); println("");
+                               println("using namespace std;\n");
+                               // Find out if there are callback objects
+                               Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+                               boolean callbackExist = !callbackClasses.isEmpty();
+                               // Write class header
+                               println("class " + newSkelClass + " : public " + intface); println("{");
+                               println("private:\n");
+                               // Write properties
+                               writePropertiesCplusSkeleton(intface, callbackExist, callbackClasses);
+                               println("public:\n");
+                               // Write constructors
+                               println(newSkelClass + "();");
+                               println(newSkelClass + "(" + intface + "*_mainObj, int _portSend, int _portRecv);");
+                               println(newSkelClass + "(" + intface + "*_mainObj, IoTRMIComm *rmiComm, int _objectId);");
+                               // Write deconstructor
+                               println("~" + newSkelClass + "();");
+                               // Write method declarations
+                               println("bool didInitWaitInvoke();");
+                               writeMethodDeclCplusSkeleton(methods, intDecl, callbackClasses);
+                               // Write method helper declarations
+                               writeMethodHelperDeclCplusSkeleton(methods, intDecl, newSkelClass);
+                               // Write waitRequestInvokeMethod() declaration - main loop
+                               println("void ___waitRequestInvokeMethod(" + newSkelClass + "* skel);");
+                               println("};");
+                               writePermissionInitializationCplus(intface, newSkelClass, intDecl);
+                               println("#endif");
+                               pw.close();
+                               System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp...");
+                       }
                }
        }
 
@@ -4329,51 +4397,64 @@ public class IoTCompiler {
                // Create a new directory
                String path = createDirectories(dir, subdir);
                for (String intface : mapIntfacePTH.keySet()) {
-                       // Open a new file to write into
-                       String newSkelClass = intface + "_Skeleton";
-                       FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".cpp");
-                       pw = new PrintWriter(new BufferedWriter(fw));
-                       // Write file headers
-                       println("#include <iostream>");
-                       println("#include \"" + newSkelClass + ".hpp\"\n");
-                       // Pass in set of methods and get import classes
-                       DeclarationHandler decHandler = mapIntDeclHand.get(intface);
-                       InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
-                       List<String> methods = intDecl.getMethods();
-                       // Find out if there are callback objects
-                       Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
-                       boolean callbackExist = !callbackClasses.isEmpty();
-                       for(String str: callbackClasses) {
-                               if (intface.equals(mainClass))
-                                       println("#include \"" + getStubInterface(str) + "_Stub.cpp\"\n");
+
+                       // Check if there is more than 1 class that uses the same interface
+                       List<String> drvList = mapInt2Drv.get(intface);
+                       for(int i = 0; i < drvList.size(); i++) {
+
+                               // Open a new file to write into
+                               String newSkelClass = intface + "_Skeleton";
+                               // Get driver class
+                               String driverClass = drvList.get(i);
+                               // Check if this interface is a callback class
+                               if(isCallbackClass(intface))
+                                       path = createDirectories(dir + "/" + subdir, controllerClass);
                                else
-                                       println("#include \"" + getStubInterface(str) + "_Stub.hpp\"\n");
-                       }
-                       println("using namespace std;\n");
-                       // Write constructor
-                       writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist, intDecl, methods);
-                       // Write callback constructor
-                       writeCallbackConstructorCplusSkeleton(newSkelClass, intface, callbackExist, intDecl, methods);
-                       // Write deconstructor
-                       writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
-                       // Write didInitWaitInvoke() to return bool
-                       writeReturnDidAlreadyInitWaitInvoke(newSkelClass);
-                       // Write methods
-                       writeMethodCplusSkeleton(methods, intDecl, newSkelClass);
-                       // Write method helper
-                       writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses, newSkelClass);
-                       // Write waitRequestInvokeMethod() - main loop
-                       writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface, newSkelClass);
-                       // Write external functions for .so file
-                       writeSkelExternalCFunctions(newSkelClass, intface);
-                       // TODO: Remove this later
-                       if (intface.equals(mainClass)) {
-                               println("int main() {");
-                               println("return 0;");
-                               println("}");
+                                       path = createDirectories(dir + "/" + subdir, driverClass);
+                               FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".cpp");
+                               pw = new PrintWriter(new BufferedWriter(fw));
+                               // Write file headers
+                               println("#include <iostream>");
+                               println("#include \"" + newSkelClass + ".hpp\"\n");
+                               // Pass in set of methods and get import classes
+                               DeclarationHandler decHandler = mapIntDeclHand.get(intface);
+                               InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+                               List<String> methods = intDecl.getMethods();
+                               // Find out if there are callback objects
+                               Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+                               boolean callbackExist = !callbackClasses.isEmpty();
+                               for(String str: callbackClasses) {
+                                       if (intface.equals(mainClass))
+                                               println("#include \"" + getStubInterface(str) + "_Stub.cpp\"\n");
+                                       else
+                                               println("#include \"" + getStubInterface(str) + "_Stub.hpp\"\n");
+                               }
+                               println("using namespace std;\n");
+                               // Write constructor
+                               writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist, intDecl, methods);
+                               // Write callback constructor
+                               writeCallbackConstructorCplusSkeleton(newSkelClass, intface, callbackExist, intDecl, methods);
+                               // Write deconstructor
+                               writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
+                               // Write didInitWaitInvoke() to return bool
+                               writeReturnDidAlreadyInitWaitInvoke(newSkelClass);
+                               // Write methods
+                               writeMethodCplusSkeleton(methods, intDecl, newSkelClass);
+                               // Write method helper
+                               writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses, newSkelClass);
+                               // Write waitRequestInvokeMethod() - main loop
+                               writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface, newSkelClass);
+                               // Write external functions for .so file
+                               writeSkelExternalCFunctions(newSkelClass, intface);
+                               // TODO: Remove this later
+                               if (intface.equals(mainClass)) {
+                                       println("int main() {");
+                                       println("return 0;");
+                                       println("}");
+                               }
+                               pw.close();
+                               System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".cpp...");
                        }
-                       pw.close();
-                       System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".cpp...");
                }
        }