@Override
    public void process(CompilationUnitDeclaration cud, int i) {
      super.process(cud, i);
      ClassFile[] classFiles = cud.compilationResult().getClassFiles();
      Map<ClassFile, CompiledClass> results = new LinkedHashMap<ClassFile, CompiledClass>();
      for (ClassFile classFile : classFiles) {
        createCompiledClass(classFile, results);
      }
      List<CompiledClass> compiledClasses = new ArrayList<CompiledClass>(results.values());
      addBinaryTypes(compiledClasses);

      ICompilationUnit icu = cud.compilationResult().compilationUnit;
      Adapter adapter = (Adapter) icu;
      CompilationUnitBuilder builder = adapter.getBuilder();

      // TODO this code was added for the arquillian gwt extension
      if (cud.types != null) {
        for (TypeDeclaration type : cud.types) {
          if (type.methods != null) {
            if (isAnnotationPresent(RunWith.class.getSimpleName(), type.annotations)) {
              Set<AbstractMethodDeclaration> filteredMethods =
                  new HashSet<AbstractMethodDeclaration>();
              boolean match = false;
              for (AbstractMethodDeclaration decl : type.methods) {
                if (decl.annotations != null) {
                  // TODO make this configurable
                  if ((isAnnotationPresent(RunAsGwtClient.class.getSimpleName(), decl.annotations)
                          || isAnnotationPresent(
                              RunAsGwtClient.class.getSimpleName(), type.annotations))
                      && !isAnnotationPresent(Deployment.class.getSimpleName(), decl.annotations)) {
                    filteredMethods.add(decl);
                  } else {
                    match = true;
                    System.out.println("Ignoring non-translatable method:\n" + decl.toString());
                  }
                }
              }
              if (match) {
                type.methods =
                    filteredMethods.toArray(new AbstractMethodDeclaration[filteredMethods.size()]);
              }
            }
          }
        }
      }

      processor.process(builder, cud, compiledClasses);
    }
 /** Recursively creates enclosing types first. */
 private void createCompiledClass(ClassFile classFile, Map<ClassFile, CompiledClass> results) {
   if (results.containsKey(classFile)) {
     // Already created.
     return;
   }
   CompiledClass enclosingClass = null;
   if (classFile.enclosingClassFile != null) {
     ClassFile enclosingClassFile = classFile.enclosingClassFile;
     createCompiledClass(enclosingClassFile, results);
     enclosingClass = results.get(enclosingClassFile);
     assert enclosingClass != null;
   }
   String internalName = CharOperation.charToString(classFile.fileName());
   CompiledClass result =
       new CompiledClass(
           classFile.getBytes(), enclosingClass, isLocalType(classFile), internalName);
   results.put(classFile, result);
 }
 private void addBinaryTypes(Collection<CompiledClass> compiledClasses) {
   for (CompiledClass cc : compiledClasses) {
     binaryTypes.put(cc.getInternalName(), cc);
   }
 }