/**
  * check the conditions side effect: increment error number
  *
  * @param cunit the compilation unit
  */
 protected void checkCondition(JCompilationUnit cunit) {
   try {
     cunit.analyseConditions();
   } catch (PositionedError e) {
     reportTrouble(e);
   }
 }
 /**
  * check that interface of a given compilation unit is correct side effect: increment error number
  *
  * @param cunit the compilation unit
  */
 protected void checkInitializers(JCompilationUnit cunit) {
   try {
     cunit.checkInitializers(this);
   } catch (PositionedError e) {
     reportTrouble(e);
   }
 }
 /**
  * check that body of a given compilation unit is correct side effect: increment error number
  *
  * @param cunit the compilation unit
  */
 protected void checkBody(JCompilationUnit cunit) {
   try {
     cunit.checkBody(this);
     // Log.verbose("body checked: "+cunit.getFileName());
   } catch (PositionedError e) {
     reportTrouble(e);
   }
 }
  /**
   * Generates the code from an array of compilation unit and a destination
   *
   * @param destination the directory where to write classfiles
   */
  public void genCode(TypeFactory factory, JCompilationUnit cus[]) {
    ArrayList<CSourceClass> classes = new ArrayList<CSourceClass>(100);

    for (JCompilationUnit cu : cus) {
      classes.addAll(cu.getContext().getAndCleanSourceClasses());
    }

    BytecodeOptimizer optimizer = new BytecodeOptimizer(options.optimize);

    try {
      //        	int
      //        		javaTypeCounter = 0,
      //        		caesarTypeCounter = 0,
      //        		abstractImplicitTypeCounter = 0,
      //        		topLevelCClassCounter = 0,
      //        		explicitCaesarTypeCounter = 0;

      for (CSourceClass clazz : classes) {

        //            	if(clazz.isMixinInterface()) {
        //            		caesarTypeCounter++;
        //
        //            		if(!clazz.isImplicit()) {
        //                		explicitCaesarTypeCounter++;
        //                		if(!clazz.isNested()) {
        //                			topLevelCClassCounter++;
        //                		}
        //                	}
        //            	}
        //            	else if(!clazz.isMixin() && !clazz.isImplicit()) {
        //            		javaTypeCounter++;
        //            	}

        // Implicit abstract classes are not needed because they are never
        // instantiated and cannot be super classes of other classes
        if (!clazz.isMixinInterface() && clazz.isImplicit() && clazz.isAbstract()) {
          continue;
        }

        // IVICA
        // removed: classes[count].genCode(optimizer, options.destination, factory);
        ClassInfo classInfo = clazz.genClassInfo(optimizer, options.destination, factory);

        classInfo.write(options.destination);
        byte[] codeBuf = classInfo.getByteArray();

        byteCodeMap.addSourceClass(clazz, codeBuf);
        // IVICA:END

        // Log.verbose("class file generated: "+classes[count].getQualifiedName());
      }

      //            System.out.println("JAVA TYPES              : "+javaTypeCounter);
      //            System.out.println("CAESAR TYPES            : "+caesarTypeCounter);
      //            System.out.println("IMPLICIT ABSTRACT TYPES : "+abstractImplicitTypeCounter);
      //            System.out.println("EXPLICIT CAESAR TYPES   : "+explicitCaesarTypeCounter);
      //            System.out.println("TOP-LEVEL CAESAR TYPES  : "+topLevelCClassCounter);
    } catch (PositionedError e) {
      reportTrouble(e);
    } catch (ClassFileFormatException e) {
      e.printStackTrace();
      reportTrouble(new UnpositionedError(Messages.FORMATTED_ERROR, e.getMessage()));
    } catch (IOException e) {
      reportTrouble(
          new UnpositionedError(
              Messages.IO_EXCEPTION,
              "classfile",
              // !!!FIXME !!!
              e.getMessage()));
    }
  }