public int createAssembly() throws IOException {
        logger = Log.getLogger();
        logger.debug("Packing ...");
        
        removeOldAssemblies(targetLocation);
        
        String loaderName = J2JSCompiler.compiler.getTargetPlatform().toLowerCase();
        Writer writer;
        
        if ("javascript".equals(loaderName)) {
            writer = new FileWriter(targetLocation);
            pipeFileToStream(writer, "javascript/loaders/" + loaderName + ".js");
        } else {
            targetLocation.mkdirs();
            writer = new JunkWriter(targetLocation);
        }
        writer.write("// Assembly generated by j2js " + Utils.getVersion() + " on " + Utils.currentTimeStamp() + "\n");
        pipeFileToStream(writer, "javascript/runtime.js");
        writer.write("j2js.assemblyVersion = 'j2js Assembly " + targetLocation.getName() + "@" + Utils.currentTimeStamp() + "';\n");
        
        writer.write("j2js.userData = {};\n");
        
        int classCount = 0;
        for (ClassUnit fileUnit : project.getClasses()) {
            if (!fileUnit.isTainted()) continue;
            writer.write("j2js.");
            writer.write(DECLARECLASS);
            writer.write("(\"" + fileUnit.getSignature() + "\"");
            writer.write(", " + fileUnit.getSignature().getId());
            writer.write(");\n");
            classCount++;
        }
        
        project.currentGeneratedMethods = 0;
        
        if (J2JSCompiler.compiler.getSingleEntryPoint() != null) {
            Signature signature = project.getSignature(J2JSCompiler.compiler.getSingleEntryPoint());
            ClassUnit clazz = project.getClassUnit(signature.className());
            clazz.write(0, writer);
        } else {
            ClassUnit object = project.getJavaLangObject();
            object.write(0, writer);
 
            for (ClassUnit cu : project.getClasses()) {
                // TODO Interface: Generate them nicely.
                if (cu.isInterface) {
                    cu.write(0, writer);
                }
            }
            
//            for (ClassUnit cu : project.getClasses()) {
//                if (cu.isInterface && cu.getInterfaces().size() != 0) {
//                    cu.write(0, writer);
//                }
//            }
        }
        
        if (getProject().getOrCreateClassUnit("java.lang.String").isTainted()) {
            writer.write("String.prototype.clazz = j2js.forName('java.lang.String');\n");
        }

        writer.write("j2js.onLoad('" + entryPointClassName + "#main(java.lang.String[])void');\n");
        
//        String resourcePath = J2JSCompiler.compiler.resourcePath;
//        if (resourcePath != null) {
//            resolveResources(new File(J2JSCompiler.compiler.getBaseDir(), resourcePath), writer);
//        }

        writer.close();
        
        if ("web".equals(loaderName)) {
            Writer loader = new FileWriter(new File(targetLocation, "/0.js"));
            loader.write("var j2js = {assemblySize:");
            loader.write(Integer.toString(((JunkWriter) writer).getSize()));
            loader.write("};\n");
            pipeFileToStream(loader, "javascript/loaders/" + loaderName + ".js");
            loader.close();
        }

        return project.currentGeneratedMethods;
    }