Adding callback support for C++; still missing dynamic policy checks for both
authorrtrimana <rtrimana@uci.edu>
Thu, 17 Nov 2016 00:38:20 +0000 (16:38 -0800)
committerrtrimana <rtrimana@uci.edu>
Thu, 17 Nov 2016 00:38:20 +0000 (16:38 -0800)
iotjava/Makefile
iotjava/iotpolicy/IoTCompiler.java

index e748017..a63d357 100644 (file)
@@ -32,8 +32,9 @@ PHONY += compile
 compile:
        cd $(BIN_DIR)/iotpolicy/output_files; cp *.java ./Java
        cd $(BIN_DIR)/iotpolicy/output_files; cp *.hpp ./Cplus
-       cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) *.java
+#      cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) *.java
 #      cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./*.hpp --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
+       cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./Camera_CallbackSkeleton.hpp --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
 
 PHONY += clean
 clean:
@@ -45,8 +46,8 @@ clean:
 PHONY += rmi
 rmi:
        mkdir -p $(BIN_DIR)
-       $(JAVAC) -cp .:../$(BIN_DIR) -d $(BIN_DIR) iotrmi/Java/*.java
-       $(JAVAC) -cp .:../$(BIN_DIR) -d $(BIN_DIR) iotrmi/Java/sample/*.java
+#      $(JAVAC) -cp .:../$(BIN_DIR) -d $(BIN_DIR) iotrmi/Java/*.java
+#      $(JAVAC) -cp .:../$(BIN_DIR) -d $(BIN_DIR) iotrmi/Java/sample/*.java
 #      mkdir -p $(BIN_DIR)/iotrmi/C++
        #$(G++) iotrmi/C++/IoTSocketServer.cpp -o $(BIN_DIR)/iotrmi/C++/IoTSocketServer.out
        #$(G++) iotrmi/C++/IoTSocketClient.cpp -o $(BIN_DIR)/iotrmi/C++/IoTSocketClient.out
index 7681ff5..619146e 100644 (file)
@@ -194,7 +194,7 @@ public class IoTCompiler {
                        for (int i = 0; i < methParams.size(); i++) {
                                // Check for params with driver class types and exchange it 
                                //              with its remote interface
-                               String paramType = checkAndGetParamClass(methPrmTypes.get(i), false);
+                               String paramType = checkAndGetParamClass(methPrmTypes.get(i));
                                print(paramType + " " + methParams.get(i));
                                // Check if this is the last element (don't print a comma)
                                if (i != methParams.size() - 1) {
@@ -487,14 +487,25 @@ public class IoTCompiler {
        }
 
 
+       /**
+        * HELPER: returnGenericCallbackType() returns the callback type
+        */
+       private String returnGenericCallbackType(String paramType) {
+
+               if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES)
+                       return getTypeOfGeneric(paramType)[0];
+               else
+                       return paramType;
+       }
+
+
        /**
         * HELPER: checkCallbackType() checks the callback type
         */
        private boolean checkCallbackType(String paramType, String callbackType) {
 
-               if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES)
-                       paramType = getTypeOfGeneric(paramType)[0];
-               return callbackType.equals(paramType);
+               String prmType = returnGenericCallbackType(paramType);
+               return callbackType.equals(prmType);
        }
 
 
@@ -593,16 +604,12 @@ public class IoTCompiler {
                        String callbackType = null;
                        for (int i = 0; i < methParams.size(); i++) {
 
-                               String paramType = methPrmTypes.get(i);
-                               if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES)
-                                       paramType = getTypeOfGeneric(paramType)[0];
+                               String paramType = returnGenericCallbackType(methPrmTypes.get(i));
                                // Check if this has callback object
-                               if (callbackClasses != null) {
-                                       if (callbackClasses.contains(paramType)) {
-                                               isCallbackMethod = true;
-                                               callbackType = paramType;       
-                                               // Even if there're 2 callback arguments, we expect them to be of the same interface
-                                       }
+                               if (callbackClasses.contains(paramType)) {
+                                       isCallbackMethod = true;
+                                       callbackType = paramType;       
+                                       // Even if there're 2 callback arguments, we expect them to be of the same interface
                                }
                                print(methPrmTypes.get(i) + " " + methParams.get(i));
                                // Check if this is the last element (don't print a comma)
@@ -647,7 +654,7 @@ public class IoTCompiler {
                                Set<String> methods = intMeth.getValue();
                                Set<String> importClasses = getImportClasses(methods, intDecl);
                                List<String> stdImportClasses = getStandardJavaImportClasses();
-                               List<String> allImportClasses = getAllImportClasses(stdImportClasses, importClasses);
+                               List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
                                printImportStatements(allImportClasses); println("");
                                // Find out if there are callback objects
                                Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
@@ -738,7 +745,7 @@ public class IoTCompiler {
                                Set<String> methods = intMeth.getValue();
                                Set<String> importClasses = getImportClasses(methods, intDecl);
                                List<String> stdImportClasses = getStandardJavaImportClasses();
-                               List<String> allImportClasses = getAllImportClasses(stdImportClasses, importClasses);
+                               List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
                                printImportStatements(allImportClasses); println("");
                                // Find out if there are callback objects
                                Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
@@ -854,12 +861,10 @@ public class IoTCompiler {
                        for (int i = 0; i < methParams.size(); i++) {
 
                                String origParamType = methPrmTypes.get(i);
-                               String paramType = checkAndGetParamClass(origParamType, false);
-                               if (callbackClasses != null) {  // Check if this has callback object
-                                       if (callbackClasses.contains(origParamType)) {
-                                               isCallbackMethod = true;
-                                               callbackType = origParamType;   
-                                       }
+                               String paramType = checkAndGetParamClass(origParamType);
+                               if (callbackClasses.contains(origParamType)) { // Check if this has callback object
+                                       isCallbackMethod = true;
+                                       callbackType = origParamType;   
                                }
                                print(paramType + " " + methParams.get(i));
                                // Check if this is the last element (don't print a comma)
@@ -878,9 +883,9 @@ public class IoTCompiler {
 
 
        /**
-        * HELPER: writeCallbackStubGeneration() writes the callback stub generation part
+        * HELPER: writeCallbackJavaStubGeneration() writes the callback stub generation part
         */
-       private Map<Integer,String> writeCallbackStubGeneration(List<String> methParams, List<String> methPrmTypes, String callbackType) {
+       private Map<Integer,String> writeCallbackJavaStubGeneration(List<String> methParams, List<String> methPrmTypes, String callbackType) {
 
                Map<Integer,String> mapStubParam = new HashMap<Integer,String>();
                // Iterate over callback objects
@@ -890,7 +895,7 @@ public class IoTCompiler {
                        //if (callbackType.equals(paramType)) {
                        if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
                                println("try {");
-                               String exchParamType = checkAndGetParamClass(paramType, false);
+                               String exchParamType = checkAndGetParamClass(paramType);
                                // Print array if this is array or list if this is a list of callback objects
                                if (isArray(paramType, param)) {
                                        println("int numStubs" + i + " = (int) paramObj[" + i + "];");
@@ -905,7 +910,7 @@ public class IoTCompiler {
                        }
                        // Generate a loop if needed
                        if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
-                               String exchParamType = checkAndGetParamClass(paramType, false);
+                               String exchParamType = checkAndGetParamClass(paramType);
                                if (isArray(paramType, param)) {
                                        println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
                                        println("stub" + i + "[objId] = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
@@ -917,8 +922,8 @@ public class IoTCompiler {
                                        println("objIdCnt++;");
                                        println("}");
                                }
+                               mapStubParam.put(i, "stub" + i);        // List of all stub parameters
                        }
-                       mapStubParam.put(i, "stub" + i);        // List of all stub parameters
                }
                return mapStubParam;
        }
@@ -934,19 +939,13 @@ public class IoTCompiler {
                String callbackType = null;
                print("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { ");
                for (int i = 0; i < methParams.size(); i++) {
-                       String paramType = methPrmTypes.get(i);
-                       if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES)
-                               paramType = getTypeOfGeneric(paramType)[0];
-                       if (callbackClasses != null) {
-                               if (callbackClasses.contains(paramType)) {
-                                       isCallbackMethod = true;
-                                       callbackType = paramType;
-                                       print("int.class");
-                               } else {
-                                       String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
-                                       print(getSimpleType(prmType) + ".class");
-                               }
-                       } else { // Generate normal classes if it's not a callback object
+
+                       String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+                       if (callbackClasses.contains(paramType)) {
+                               isCallbackMethod = true;
+                               callbackType = paramType;
+                               print("int.class");
+                       } else {        // Generate normal classes if it's not a callback object
                                String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
                                print(getSimpleType(prmType) + ".class");
                        }
@@ -968,7 +967,7 @@ public class IoTCompiler {
                println(" });");
                Map<Integer,String> mapStubParam = null;
                if (isCallbackMethod)
-                       mapStubParam = writeCallbackStubGeneration(methParams, methPrmTypes, callbackType);
+                       mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType);
                // Check if this is "void"
                String retType = intDecl.getMethodType(method);
                if (retType.equals("void")) {
@@ -1089,7 +1088,7 @@ public class IoTCompiler {
                        List<String> methods = intDecl.getMethods();
                        Set<String> importClasses = getImportClasses(methods, intDecl);
                        List<String> stdImportClasses = getStandardJavaImportClasses();
-                       List<String> allImportClasses = getAllImportClasses(stdImportClasses, importClasses);
+                       List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
                        printImportStatements(allImportClasses);
                        // Find out if there are callback objects
                        Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
@@ -1229,7 +1228,7 @@ public class IoTCompiler {
                        List<String> methods = intDecl.getMethods();
                        Set<String> importClasses = getImportClasses(methods, intDecl);
                        List<String> stdImportClasses = getStandardJavaImportClasses();
-                       List<String> allImportClasses = getAllImportClasses(stdImportClasses, importClasses);
+                       List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
                        printImportStatements(allImportClasses);
                        // Find out if there are callback objects
                        Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
@@ -1254,6 +1253,35 @@ public class IoTCompiler {
        }
 
 
+       /**
+        * HELPER: writeMethodCplusLocalInterface() writes the method of the interface
+        */
+       private void writeMethodCplusLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
+
+               for (String method : methods) {
+
+                       List<String> methParams = intDecl.getMethodParams(method);
+                       List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+                       print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
+                               intDecl.getMethodId(method) + "(");
+                       for (int i = 0; i < methParams.size(); i++) {
+                               // Check for params with driver class types and exchange it 
+                               //              with its remote interface
+                               String paramType = checkAndGetParamClass(methPrmTypes.get(i));
+                               paramType = checkAndGetCplusType(paramType);
+                               // Check for arrays - translate into vector in C++
+                               String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
+                               print(paramComplete);
+                               // Check if this is the last element (don't print a comma)
+                               if (i != methParams.size() - 1) {
+                                       print(", ");
+                               }
+                       }
+                       println(") = 0;");
+               }
+       }
+
+
        /**
         * HELPER: writeMethodCplusInterface() writes the method of the interface
         */
@@ -1268,7 +1296,6 @@ public class IoTCompiler {
                        for (int i = 0; i < methParams.size(); i++) {
                                // Check for params with driver class types and exchange it 
                                //              with its remote interface
-                               //String paramType = checkAndGetParamClass(methPrmTypes.get(i), true);
                                String paramType = methPrmTypes.get(i);
                                paramType = checkAndGetCplusType(paramType);
                                // Check for arrays - translate into vector in C++
@@ -1359,7 +1386,7 @@ public class IoTCompiler {
                        DeclarationHandler decHandler = mapIntDeclHand.get(intface);
                        InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
                        List<String> methods = intDecl.getMethods();
-                       Set<String> includeClasses = getIncludeClasses(methods, intDecl);
+                       Set<String> includeClasses = getIncludeClasses(methods, intDecl, true);
                        printIncludeStatements(includeClasses); println("");
                        println("using namespace std;\n");
                        // Write enum if any...
@@ -1371,7 +1398,7 @@ public class IoTCompiler {
                        println("class " + intface); println("{");
                        println("public:");
                        // Write methods
-                       writeMethodCplusInterface(methods, intDecl);
+                       writeMethodCplusLocalInterface(methods, intDecl);
                        println("};");
                        println("#endif");
                        pw.close();
@@ -1405,9 +1432,9 @@ public class IoTCompiler {
                                println("#define _" + newIntface.toUpperCase() + "_HPP__");
                                println("#include <iostream>");
                                // Pass in set of methods and get import classes
-                               Set<String> includeClasses = getIncludeClasses(intMeth.getValue(), intDecl);
+                               Set<String> includeClasses = getIncludeClasses(intMeth.getValue(), intDecl, false);
                                List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
-                               List<String> allIncludeClasses = getAllImportClasses(stdIncludeClasses, includeClasses);
+                               List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
                                printIncludeStatements(allIncludeClasses); println("");                 
                                println("using namespace std;\n");
                                println("class " + newIntface);
@@ -1427,7 +1454,7 @@ public class IoTCompiler {
        /**
         * HELPER: writeMethodCplusStub() writes the method of the stub
         */
-       private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl) {
+       private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
 
                for (String method : methods) {
 
@@ -1435,11 +1462,18 @@ public class IoTCompiler {
                        List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
                        print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
                                intDecl.getMethodId(method) + "(");
+                       boolean isCallbackMethod = false;
+                       String callbackType = null;
                        for (int i = 0; i < methParams.size(); i++) {
 
-                               //String paramType = checkAndGetParamClass(methPrmTypes.get(i), true);
                                String paramType = methPrmTypes.get(i);
-                               String methPrmType = checkAndGetCplusType(paramType);
+                               // Check if this has callback object
+                               if (callbackClasses.contains(paramType)) {
+                                       isCallbackMethod = true;
+                                       callbackType = paramType;       
+                                       // Even if there're 2 callback arguments, we expect them to be of the same interface
+                               }
+                               String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
                                String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
                                print(methParamComplete);
                                // Check if this is the last element (don't print a comma)
@@ -1448,8 +1482,96 @@ public class IoTCompiler {
                                }
                        }
                        println(") { ");
-                       writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method);
+                       if (isCallbackMethod)
+                               writeCallbackMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType);
+                       else
+                               writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method);
                        println("}\n");
+                       // Write the init callback helper method
+                       if (isCallbackMethod) {
+                               writeInitCallbackCplusStub(callbackType, intDecl);
+                               writeInitCallbackSendInfoCplusStub(intDecl);
+                       }
+               }
+       }
+
+
+       /**
+        * HELPER: writeCallbackMethodBodyCplusStub() writes the callback method of the stub class
+        */
+       private void writeCallbackMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
+                       List<String> methPrmTypes, String method, String callbackType) {
+
+               // Check if this is single object, array, or list of objects
+               boolean isArrayOrList = false;
+               String callbackParam = null;
+               for (int i = 0; i < methParams.size(); i++) {
+
+                       String paramType = methPrmTypes.get(i);
+                       if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+                               String param = methParams.get(i);
+                               if (isArrayOrList(paramType, param)) {  // Generate loop
+                                       println("for (" + paramType + "* cb : " + getSimpleIdentifier(param) + ") {");
+                                       println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);");
+                                       isArrayOrList = true;
+                                       callbackParam = getSimpleIdentifier(param);
+                               } else
+                                       println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(" +
+                                               getSimpleIdentifier(param) + ", objIdCnt++);");
+                               println("vecCallbackObj.push_back(skel);");
+                               if (isArrayOrList(paramType, param))
+                                       println("}");
+                       }
+               }
+               println("int numParam = " + methParams.size() + ";");
+               println("int methodId = " + intDecl.getMethodNumId(method) + ";");
+               String retType = intDecl.getMethodType(method);
+               String retTypeC = checkAndGetCplusType(retType);
+               println("string retType = \"" + checkAndGetCplusArrayType(retTypeC) + "\";");
+               // Generate array of parameter types
+               print("string paramCls[] = { ");
+               for (int i = 0; i < methParams.size(); i++) {
+                       String paramType = methPrmTypes.get(i);
+                       if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+                               print("\"int\"");
+                       } else { // Generate normal classes if it's not a callback object
+                               String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
+                               String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
+                               print("\"" + prmType + "\"");
+                       }
+                       if (i != methParams.size() - 1) // Check if this is the last element
+                               print(", ");
+               }
+               println(" };");
+               print("int ___paramCB = ");
+               if (isArrayOrList)
+                       println(callbackParam + ".size();");
+               else
+                       println("1;");
+               // Generate array of parameter objects
+               print("void* paramObj[] = { ");
+               for (int i = 0; i < methParams.size(); i++) {
+                       String paramType = methPrmTypes.get(i);
+                       if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+                               print("&___paramCB");
+                       } else
+                               print(getSimpleIdentifier(methParams.get(i)));
+                       if (i != methParams.size() - 1)
+                               print(", ");
+               }
+               println(" };");
+               // Check if this is "void"
+               if (retType.equals("void")) {
+                       println("void* retObj = NULL;");
+                       println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
+               } else { // We do have a return value
+                       if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
+                               println(checkAndGetCplusType(retType) + " retVal;");
+                       else
+                               println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
+                       println("void* retObj = &retVal;");
+                       println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
+                       println("return retVal;");
                }
        }
 
@@ -1480,7 +1602,7 @@ public class IoTCompiler {
                // Generate array of parameter objects
                print("void* paramObj[] = { ");
                for (int i = 0; i < methParams.size(); i++) {
-                       print("&" + checkAndGetCplusType(getSimpleIdentifier(methParams.get(i))));
+                       print("&" + getSimpleIdentifier(methParams.get(i)));
                        // Check if this is the last element (don't print a comma)
                        if (i != methParams.size() - 1) {
                                print(", ");
@@ -1506,7 +1628,7 @@ public class IoTCompiler {
        /**
         * HELPER: writePropertiesCplusStub() writes the properties of the stub class
         */
-       private void writePropertiesCplusStub(String intface, String newIntface) {
+       private void writePropertiesCplusStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
 
                println("IoTRMICall *rmiCall;");
                //println("IoTRMIObject\t\t\t*rmiObj;");
@@ -1517,6 +1639,15 @@ public class IoTCompiler {
                println("const static int objectId = " + objId + ";");
                mapNewIntfaceObjId.put(newIntface, objId);
                mapIntfaceObjId.put(intface, objId++);
+               if (callbackExist) {
+               // We assume that each class only has one callback interface for now
+                       Iterator it = callbackClasses.iterator();
+                       String callbackType = (String) it.next();
+                       println("// Callback properties");
+                       println("IoTRMIObject *rmiObj;");
+                       println("vector<" + callbackType + "*> vecCallbackObj;");
+                       println("static int objIdCnt;");
+               }
                println("\n");
        }
 
@@ -1524,13 +1655,21 @@ public class IoTCompiler {
        /**
         * HELPER: writeConstructorCplusStub() writes the constructor of the stub class
         */
-       private void writeConstructorCplusStub(String newStubClass) {
+       private void writeConstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
 
                println(newStubClass + 
                        "(int _port, const char* _address, int _rev, bool* _bResult, vector<int> _ports) {");
                println("address = _address;");
                println("ports = _ports;");
                println("rmiCall = new IoTRMICall(_port, _address, _rev, _bResult);");
+               if (callbackExist) {
+                       println("objIdCnt = 0;");
+                       Iterator it = callbackClasses.iterator();
+                       String callbackType = (String) it.next();
+                       println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
+                       println("th1.detach();");
+                       println("___regCB();");
+               }
                println("}\n");
        }
 
@@ -1538,16 +1677,74 @@ public class IoTCompiler {
        /**
         * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
         */
-       private void writeDeconstructorCplusStub(String newStubClass) {
+       private void writeDeconstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
 
                println("~" + newStubClass + "() {");
                println("if (rmiCall != NULL) {");
                println("delete rmiCall;");
                println("rmiCall = NULL;");
                println("}");
+               if (callbackExist) {
+               // We assume that each class only has one callback interface for now
+                       println("if (rmiObj != NULL) {");
+                       println("delete rmiObj;");
+                       println("rmiObj = NULL;");
+                       println("}");
+                       Iterator it = callbackClasses.iterator();
+                       String callbackType = (String) it.next();
+                       println("for(" + callbackType + "* cb : vecCallbackObj) {");
+                       println("delete cb;");
+                       println("cb = NULL;");
+                       println("}");
+               }
                println("}");
                println("");
-               // Check if this is callback!!! and print "delete rmiObj and vecCBObj"
+       }
+
+
+       /**
+        * HELPER: writeInitCallbackCplusStub() writes the constructor of the stub class
+        */
+       private void writeInitCallbackCplusStub(String intface, InterfaceDecl intDecl) {
+
+               println("void ___initCallBack() {");
+               println("bool bResult = false;");
+               println("rmiObj = new IoTRMIObject(ports[0], &bResult);");
+               println("while (true) {");
+               println("char* method = rmiObj->getMethodBytes();");
+               println("int methodId = IoTRMIObject::getMethodId(method);");
+               println("int objId = IoTRMIObject::getObjectId(method);");
+               println("if (objId < vecCallbackObj.size()) {   // Check if still within range");
+               println(intface + "_CallbackSkeleton* skel = dynamic_cast<" + intface + 
+                       "_CallbackSkeleton*> (vecCallbackObj.at(objId));");
+               println("skel->invokeMethod(rmiObj);");
+               println("} else {");
+               println("cerr << \"Illegal object Id: \" << to_string(objId);");
+               // TODO: perhaps need to change this into "throw" to make it cleaner (allow stack unfolding)
+               println("exit(-1);");
+               println("}");
+               println("}");
+               println("}\n");
+       }
+
+
+       /**
+        * HELPER: writeInitCallbackSendInfoCplusStub() writes the constructor of the stub class
+        */
+       private void writeInitCallbackSendInfoCplusStub(InterfaceDecl intDecl) {
+
+               // Generate info sending part
+               println("void ___regCB() {");
+               println("int numParam = 3;");
+               String method = "___initCallBack()";
+               println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";");
+               println("string retType = \"void\";");
+               println("string paramCls[] = { \"int\", \"string\", \"int\" };");
+               println("int rev = 0;");
+               println("void* paramObj[] = { &ports[0], &address, &rev };");
+               println("void* retObj = NULL;");
+               println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
+               println("}\n");
        }
 
 
@@ -1571,24 +1768,30 @@ public class IoTCompiler {
                                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();
+                               if (callbackExist)      // Need thread library if this has callback
+                                       println("#include <thread>");
                                println("#include \"" + newIntface + ".hpp\""); println("");            
                                println("using namespace std;"); println("");
                                println("class " + newStubClass + " : public " + newIntface); println("{");
                                println("private:\n");
-                               writePropertiesCplusStub(intface, newIntface);
+                               writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses);
                                println("public:\n");
                                // Add default constructor and destructor
                                println(newStubClass + "() { }"); println("");
-                               writeConstructorCplusStub(newStubClass);
-                               writeDeconstructorCplusStub(newStubClass);
-                               DeclarationHandler decHandler = mapIntDeclHand.get(intface);
-                               InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+                               writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses);
+                               writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
                                // Write methods
-                               writeMethodCplusStub(intMeth.getValue(), intDecl);
+                               writeMethodCplusStub(methods, intDecl, callbackClasses);
                                print("}"); println(";");
                                println("#endif");
                                pw.close();
-                               System.out.println("IoTCompiler: Generated stub class " + newIntface + ".hpp...");
+                               System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
                        }
                }
        }
@@ -1597,11 +1800,23 @@ public class IoTCompiler {
        /**
         * HELPER: writePropertiesCplusCallbackStub() writes the properties of the stub class
         */
-       private void writePropertiesCplusCallbackStub(String intface, String newIntface) {
+       private void writePropertiesCplusCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
 
                println("IoTRMICall *rmiCall;");
                // Get the object Id
                println("static int objectId;");
+               if (callbackExist) {
+               // We assume that each class only has one callback interface for now
+                       Iterator it = callbackClasses.iterator();
+                       String callbackType = (String) it.next();
+                       println("// Callback properties");
+                       println("IoTRMIObject *rmiObj;");
+                       println("vector<" + callbackType + "*> vecCallbackObj;");
+                       println("static int objIdCnt;");
+                       // TODO: Need to initialize address and ports if we want to have callback-in-callback
+                       println("string address;");
+                       println("vector<int> ports;\n");
+               }
                println("\n");
        }
 
@@ -1609,11 +1824,18 @@ public class IoTCompiler {
        /**
         * HELPER: writeConstructorCplusCallbackStub() writes the constructor of the stub class
         */
-       private void writeConstructorCplusCallbackStub(String newStubClass) {
+       private void writeConstructorCplusCallbackStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
 
                println(newStubClass + "(IoTRMICall* _rmiCall, int _objectId) {");
                println("objectId = _objectId;");
                println("rmiCall = _rmiCall;");
+               if (callbackExist) {
+                       Iterator it = callbackClasses.iterator();
+                       String callbackType = (String) it.next();
+                       println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
+                       println("th1.detach();");
+                       println("___regCB();");
+               }
                println("}\n");
        }
 
@@ -1634,24 +1856,30 @@ public class IoTCompiler {
                                String newStubClass = newIntface + "_CallbackStub";
                                FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
                                pw = new PrintWriter(new BufferedWriter(fw));
+                               // 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();
                                // Write file headers
                                println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
                                println("#define _" + newStubClass.toUpperCase() + "_HPP__");
                                println("#include <iostream>");
+                               if (callbackExist)
+                                       println("#include <thread>");
                                println("#include \"" + newIntface + ".hpp\""); println("");            
                                println("using namespace std;"); println("");
                                println("class " + newStubClass + " : public " + newIntface); println("{");
                                println("private:\n");
-                               writePropertiesCplusCallbackStub(intface, newIntface);
+                               writePropertiesCplusCallbackStub(intface, newIntface, callbackExist, callbackClasses);
                                println("public:\n");
                                // Add default constructor and destructor
                                println(newStubClass + "() { }"); println("");
-                               writeConstructorCplusCallbackStub(newStubClass);
-                               writeDeconstructorCplusStub(newStubClass);
-                               DeclarationHandler decHandler = mapIntDeclHand.get(intface);
-                               InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+                               writeConstructorCplusCallbackStub(newStubClass, callbackExist, callbackClasses);
+                               writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
                                // Write methods
-                               writeMethodCplusStub(intMeth.getValue(), intDecl);
+                               writeMethodCplusStub(methods, intDecl, callbackClasses);
                                print("}"); println(";");
                                println("#endif");
                                pw.close();
@@ -1664,11 +1892,20 @@ public class IoTCompiler {
        /**
         * HELPER: writePropertiesCplusSkeleton() writes the properties of the skeleton class
         */
-       private void writePropertiesCplusSkeleton(String intface) {
+       private void writePropertiesCplusSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
 
                println(intface + " *mainObj;");
                //println("private int ports;");
-               //println("private IoTRMICall rmiCall;");
+               // Callback
+               if (callbackExist) {
+                       Iterator it = callbackClasses.iterator();
+                       String callbackType = (String) it.next();
+                       String exchangeType = checkAndGetParamClass(callbackType);
+                       println("// Callback properties");
+                       println("static int objIdCnt;");
+                       println("vector<" + exchangeType + "*> vecCallbackObj;");
+                       println("IoTRMICall *rmiCall;");
+               }
                println("IoTRMIObject *rmiObj;\n");
                // Keep track of object Ids of all stubs registered to this interface
                Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
@@ -1678,8 +1915,6 @@ public class IoTCompiler {
 //                     println("const static int object" + newObjectId + "Id = " + 
 //                             newObjectId + ";\t//" + newIntface);
                }
-               // TODO: CALLBACKS!
-               // TODO: code the set of allowed functions here
                println("\n");
        }
 
@@ -1687,14 +1922,18 @@ public class IoTCompiler {
        /**
         * HELPER: writeConstructorCplusSkeleton() writes the constructor of the skeleton class
         */
-       private void writeConstructorCplusSkeleton(String newSkelClass, String intface) {
+       private void writeConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist) {
 
                println(newSkelClass + "(" + intface + " *_mainObj, int _port) {");
                println("bool _bResult = false;");
                println("mainObj = _mainObj;");
                println("rmiObj = new IoTRMIObject(_port, &_bResult);");
+               // Callback
+               if (callbackExist) {
+                       println("objIdCnt = 0;");
+               }
                //println("set0Allowed = Arrays.asList(object0Permission);");
-               //println("___waitRequestInvokeMethod();");
+               println("___waitRequestInvokeMethod();");
                println("}\n");
        }
 
@@ -1702,16 +1941,29 @@ public class IoTCompiler {
        /**
         * HELPER: writeDeconstructorCplusSkeleton() writes the deconstructor of the skeleton class
         */
-       private void writeDeconstructorCplusSkeleton(String newSkelClass) {
+       private void writeDeconstructorCplusSkeleton(String newSkelClass, boolean callbackExist, Set<String> callbackClasses) {
 
                println("~" + newSkelClass + "() {");
                println("if (rmiObj != NULL) {");
                println("delete rmiObj;");
                println("rmiObj = NULL;");
                println("}");
+               if (callbackExist) {
+               // We assume that each class only has one callback interface for now
+                       println("if (rmiCall != NULL) {");
+                       println("delete rmiCall;");
+                       println("rmiCall = NULL;");
+                       println("}");
+                       Iterator it = callbackClasses.iterator();
+                       String callbackType = (String) it.next();
+                       String exchangeType = checkAndGetParamClass(callbackType);
+                       println("for(" + exchangeType + "* cb : vecCallbackObj) {");
+                       println("delete cb;");
+                       println("cb = NULL;");
+                       println("}");
+               }
                println("}");
                println("");
-               // Check if this is callback!!! and print "delete rmiObj and vecCBObj"
        }
 
 
@@ -1736,10 +1988,32 @@ public class IoTCompiler {
        }
 
 
+       /**
+        * HELPER: writeInitCallbackCplusSkeleton() writes the init callback method for skeleton class
+        */
+       private void writeInitCallbackCplusSkeleton(boolean callbackSkeleton) {
+
+               // This is a callback skeleton generation
+               if (callbackSkeleton)
+                       println("void ___regCB(IoTRMIObject* rmiObj) {");
+               else
+                       println("void ___regCB() {");
+               println("int numParam = 3;");
+               println("int param1 = 0;");
+               println("string param2 = \"\";");
+               println("int param3 = 0;");
+               println("void* paramObj[] = { &param1, &param2, &param3 };");
+               println("bool bResult = false;");
+               println("rmiCall = new IoTRMICall(param1, param2.c_str(), param3, &bResult);");
+               println("}\n");
+       }
+
+
        /**
         * HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class
         */
-       private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
+       private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, 
+                       Set<String> callbackClasses, boolean callbackSkeleton) {
 
                for (String method : methods) {
 
@@ -1748,9 +2022,16 @@ public class IoTCompiler {
                        String methodId = intDecl.getMethodId(method);
                        String methodType = checkAndGetCplusType(intDecl.getMethodType(method));
                        print(methodType + " " + methodId + "(");
+                       boolean isCallbackMethod = false;
+                       String callbackType = null;
                        for (int i = 0; i < methParams.size(); i++) {
 
-                               String paramType = checkAndGetParamClass(methPrmTypes.get(i), true);
+                               String origParamType = methPrmTypes.get(i);
+                               if (callbackClasses.contains(origParamType)) { // Check if this has callback object
+                                       isCallbackMethod = true;
+                                       callbackType = origParamType;   
+                               }
+                               String paramType = checkAndGetParamClass(methPrmTypes.get(i));
                                String methPrmType = checkAndGetCplusType(paramType);
                                String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
                                print(methParamComplete);
@@ -1763,6 +2044,56 @@ public class IoTCompiler {
                        // Now, write the body of skeleton!
                        writeStdMethodBodyCplusSkeleton(methParams, methodId, intDecl.getMethodType(method));
                        println("}\n");
+                       if (isCallbackMethod)
+                               writeInitCallbackCplusSkeleton(callbackSkeleton);
+               }
+       }
+
+
+       /**
+        * HELPER: writeCallbackCplusNumStubs() writes the numStubs variable
+        */
+       private void writeCallbackCplusNumStubs(List<String> methParams, List<String> methPrmTypes, String callbackType) {
+
+               for (int i = 0; i < methParams.size(); i++) {
+                       String paramType = methPrmTypes.get(i);
+                       String param = methParams.get(i);
+                       //if (callbackType.equals(paramType)) {
+                       if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+                               String exchParamType = checkAndGetParamClass(paramType);
+                               // Print array if this is array or list if this is a list of callback objects
+                               println("int numStubs" + i + " = 0;");
+                       }
+               }
+       }
+
+
+       /**
+        * HELPER: writeCallbackCplusStubGeneration() writes the callback stub generation part
+        */
+       private void writeCallbackCplusStubGeneration(List<String> methParams, List<String> methPrmTypes, String callbackType) {
+
+               // Iterate over callback objects
+               for (int i = 0; i < methParams.size(); i++) {
+                       String paramType = methPrmTypes.get(i);
+                       String param = methParams.get(i);
+                       // Generate a loop if needed
+                       if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+                               String exchParamType = checkAndGetParamClass(paramType);
+                               if (isArrayOrList(paramType, param)) {
+                                       println("vector<" + exchParamType + "> stub;");
+                                       println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
+                                       println(exchParamType + "* cb" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
+                                       println("stub" + i + ".push_back(cb);");
+                                       println("vecCallbackObj.push_back(cb);");
+                                       println("objIdCnt++;");
+                                       println("}");
+                               } else {
+                                       println(exchParamType + "* stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
+                                       println("vecCallbackObj.push_back(stub" + i + ");");
+                                       println("objIdCnt++;");
+                               }
+                       }
                }
        }
 
@@ -1771,42 +2102,66 @@ public class IoTCompiler {
         * HELPER: writeStdMethodHelperBodyCplusSkeleton() writes the standard method body helper in the skeleton class
         */
        private void writeStdMethodHelperBodyCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
-                       List<String> methPrmTypes, String method, String methodId) {
+                       List<String> methPrmTypes, String method, String methodId, Set<String> callbackClasses) {
 
                // Generate array of parameter types
+               boolean isCallbackMethod = false;
+               String callbackType = null;
                print("string paramCls[] = { ");
                for (int i = 0; i < methParams.size(); i++) {
-                       String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
-                       String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
-                       print("\"" + paramType + "\"");
+                       String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+                       if (callbackClasses.contains(paramType)) {
+                               isCallbackMethod = true;
+                               callbackType = paramType;
+                               print("\"int\"");
+                       } else {        // Generate normal classes if it's not a callback object
+                               String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
+                               String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
+                               print("\"" + prmType + "\"");
+                       }
                        if (i != methParams.size() - 1) {
                                print(", ");
                        }
                }
                println(" };");
                println("int numParam = " + methParams.size() + ";");
+               if (isCallbackMethod)
+                       writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType);
                // Generate parameters
                for (int i = 0; i < methParams.size(); i++) {
-                       String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
-                       String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
-                       println(methParamComplete + ";");
+                       String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+                       if (!callbackClasses.contains(paramType)) {                     
+                               String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
+                               String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
+                               println(methParamComplete + ";");
+                       }
                }
                // Generate array of parameter objects
                print("void* paramObj[] = { ");
                for (int i = 0; i < methParams.size(); i++) {
-                       print("&" + getSimpleIdentifier(methParams.get(i)));
+                       String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+                       if (callbackClasses.contains(paramType))
+                               print("&numStubs" + i);
+                       else
+                               print("&" + getSimpleIdentifier(methParams.get(i)));
                        if (i != methParams.size() - 1) {
                                print(", ");
                        }
                }
                println(" };");
                println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
+               if (isCallbackMethod)
+                       writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType);
                String retType = intDecl.getMethodType(method);
                // Check if this is "void"
                if (retType.equals("void")) {
                        print(methodId + "(");
                        for (int i = 0; i < methParams.size(); i++) {
-                               print(getSimpleIdentifier(methParams.get(i)));
+                               String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+                               if (callbackClasses.contains(paramType))
+                                       print("stub" + i);
+                               else
+                                       print(getSimpleIdentifier(methParams.get(i)));
                                if (i != methParams.size() - 1) {
                                        print(", ");
                                }
@@ -1815,7 +2170,11 @@ public class IoTCompiler {
                } else { // We do have a return value
                        print(checkAndGetCplusType(retType) + " retVal = " + methodId + "(");
                        for (int i = 0; i < methParams.size(); i++) {
-                               print(getSimpleIdentifier(methParams.get(i)));
+                               String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+                               if (callbackClasses.contains(paramType))
+                                       print("stub" + i);
+                               else
+                                       print(getSimpleIdentifier(methParams.get(i)));
                                if (i != methParams.size() - 1) {
                                        print(", ");
                                }
@@ -1831,7 +2190,7 @@ public class IoTCompiler {
        /**
         * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class
         */
-       private void writeMethodHelperCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
+       private void writeMethodHelperCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
 
                // Use this set to handle two same methodIds
                Set<String> uniqueMethodIds = new HashSet<String>();
@@ -1850,7 +2209,7 @@ public class IoTCompiler {
                        String retType = intDecl.getMethodType(method);
                        println(helperMethod + "() {");
                        // Now, write the helper body of skeleton!
-                       writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId);
+                       writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
                        println("}\n");
                }
        }
@@ -1859,7 +2218,7 @@ public class IoTCompiler {
        /**
         * HELPER: writeCplusWaitRequestInvokeMethod() writes the main loop of the skeleton class
         */
-       private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl) {
+       private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist) {
 
                // Use this set to handle two same methodIds
                Set<String> uniqueMethodIds = new HashSet<String>();
@@ -1883,6 +2242,12 @@ public class IoTCompiler {
                                uniqueMethodIds.add(methodId);
                        println(helperMethod + "(); break;");
                }
+               String method = "___initCallBack()";
+               // Print case -9999 (callback handler) if callback exists
+               if (callbackExist) {
+                       int methodId = intDecl.getHelperMethodNumId(method);
+                       println("case " + methodId + ": ___regCB(); break;");
+               }
                println("default: ");
                println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
                println("throw exception();");
@@ -1913,27 +2278,30 @@ public class IoTCompiler {
                        DeclarationHandler decHandler = mapIntDeclHand.get(intface);
                        InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
                        List<String> methods = intDecl.getMethods();
-                       Set<String> includeClasses = getIncludeClasses(methods, intDecl);
+                       Set<String> includeClasses = getIncludeClasses(methods, intDecl, true);
                        List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
-                       List<String> allIncludeClasses = getAllImportClasses(stdIncludeClasses, includeClasses);
-                       printIncludeStatements(allIncludeClasses); println("");                 
+                       List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
+                       printIncludeStatements(allIncludeClasses); 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);
+                       writePropertiesCplusSkeleton(intface, callbackExist, callbackClasses);
                        println("public:\n");
                        // Write constructor
-                       writeConstructorCplusSkeleton(newSkelClass, intface);
+                       writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist);
                        // Write deconstructor
-                       writeDeconstructorCplusSkeleton(newSkelClass);
+                       writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
                        // Write methods
-                       writeMethodCplusSkeleton(methods, intDecl);
+                       writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false);
                        // Write method helper
-                       writeMethodHelperCplusSkeleton(methods, intDecl);
+                       writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses);
                        // Write waitRequestInvokeMethod() - main loop
-                       writeCplusWaitRequestInvokeMethod(methods, intDecl);
+                       writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist);
                        println("};");
                        println("#endif");
                        pw.close();
@@ -1945,12 +2313,21 @@ public class IoTCompiler {
        /**
         * HELPER: writePropertiesCplusCallbackSkeleton() writes the properties of the callback skeleton class
         */
-       private void writePropertiesCplusCallbackSkeleton(String intface) {
+       private void writePropertiesCplusCallbackSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
 
                println(intface + " *mainObj;");
-               //println("IoTRMIObject *rmiObj;\n");
                // Keep track of object Ids of all stubs registered to this interface
                println("static int objectId;");
+               // Callback
+               if (callbackExist) {
+                       Iterator it = callbackClasses.iterator();
+                       String callbackType = (String) it.next();
+                       String exchangeType = checkAndGetParamClass(callbackType);
+                       println("// Callback properties");
+                       println("IoTRMICall* rmiCall;");
+                       println("vector<" + exchangeType + "*> vecCallbackObj;");
+                       println("static int objIdCnt;");
+               }
                println("\n");
        }
 
@@ -1958,19 +2335,50 @@ public class IoTCompiler {
        /**
         * HELPER: writeConstructorCplusCallbackSkeleton() writes the constructor of the skeleton class
         */
-       private void writeConstructorCplusCallbackSkeleton(String newSkelClass, String intface) {
+       private void writeConstructorCplusCallbackSkeleton(String newSkelClass, String intface, boolean callbackExist) {
 
                println(newSkelClass + "(" + intface + " *_mainObj, int _objectId) {");
                println("mainObj = _mainObj;");
                println("objectId = _objectId;");
+               // Callback
+               if (callbackExist) {
+                       println("objIdCnt = 0;");
+               }
                println("}\n");
        }
 
 
+       /**
+        * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
+        */
+       private void writeDeconstructorCplusCallbackSkeleton(String newStubClass, boolean callbackExist, 
+                       Set<String> callbackClasses) {
+
+               println("~" + newStubClass + "() {");
+               if (callbackExist) {
+               // We assume that each class only has one callback interface for now
+                       println("if (rmiCall != NULL) {");
+                       println("delete rmiCall;");
+                       println("rmiCall = NULL;");
+                       println("}");
+                       Iterator it = callbackClasses.iterator();
+                       String callbackType = (String) it.next();
+                       String exchangeType = checkAndGetParamClass(callbackType);
+                       println("for(" + exchangeType + "* cb : vecCallbackObj) {");
+                       println("delete cb;");
+                       println("cb = NULL;");
+                       println("}");
+               }
+               println("}");
+               println("");
+       }
+
+
        /**
         * HELPER: writeMethodHelperCplusCallbackSkeleton() writes the method helper of the callback skeleton class
         */
-       private void writeMethodHelperCplusCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
+       private void writeMethodHelperCplusCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl, 
+                       Set<String> callbackClasses) {
 
                // Use this set to handle two same methodIds
                Set<String> uniqueMethodIds = new HashSet<String>();
@@ -1989,7 +2397,7 @@ public class IoTCompiler {
                        String retType = intDecl.getMethodType(method);
                        println(helperMethod + "(IoTRMIObject* rmiObj) {");
                        // Now, write the helper body of skeleton!
-                       writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId);
+                       writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
                        println("}\n");
                }
        }
@@ -1998,7 +2406,8 @@ public class IoTCompiler {
        /**
         * HELPER: writeCplusCallbackWaitRequestInvokeMethod() writes the main loop of the skeleton class
         */
-       private void writeCplusCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl) {
+       private void writeCplusCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, 
+                       boolean callbackExist) {
 
                // Use this set to handle two same methodIds
                Set<String> uniqueMethodIds = new HashSet<String>();
@@ -2019,6 +2428,12 @@ public class IoTCompiler {
                                uniqueMethodIds.add(methodId);
                        println(helperMethod + "(rmiObj); break;");
                }
+               String method = "___initCallBack()";
+               // Print case -9999 (callback handler) if callback exists
+               if (callbackExist) {
+                       int methodId = intDecl.getHelperMethodNumId(method);
+                       println("case " + methodId + ": ___regCB(rmiObj); break;");
+               }
                println("default: ");
                println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
                println("throw exception();");
@@ -2049,27 +2464,30 @@ public class IoTCompiler {
                        DeclarationHandler decHandler = mapIntDeclHand.get(intface);
                        InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
                        List<String> methods = intDecl.getMethods();
-                       Set<String> includeClasses = getIncludeClasses(methods, intDecl);
+                       Set<String> includeClasses = getIncludeClasses(methods, intDecl, true);
                        List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
-                       List<String> allIncludeClasses = getAllImportClasses(stdIncludeClasses, includeClasses);
+                       List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
                        printIncludeStatements(allIncludeClasses); println("");                 
+                       // Find out if there are callback objects
+                       Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+                       boolean callbackExist = !callbackClasses.isEmpty();
                        println("using namespace std;\n");
                        // Write class header
                        println("class " + newSkelClass + " : public " + intface); println("{");
                        println("private:\n");
                        // Write properties
-                       writePropertiesCplusCallbackSkeleton(intface);
+                       writePropertiesCplusCallbackSkeleton(intface, callbackExist, callbackClasses);
                        println("public:\n");
                        // Write constructor
-                       writeConstructorCplusCallbackSkeleton(newSkelClass, intface);
+                       writeConstructorCplusCallbackSkeleton(newSkelClass, intface, callbackExist);
                        // Write deconstructor
-                       //writeDeconstructorCplusSkeleton(newSkelClass);
+                       writeDeconstructorCplusCallbackSkeleton(newSkelClass, callbackExist, callbackClasses);
                        // Write methods
-                       writeMethodCplusSkeleton(methods, intDecl);
+                       writeMethodCplusSkeleton(methods, intDecl, callbackClasses, true);
                        // Write method helper
-                       writeMethodHelperCplusCallbackSkeleton(methods, intDecl);
+                       writeMethodHelperCplusCallbackSkeleton(methods, intDecl, callbackClasses);
                        // Write waitRequestInvokeMethod() - main loop
-                       writeCplusCallbackWaitRequestInvokeMethod(methods, intDecl);
+                       writeCplusCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
                        println("};");
                        println("#endif");
                        pw.close();
@@ -2222,7 +2640,7 @@ public class IoTCompiler {
        private void println(String str) {
                if (newline) {
                        int tab = tablevel;
-                       if (str.equals("}"))
+                       if (str.contains("}") && !str.contains("{"))
                                tab--;
                        for(int i=0; i<tab; i++)
                                pw.print("\t");
@@ -2234,6 +2652,7 @@ public class IoTCompiler {
 
 
        private void updatetabbing(String str) {
+
                tablevel+=count(str,'{')-count(str,'}');
        }
 
@@ -2359,17 +2778,17 @@ public class IoTCompiler {
 
 
        // Generate a set of standard classes for import statements
-       private List<String> getAllImportClasses(Collection<String> stdImportClasses, Collection<String> importClasses) {
+       private List<String> getAllLibClasses(Collection<String> stdLibClasses, Collection<String> libClasses) {
 
-               List<String> allImportClasses = new ArrayList<String>(stdImportClasses);
+               List<String> allLibClasses = new ArrayList<String>(stdLibClasses);
                // Iterate over the list of import classes
-               for (String str : importClasses) {
-                       if (!stdImportClasses.contains(str)) {
-                               stdImportClasses.add(str);
+               for (String str : libClasses) {
+                       if (!allLibClasses.contains(str)) {
+                               allLibClasses.add(str);
                        }
                }
 
-               return allImportClasses;
+               return allLibClasses;
        }
 
 
@@ -2393,7 +2812,7 @@ public class IoTCompiler {
 
 
        // Generate a set of classes for include statements
-       private Set<String> getIncludeClasses(Collection<String> methods, InterfaceDecl intDecl) {
+       private Set<String> getIncludeClasses(Collection<String> methods, InterfaceDecl intDecl, boolean needExchange) {
 
                Set<String> includeClasses = new HashSet<String>();
                for (String method : methods) {
@@ -2407,7 +2826,14 @@ public class IoTCompiler {
                                if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
                                        includeClasses.add("<" + getNonPrimitiveCplusClass(simpleType) + ">");
                                } else if (getParamCategory(simpleType) == ParamCategory.USERDEFINED) {
-                                       includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\"");
+                                       // For original interface, we need it exchanged... not for stub interfaces
+                                       if (needExchange) {
+                                               includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\"");
+                                               includeClasses.add("\"" + exchangeParamType(simpleType) + "_CallbackStub.hpp\"");
+                                       } else {
+                                               includeClasses.add("\"" + simpleType + ".hpp\"");
+                                               includeClasses.add("\"" + simpleType + "_CallbackSkeleton.hpp\"");
+                                       }
                                } else if (param.contains("[]")) {
                                // Check if this is array for C++; translate into vector
                                        includeClasses.add("<vector>");
@@ -2504,9 +2930,12 @@ public class IoTCompiler {
                                return cplusTemplate;
                        } else
                                return getNonPrimitiveCplusClass(paramType);
+               } else if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
+                       return paramType + "*";
                } else
                        // Just return it as is if it's not non-primitives
                        return paramType;
+                       //return checkAndGetParamClass(paramType, true);
        }
 
 
@@ -2619,15 +3048,11 @@ public class IoTCompiler {
 
 
        // Get the right type for a callback object
-       private String checkAndGetParamClass(String paramType, boolean needPtr) {
+       private String checkAndGetParamClass(String paramType) {
 
                // Check if this is generics
                if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
-                       // If true then return with pointer (C++)
-                       if (needPtr)
-                               return exchangeParamType(paramType) + "*";
-                       else    // Java, so no pointer needed
-                               return exchangeParamType(paramType);
+                       return exchangeParamType(paramType);
                } else
                        return paramType;
        }