Remove the pre-GwtAstBuilder compile chain.

- WebModeCompilerFrontEnd
- BuildTypeMap
- GenerateJavaAST

http://gwt-code-reviews.appspot.com/1465805/


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10490 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/GwtAstBuilderUtil.java b/dev/core/src/com/google/gwt/dev/GwtAstBuilderUtil.java
deleted file mode 100644
index 18c66cf..0000000
--- a/dev/core/src/com/google/gwt/dev/GwtAstBuilderUtil.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev;
-
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.linker.ArtifactSet;
-import com.google.gwt.dev.cfg.ModuleDef;
-import com.google.gwt.dev.javac.CompilationState;
-import com.google.gwt.dev.javac.CompilationUnit;
-import com.google.gwt.dev.javac.StandardGeneratorContext;
-import com.google.gwt.dev.jdt.RebindPermutationOracle;
-import com.google.gwt.dev.jdt.WebModeCompilerFrontEnd;
-import com.google.gwt.dev.jjs.CorrelationFactory;
-import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory;
-import com.google.gwt.dev.jjs.JJSOptionsImpl;
-import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.jjs.impl.BuildTypeMap;
-import com.google.gwt.dev.jjs.impl.GenerateJavaAST;
-import com.google.gwt.dev.jjs.impl.GwtAstBuilder;
-import com.google.gwt.dev.jjs.impl.TypeLinker;
-import com.google.gwt.dev.jjs.impl.TypeMap;
-import com.google.gwt.dev.js.ast.JsProgram;
-
-import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Used by GwtAstBuilderTest.
- * 
- * TODO(zundel): remove after GwtAstBuilderTest is obsolete.
- */
-public class GwtAstBuilderUtil {
-
-  public static JProgram buildGenerateJavaAst(final TreeLogger logger, ModuleDef module,
-      final CompilationState compilationState) throws UnableToCompleteException {
-    final StandardGeneratorContext genCtx =
-        new StandardGeneratorContext(compilationState, module, null, new ArtifactSet(), true);
-    RebindPermutationOracle rpo = new RebindPermutationOracle() {
-      public void clear() {
-      }
-
-      public String[] getAllPossibleRebindAnswers(TreeLogger logger, String sourceTypeName)
-          throws UnableToCompleteException {
-        return new String[0];
-      }
-
-      public CompilationState getCompilationState() {
-        return compilationState;
-      }
-
-      public StandardGeneratorContext getGeneratorContext() {
-        return genCtx;
-      }
-    };
-
-    List<String> allRootTypes = new ArrayList<String>();
-    for (CompilationUnit unit : compilationState.getCompilationUnits()) {
-      allRootTypes.add(unit.getTypeName());
-    }
-    CompilationUnitDeclaration[] goldenCuds =
-        WebModeCompilerFrontEnd.getCompilationUnitDeclarations(logger, allRootTypes
-            .toArray(new String[allRootTypes.size()]), rpo, TypeLinker.NULL_TYPE_LINKER).compiledUnits;
-
-    CorrelationFactory correlator = DummyCorrelationFactory.INSTANCE;
-    JsProgram jsProgram = new JsProgram(correlator);
-    JProgram jprogram = new JProgram(correlator);
-    TypeMap typeMap = new TypeMap(jprogram);
-    TypeDeclaration[] allTypeDeclarations = BuildTypeMap.exec(typeMap, goldenCuds, jsProgram);
-    // BuildTypeMap can uncover syntactic JSNI errors; report & abort
-    checkForErrors(logger, goldenCuds);
-
-    // Compute all super type/sub type info
-    jprogram.typeOracle.computeBeforeAST();
-
-    // (2) Create our own Java AST from the JDT AST.
-    GenerateJavaAST.exec(allTypeDeclarations, typeMap, jprogram, new JJSOptionsImpl());
-
-    // GenerateJavaAST can uncover semantic JSNI errors; report & abort
-    checkForErrors(logger, goldenCuds);
-    return jprogram;
-  }
-
-  public static CompilationState buildGwtAst(TreeLogger logger, ModuleDef module)
-      throws UnableToCompleteException {
-    boolean gwtAstWasEnabled = GwtAstBuilder.ENABLED;
-    try {
-      GwtAstBuilder.ENABLED = true;
-      // Avoid call to System.currentTimeMillis() if not logging INFO level
-      long start = logger.isLoggable(TreeLogger.INFO) ? System.currentTimeMillis() : 0L;
-      final CompilationState compilationState = module.getCompilationState(logger);
-      if (logger.isLoggable(TreeLogger.INFO)) {
-        logger.log(TreeLogger.INFO, (System.currentTimeMillis() - start)
-            + " time to get compilation state");
-      }
-      return compilationState;
-    } finally {
-      GwtAstBuilder.ENABLED = gwtAstWasEnabled;
-    }
-  }
-
-  private static void checkForErrors(TreeLogger logger, CompilationUnitDeclaration[] goldenCuds)
-      throws UnableToCompleteException {
-    for (CompilationUnitDeclaration cud : goldenCuds) {
-      CompilationResult result = cud.compilationResult();
-      if (result.hasErrors()) {
-        logger.log(TreeLogger.ERROR, "Aborting on '" + String.valueOf(cud.getFileName()) + "'");
-        throw new UnableToCompleteException();
-      }
-    }
-  }
-}
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
index 2aa4957..91bbe05 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
@@ -117,11 +117,9 @@
               new Dependencies(packageName, unresolvedQualified, unresolvedSimple, apiRefs);
 
           List<JDeclaredType> types = Collections.emptyList();
-          if (GwtAstBuilder.ENABLED) {
-            if (!cud.compilationResult().hasErrors()) {
-              // Make a GWT AST.
-              types = astBuilder.process(cud, artificialRescues, jsniMethods, jsniRefs);
-            }
+          if (!cud.compilationResult().hasErrors()) {
+            // Make a GWT AST.
+            types = astBuilder.process(cud, artificialRescues, jsniMethods, jsniRefs);
           }
 
           for (CompiledClass cc : compiledClasses) {
diff --git a/dev/core/src/com/google/gwt/dev/javac/PersistentUnitCache.java b/dev/core/src/com/google/gwt/dev/javac/PersistentUnitCache.java
index f07afbb..183b500 100644
--- a/dev/core/src/com/google/gwt/dev/javac/PersistentUnitCache.java
+++ b/dev/core/src/com/google/gwt/dev/javac/PersistentUnitCache.java
@@ -494,10 +494,8 @@
               if (unit == null) {
                 break;
               }
-              if (GwtAstBuilder.ENABLED) {
-                if (unit.getTypesSerializedVersion() != GwtAstBuilder.getSerializationVersion()) {
-                  continue;
-                }
+              if (unit.getTypesSerializedVersion() != GwtAstBuilder.getSerializationVersion()) {
+                continue;
               }
               UnitCacheEntry entry = new UnitCacheEntry(unit, UnitOrigin.PERSISTENT);
               UnitCacheEntry existingEntry = unitMap.get(unit.getResourcePath());
diff --git a/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java b/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java
deleted file mode 100644
index d555625..0000000
--- a/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jdt;
-
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.TreeLogger.HelpInfo;
-import com.google.gwt.dev.javac.CompilationState;
-import com.google.gwt.dev.javac.CompilationUnit;
-import com.google.gwt.dev.javac.GWTProblem;
-import com.google.gwt.dev.javac.JdtCompiler;
-import com.google.gwt.dev.javac.Shared;
-import com.google.gwt.dev.util.CharArrayComparator;
-import com.google.gwt.dev.util.Empty;
-import com.google.gwt.dev.util.Util;
-import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.core.compiler.IProblem;
-import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.Compiler;
-import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
-import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
-import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
-import org.eclipse.jdt.internal.compiler.IProblemFactory;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
-import org.eclipse.jdt.internal.compiler.env.IBinaryType;
-import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
-import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
-import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
-import org.eclipse.jdt.internal.compiler.util.Messages;
-
-import java.net.URL;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-/**
- * A facade around the JDT compiler to manage on-demand compilation, caching
- * smartly where possible.
- */
-public abstract class AbstractCompiler {
-
-  /**
-   * Contains the results of a compilation run. Includes both the compiled
-   * source units and the type bindings for binary types that were looked up
-   * during the compilation.
-   */
-  public static class CompilationResults {
-    /**
-     * Bindings for binary types looked up during compilation.
-     */
-    public final Map<String, BinaryTypeBinding> binaryBindings;
-
-    /**
-     * Compiled source units.
-     */
-    public final CompilationUnitDeclaration[] compiledUnits;
-
-    public CompilationResults(CompilationUnitDeclaration[] compiledUnits,
-        Map<String, BinaryTypeBinding> binaryBindings) {
-      this.compiledUnits = compiledUnits;
-      this.binaryBindings = binaryBindings;
-    }
-  }
-
-  /**
-   * Adapts a {@link CompilationUnit} for a JDT compile.
-   */
-  public static class CompilationUnitAdapter implements ICompilationUnit {
-
-    private final CompilationUnit unit;
-
-    public CompilationUnitAdapter(CompilationUnit unit) {
-      this.unit = unit;
-    }
-
-    @SuppressWarnings("deprecation")
-    public char[] getContents() {
-      return unit.getSource().toCharArray();
-    }
-
-    public char[] getFileName() {
-      return unit.getResourceLocation().toCharArray();
-    }
-
-    public char[] getMainTypeName() {
-      return Shared.getShortName(unit.getTypeName()).toCharArray();
-    }
-
-    public char[][] getPackageName() {
-      String packageName = Shared.getPackageName(unit.getTypeName());
-      return CharOperation.splitOn('.', packageName.toCharArray());
-    }
-
-    @Override
-    public String toString() {
-      return unit.toString();
-    }
-  }
-
-  /**
-   * Shields {@link AbstractCompiler} so it can be garbage collected at the end
-   * of a compile.
-   */
-  private static class Sandbox {
-
-    /**
-     * Adapted to hook the processing of compilation unit declarations so as to
-     * be able to add additional compilation units based on the results of
-     * previously-compiled ones. Examples of cases where this is useful include
-     * classes referenced only from JSNI and <code>GWT.create</code>.
-     */
-    private class CompilerImpl extends Compiler {
-
-      private Map<String, BinaryTypeBinding> bindings;
-      private Set<CompilationUnitDeclaration> cuds;
-      private long jdtProcessNanos;
-
-      public CompilerImpl(INameEnvironment environment, IErrorHandlingPolicy policy,
-          CompilerOptions compilerOptions, ICompilerRequestor requestor,
-          IProblemFactory problemFactory) {
-        super(environment, policy, compilerOptions, requestor, problemFactory);
-      }
-
-      @Override
-      public void accept(IBinaryType binaryType, PackageBinding packageBinding,
-          AccessRestriction accessRestriction) {
-        // Do the same thing as super.accept(), but record the BinaryTypeBinding
-        // that is generated from lookupEnvironment.
-        if (this.options.verbose) {
-          out.println(Messages.bind(Messages.compilation_loadBinary, new String(binaryType
-              .getName())));
-        }
-        BinaryTypeBinding binding =
-            lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
-        String name = CharOperation.toString(binding.compoundName);
-        if (bindings != null) {
-          bindings.put(name, binding);
-        }
-      }
-
-      @Override
-      public void compile(ICompilationUnit[] sourceUnits) {
-        SpeedTracerLogger.Event compileEvent =
-            SpeedTracerLogger.start(CompilerEventType.JDT_COMPILER_SANDBOX);
-        try {
-          super.compile(sourceUnits);
-        } finally {
-          compileEvent.end();
-        }
-        cuds = null;
-      }
-
-      @Override
-      public void process(CompilationUnitDeclaration unit, int index) {
-
-        long processBeginNanos = System.nanoTime();
-
-        // The following block of code is a copy of super.process(cud, index),
-        // with the modification that cud.generateCode is conditionally called
-        // based on doGenerateBytes
-        {
-          this.lookupEnvironment.unitBeingCompleted = unit;
-          long parseStart = System.currentTimeMillis();
-
-          this.parser.getMethodBodies(unit);
-
-          long resolveStart = System.currentTimeMillis();
-          this.stats.parseTime += resolveStart - parseStart;
-
-          // fault in fields & methods
-          if (unit.scope != null) {
-            unit.scope.faultInTypes();
-          }
-
-          // verify inherited methods
-          if (unit.scope != null) {
-            unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
-          }
-
-          // type checking
-          unit.resolve();
-
-          long analyzeStart = System.currentTimeMillis();
-          this.stats.resolveTime += analyzeStart - resolveStart;
-
-          // flow analysis
-          unit.analyseCode();
-
-          long generateStart = System.currentTimeMillis();
-          this.stats.analyzeTime += generateStart - analyzeStart;
-
-          // code generation
-          if (doGenerateBytes) {
-            unit.generateCode();
-          }
-
-          // reference info
-          if (options.produceReferenceInfo && unit.scope != null) {
-            unit.scope.storeDependencyInfo();
-          }
-
-          // finalize problems (suppressWarnings)
-          unit.finalizeProblems();
-
-          this.stats.generateTime += System.currentTimeMillis() - generateStart;
-
-          // refresh the total number of units known at this stage
-          unit.compilationResult.totalUnitsKnown = totalUnits;
-
-          this.lookupEnvironment.unitBeingCompleted = null;
-        }
-
-        ICompilationUnit cu = unit.compilationResult.compilationUnit;
-        String loc = String.valueOf(cu.getFileName());
-        TreeLogger branch =
-            logger.branch(TreeLogger.SPAM, "Scanning for additional dependencies: " + loc, null);
-
-        // Examine the cud for types outside of the flow of the original Java 
-        // source.
-        // 
-        String[] typeNames = outer.doFindAdditionalTypesUsingJsni(branch, unit);
-        addAdditionalTypes(branch, typeNames);
-
-        typeNames = outer.doFindAdditionalTypesUsingArtificialRescues(branch, unit);
-        addAdditionalTypes(branch, typeNames);
-
-        typeNames = outer.doFindAdditionalTypesUsingRebinds(branch, unit);
-        addAdditionalTypes(branch, typeNames);
-        if (typeNames.length > 0) {
-          refreshPackagesFromCompState();
-        }
-
-        // Optionally remember this cud.
-        //
-        if (cuds != null) {
-          cuds.add(unit);
-        }
-
-        jdtProcessNanos += System.nanoTime() - processBeginNanos;
-      }
-
-      /**
-       * Helper method for process() that receives the types found outside the
-       * flow of the original Java source. This causes the compiler to find the
-       * additional type, possibly causing the type to be compiled from source.
-       */
-      private void addAdditionalTypes(TreeLogger logger, String[] typeNames) {
-        for (String typeName : typeNames) {
-          if (logger.isLoggable(TreeLogger.SPAM)) {
-            logger.log(TreeLogger.SPAM, "Need additional type '" + typeName + "'", null);
-          }
-
-          resolvePossiblyNestedType(typeName);
-        }
-      }
-
-      private void compile(ICompilationUnit[] units, Set<CompilationUnitDeclaration> cuds,
-          Map<String, BinaryTypeBinding> bindings) {
-        this.bindings = bindings;
-        this.cuds = cuds;
-        compile(units);
-      }
-
-      private ReferenceBinding resolvePossiblyNestedType(String typeName) {
-        return JdtCompiler.resolveType(lookupEnvironment, typeName);
-      }
-    }
-
-    private class ICompilerRequestorImpl implements ICompilerRequestor {
-
-      public ICompilerRequestorImpl() {
-      }
-
-      public void acceptResult(CompilationResult result) {
-        // Handle compilation errors.
-        //
-        IProblem[] errors = result.getErrors();
-
-        if (errors != null && errors.length > 0) {
-          // Dump it to disk.
-          //
-          String fn = String.valueOf(result.compilationUnit.getFileName());
-          String msg = "Errors in '" + fn + "'";
-          TreeLogger branch = logger.branch(TreeLogger.ERROR, msg, null);
-
-          for (IProblem error : errors) {
-            // Strip the initial code from each error.
-            //
-            msg = error.toString();
-            msg = msg.substring(msg.indexOf(' '));
-
-            // Append 'Line #: msg' to the error message.
-            //
-            StringBuffer msgBuf = new StringBuffer();
-            int line = error.getSourceLineNumber();
-            if (line > 0) {
-              msgBuf.append("Line ");
-              msgBuf.append(line);
-              msgBuf.append(": ");
-            }
-            msgBuf.append(msg);
-
-            HelpInfo helpInfo = null;
-            if (error instanceof GWTProblem) {
-              GWTProblem gwtProblem = (GWTProblem) error;
-              helpInfo = gwtProblem.getHelpInfo();
-            }
-            branch.log(TreeLogger.ERROR, msgBuf.toString(), null, helpInfo);
-          }
-        }
-      }
-    }
-
-    private class INameEnvironmentImpl implements INameEnvironment {
-
-      public INameEnvironmentImpl() {
-      }
-
-      public void cleanup() {
-        // intentionally blank
-      }
-
-      public NameEnvironmentAnswer findType(char[] type, char[][] pkg) {
-        return findType(CharOperation.arrayConcat(pkg, type));
-      }
-
-      public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
-        String qname = CharOperation.toString(compoundTypeName);
-        TreeLogger branch =
-            logger.branch(TreeLogger.SPAM, "Compiler is asking about '" + qname + "'", null);
-
-        if (isPackage(qname)) {
-          branch.log(TreeLogger.SPAM, "Found to be a package", null);
-          return null;
-        }
-
-        // Didn't find it in the cache, so let's compile from source.
-        // Strip off the inner types, if any
-        //
-        String className = qname;
-        int pos = qname.indexOf('$');
-        if (pos >= 0) {
-          qname = qname.substring(0, pos);
-        }
-        CompilationUnit unit = findCompilationUnit(qname);
-        if (unit != null) {
-          if (branch.isLoggable(TreeLogger.SPAM)) {
-            branch.log(TreeLogger.SPAM, "Found type in compilation unit: "
-                + unit.getResourceLocation());
-          }
-          ICompilationUnit icu = new CompilationUnitAdapter(unit);
-          return new NameEnvironmentAnswer(icu, null);
-        } else {
-          ClassLoader classLoader = getClassLoader();
-          URL resourceURL = classLoader.getResource(className.replace('.', '/') + ".class");
-          if (resourceURL != null) {
-            /*
-             * We know that there is a .class file that matches the name that we
-             * are looking for. However, at least on OSX, this lookup is case
-             * insensitive so we need to use Class.forName to effectively verify
-             * the case.
-             */
-            if (isBinaryType(classLoader, className)) {
-              byte[] classBytes = Util.readURLAsBytes(resourceURL);
-              try {
-                ClassFileReader cfr = new ClassFileReader(classBytes, null);
-                return new NameEnvironmentAnswer(cfr, null);
-              } catch (ClassFormatException e) {
-                // Ignored.
-              }
-            }
-          }
-
-          branch.log(TreeLogger.SPAM, "Not a known type", null);
-          return null;
-        }
-      }
-
-      public boolean isPackage(char[][] parentPkg, char[] pkg) {
-        // In special cases where class bytes are asserted from the outside,
-        // a package can exist that the host doesn't know about. We have to
-        // do a special check for these cases.
-        //
-        final char[] pathChars = CharOperation.concatWith(parentPkg, pkg, '.');
-        String packageName = String.valueOf(pathChars);
-        if (isPackage(packageName)) {
-          return true;
-        } else if (isPackage(getClassLoader(), packageName)) {
-          // Grow our own list to spare calls into the host.
-          //
-          rememberPackage(packageName);
-          return true;
-        } else {
-          return false;
-        }
-      }
-
-      private ClassLoader getClassLoader() {
-        return Thread.currentThread().getContextClassLoader();
-      }
-
-      private boolean isBinaryType(ClassLoader classLoader, String typeName) {
-        try {
-          Class.forName(typeName, false, classLoader);
-          return true;
-        } catch (ClassNotFoundException e) {
-          // Ignored.
-        } catch (LinkageError e) {
-          // Ignored.
-        }
-
-        // Assume that it is not a binary type.
-        return false;
-      }
-
-      private boolean isPackage(ClassLoader classLoader, String packageName) {
-        String packageAsPath = packageName.replace('.', '/');
-
-        // Test the JRE explicitly, because the classloader trick doesn't work.
-        if (JdtCompiler.JreIndex.contains(packageAsPath)) {
-          return true;
-        }
-
-        return classLoader.getResource(packageAsPath) != null;
-      }
-
-      private boolean isPackage(String packageName) {
-        return knownPackages.contains(packageName);
-      }
-    }
-
-    final CompilerImpl compiler;
-    final boolean doGenerateBytes;
-    final Set<String> knownPackages = new HashSet<String>();
-    TreeLogger logger = null;
-    AbstractCompiler outer;
-
-    Sandbox(AbstractCompiler outer, boolean doGenerateBytes) {
-      this.outer = outer;
-      this.doGenerateBytes = doGenerateBytes;
-      rememberPackage("");
-
-      INameEnvironment env = new INameEnvironmentImpl();
-      IErrorHandlingPolicy pol = DefaultErrorHandlingPolicies.proceedWithAllProblems();
-      IProblemFactory probFact = new DefaultProblemFactory(Locale.getDefault());
-      ICompilerRequestor req = new ICompilerRequestorImpl();
-      CompilerOptions options = getCompilerOptions();
-
-      // This is only needed by TypeOracleBuilder to parse metadata.
-      options.docCommentSupport = false;
-
-      compiler = new CompilerImpl(env, pol, options, req, probFact);
-
-      // Initialize the packages list.
-      refreshPackagesFromCompState();
-    }
-
-    public void clear() {
-      outer = null;
-      logger = TreeLogger.NULL;
-      compiler.bindings = null;
-    }
-
-    private CompilationUnit findCompilationUnit(String qname) {
-      if (outer == null) {
-        return null;
-      }
-
-      // Build the initial set of compilation units.
-      Map<String, CompilationUnit> unitMap = outer.compilationState.getCompilationUnitMap();
-      CompilationUnit unit = unitMap.get(qname);
-      while (unit == null) {
-        int pos = qname.lastIndexOf('.');
-        if (pos < 0) {
-          return null;
-        }
-        qname = qname.substring(0, pos);
-        unit = unitMap.get(qname);
-      }
-      return unit;
-    }
-
-    private void refreshPackagesFromCompState() {
-      for (CompilationUnit unit : outer.compilationState.getCompilationUnits()) {
-        String packageName = Shared.getPackageName(unit.getTypeName());
-        rememberPackage(packageName);
-      }
-    }
-
-    /**
-     * Causes the compilation service itself to recognize the specified package
-     * name (and all its parent packages), avoiding a call back into the host.
-     * This is useful as an optimization, but more importantly, it is useful to
-     * compile against bytecode that was pre-compiled to which we don't have the
-     * source. This ability is crucial bridging the gap between user-level and
-     * "dev" code in Development Mode for classes such as JavaScriptHost and
-     * ShellJavaScriptHost.
-     */
-    private void rememberPackage(String packageName) {
-      if (knownPackages.add(packageName)) {
-        int i = packageName.lastIndexOf('.');
-        if (i != -1) {
-          // Ensure the parent package is also created.
-          //
-          rememberPackage(packageName.substring(0, i));
-        }
-      }
-    }
-  }
-
-  private static final Comparator<CompilationUnitDeclaration> CUD_COMPARATOR =
-      new Comparator<CompilationUnitDeclaration>() {
-
-        public int compare(CompilationUnitDeclaration cud1, CompilationUnitDeclaration cud2) {
-          ICompilationUnit cu1 = cud1.compilationResult().getCompilationUnit();
-          ICompilationUnit cu2 = cud2.compilationResult().getCompilationUnit();
-          char[][] package1 = cu1.getPackageName();
-          char[][] package2 = cu2.getPackageName();
-          for (int i = 0, c = Math.min(package1.length, package2.length); i < c; ++i) {
-            int result = CharArrayComparator.INSTANCE.compare(package1[i], package2[i]);
-            if (result != 0) {
-              return result;
-            }
-          }
-          int result = package2.length - package1.length;
-          if (result != 0) {
-            return result;
-          }
-          return CharArrayComparator.INSTANCE.compare(cu1.getMainTypeName(), cu2.getMainTypeName());
-        }
-      };
-
-  public static CompilerOptions getCompilerOptions() {
-    CompilerOptions options = JdtCompiler.getCompilerOptions();
-
-    // Turn off all debugging for Production Mode.
-    options.produceDebugAttributes = 0;
-    options.preserveAllLocalVariables = false;
-    return options;
-  }
-
-  protected CompilationState compilationState;
-  private Sandbox sandbox;
-
-  protected AbstractCompiler(CompilationState compilationState, boolean doGenerateBytes) {
-    this.compilationState = compilationState;
-    this.sandbox = new Sandbox(this, doGenerateBytes);
-  }
-
-  protected final CompilationResults compile(TreeLogger logger, ICompilationUnit[] units) {
-
-    // Any additional compilation units that are found to be needed will be
-    // pulled in while processing compilation units. See CompilerImpl.process().
-    //
-    sandbox.logger = logger;
-    try {
-      Set<CompilationUnitDeclaration> cuds =
-          new TreeSet<CompilationUnitDeclaration>(CUD_COMPARATOR);
-      LinkedHashMap<String, BinaryTypeBinding> bindings =
-          new LinkedHashMap<String, BinaryTypeBinding>();
-      sandbox.compiler.compile(units, cuds, bindings);
-      return new CompilationResults(cuds.toArray(new CompilationUnitDeclaration[cuds.size()]),
-          bindings);
-    } finally {
-      sandbox.clear();
-      sandbox = null;
-    }
-  }
-
-  /**
-   * @param logger a {@link TreeLogger}
-   * @param cud a {@link CompilationUnitDeclaration}
-   */
-  protected String[] doFindAdditionalTypesUsingArtificialRescues(TreeLogger logger,
-      CompilationUnitDeclaration cud) {
-    return Empty.STRINGS;
-  }
-
-  /**
-   * @param logger a {@link TreeLogger}
-   * @param cud a {@link CompilationUnitDeclaration}
-   */
-  protected String[] doFindAdditionalTypesUsingJsni(TreeLogger logger,
-      CompilationUnitDeclaration cud) {
-    return Empty.STRINGS;
-  }
-
-  /**
-   * @param logger a {@link TreeLogger}
-   * @param cud a {@link CompilationUnitDeclaration}
-   */
-  protected String[] doFindAdditionalTypesUsingRebinds(TreeLogger logger,
-      CompilationUnitDeclaration cud) {
-    return Empty.STRINGS;
-  }
-
-  protected final ReferenceBinding resolvePossiblyNestedType(String typeName) {
-    return sandbox.compiler.resolvePossiblyNestedType(typeName);
-  }
-}
diff --git a/dev/core/src/com/google/gwt/dev/jdt/BasicWebModeCompiler.java b/dev/core/src/com/google/gwt/dev/jdt/BasicWebModeCompiler.java
deleted file mode 100644
index eaf1dee..0000000
--- a/dev/core/src/com/google/gwt/dev/jdt/BasicWebModeCompiler.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jdt;
-
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.dev.javac.CompilationState;
-import com.google.gwt.dev.javac.CompilationUnit;
-import com.google.gwt.dev.javac.CompiledClass;
-import com.google.gwt.dev.jjs.impl.TypeLinker;
-import com.google.gwt.dev.util.JsniRef;
-import com.google.gwt.dev.util.Memory;
-
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Provides a basic front-end based on the JDT compiler that incorporates
- * GWT-specific concepts such as JSNI.
- */
-public class BasicWebModeCompiler extends AbstractCompiler {
-
-  public static CompilationResults getCompilationUnitDeclarations(TreeLogger logger,
-      CompilationState state, TypeLinker linker, String... seedTypeNames)
-      throws UnableToCompleteException {
-    return new BasicWebModeCompiler(state, linker).getCompilationUnitDeclarations(logger,
-        seedTypeNames);
-  }
-
-  private final TypeLinker linker;
-
-  /**
-   * Construct a BasicWebModeCompiler.
-   */
-  public BasicWebModeCompiler(CompilationState compilationState, TypeLinker linker) {
-    super(compilationState, false);
-    this.linker = linker;
-  }
-
-  /**
-   * Build the initial set of compilation units.
-   */
-  public CompilationResults getCompilationUnitDeclarations(TreeLogger logger,
-      String[] seedTypeNames, ICompilationUnit... additionalUnits) throws UnableToCompleteException {
-
-    Map<String, CompiledClass> classMapBySource = compilationState.getClassFileMapBySource();
-
-    /*
-     * The alreadyAdded set prevents duplicate CompilationUnits from being added
-     * to the icu list in the case of multiple JSO implementations as inner
-     * classes in the same top-level class or seed classes as SingleJsoImpls
-     * (e.g. JSO itself as the SingleImpl for all tag interfaces).
-     */
-    Set<CompilationUnit> alreadyAdded = new HashSet<CompilationUnit>();
-
-    List<ICompilationUnit> icus =
-        new ArrayList<ICompilationUnit>(seedTypeNames.length + additionalUnits.length);
-
-    Collections.addAll(icus, additionalUnits);
-
-    for (String seedTypeName : seedTypeNames) {
-      CompilationUnit unit = getUnitForType(logger, classMapBySource, seedTypeName);
-
-      if (unit == null) {
-        continue;
-      }
-
-      if (alreadyAdded.add(unit)) {
-        icus.add(new CompilationUnitAdapter(unit));
-      }
-    }
-
-    /*
-     * Compile, which will pull in everything else via the
-     * doFindAdditionalTypesUsingFoo() methods.
-     */
-    CompilationResults units = compile(logger, icus.toArray(new ICompilationUnit[icus.size()]));
-    Memory.maybeDumpMemory("WebModeCompiler");
-    return units;
-  }
-
-  /**
-   * Pull in types referenced only via JSNI.
-   */
-  @Override
-  protected String[] doFindAdditionalTypesUsingJsni(TreeLogger logger,
-      CompilationUnitDeclaration cud) {
-    FindJsniRefVisitor v = new FindJsniRefVisitor();
-    cud.traverse(v, cud.scope);
-    Set<String> jsniRefs = v.getJsniRefs();
-    Set<String> dependentTypeNames = new HashSet<String>();
-    for (String jsniRef : jsniRefs) {
-      JsniRef parsed = JsniRef.parse(jsniRef);
-      if (parsed != null) {
-        // If we fail to parse, don't add a class reference.
-        dependentTypeNames.add(parsed.className());
-      }
-    }
-    return dependentTypeNames.toArray(new String[dependentTypeNames.size()]);
-  }
-
-  /**
-   * Get the CompilationUnit for a named type or throw an
-   * UnableToCompleteException.
-   */
-  private CompilationUnit getUnitForType(TreeLogger logger,
-      Map<String, CompiledClass> classMapBySource, String typeName)
-      throws UnableToCompleteException {
-
-    CompiledClass compiledClass = classMapBySource.get(typeName);
-    if (compiledClass == null) {
-      if (linker.isExternalType(typeName)) {
-        return null;
-      }
-      logger.log(TreeLogger.ERROR, "Unable to find compilation unit for type '" + typeName + "'");
-      throw new UnableToCompleteException();
-    }
-
-    assert compiledClass.getUnit() != null;
-    return compiledClass.getUnit();
-  }
-}
diff --git a/dev/core/src/com/google/gwt/dev/jdt/FindDeferredBindingSitesVisitor.java b/dev/core/src/com/google/gwt/dev/jdt/FindDeferredBindingSitesVisitor.java
deleted file mode 100644
index fe180a1..0000000
--- a/dev/core/src/com/google/gwt/dev/jdt/FindDeferredBindingSitesVisitor.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jdt;
-
-import com.google.gwt.dev.javac.GWTProblem;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Expression;
-import org.eclipse.jdt.internal.compiler.ast.MessageSend;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.Scope;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Walks a
- * {@link org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration} to
- * find <code>GWT.create()</code> class so that we can eagerly complain about
- * deferred binding problems.
- */
-public class FindDeferredBindingSitesVisitor extends SafeASTVisitor {
-
-  /**
-   * Information about the site at which a rebind request was found, used to
-   * report problems.
-   */
-  public static class MessageSendSite {
-    public final MessageSend messageSend;
-
-    public final Scope scope;
-
-    public MessageSendSite(MessageSend messageSend, Scope scope) {
-      this.messageSend = messageSend;
-      this.scope = scope;
-    }
-  }
-
-  public static final String MAGIC_CLASS = "com.google.gwt.core.client.GWT";
-  public static final String REBIND_MAGIC_METHOD = "create";
-
-  public static void reportRebindProblem(MessageSendSite site, String message) {
-    MessageSend messageSend = site.messageSend;
-    Scope scope = site.scope;
-    // Safe since CUS.referenceContext is set in its constructor.
-    CompilationUnitDeclaration cud = scope.compilationUnitScope().referenceContext;
-    GWTProblem.recordError(messageSend, cud, message, null);
-  }
-
-  private final Map<String, MessageSendSite> results = new HashMap<String, MessageSendSite>();
-
-  @Override
-  public void endVisit(MessageSend messageSend, BlockScope scope) {
-    if (messageSend.binding == null) {
-      // Some sort of problem.
-      return;
-    }
-
-    String methodName = String.valueOf(messageSend.selector);
-    if (!methodName.equals(REBIND_MAGIC_METHOD)) {
-      // Not the create() method.
-      return;
-    }
-
-    char[][] targetClass = messageSend.binding.declaringClass.compoundName;
-    String targetClassName = CharOperation.toString(targetClass);
-    if (!targetClassName.equals(MAGIC_CLASS)) {
-      // Not being called on the Rebind class.
-      return;
-    }
-
-    MessageSendSite site = new MessageSendSite(messageSend, scope);
-
-    Expression[] args = messageSend.arguments;
-    if (args.length != 1) {
-      reportRebindProblem(site, "GWT.create() should take exactly one argument");
-      return;
-    }
-
-    if (!(args[0] instanceof ClassLiteralAccess)) {
-      reportRebindProblem(site, "Only class literals may be used as arguments to GWT.create()");
-      return;
-    }
-
-    ClassLiteralAccess cla = (ClassLiteralAccess) args[0];
-    String typeName = String.valueOf(cla.targetType.readableName());
-
-    if (!results.containsKey(typeName)) {
-      results.put(typeName, site);
-    }
-  }
-
-  public Map<String, MessageSendSite> getSites() {
-    return Collections.unmodifiableMap(results);
-  }
-}
diff --git a/dev/core/src/com/google/gwt/dev/jdt/FindJsniRefVisitor.java b/dev/core/src/com/google/gwt/dev/jdt/FindJsniRefVisitor.java
deleted file mode 100644
index 2fe19cf..0000000
--- a/dev/core/src/com/google/gwt/dev/jdt/FindJsniRefVisitor.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jdt;
-
-import com.google.gwt.dev.javac.JsniCollector;
-import com.google.gwt.dev.jjs.InternalCompilerException;
-import com.google.gwt.dev.jjs.SourceOrigin;
-import com.google.gwt.dev.js.JsParser;
-import com.google.gwt.dev.js.JsParserException;
-import com.google.gwt.dev.js.ast.JsContext;
-import com.google.gwt.dev.js.ast.JsNameRef;
-import com.google.gwt.dev.js.ast.JsProgram;
-import com.google.gwt.dev.js.ast.JsStatement;
-import com.google.gwt.dev.js.ast.JsVisitor;
-
-import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Walks the AST to find references to Java identifiers from within JSNI blocks.
- * By default, it does a full JavaScript parse to accurately find JSNI
- * references. If {@link #beSloppy()} is called, then it will run much more
- * quickly but it will return a superset of the actual JSNI references.
- */
-public class FindJsniRefVisitor extends SafeASTVisitor {
-  private final Set<String> jsniRefs = new LinkedHashSet<String>();
-
-  public Set<String> getJsniRefs() {
-    return Collections.unmodifiableSet(jsniRefs);
-  }
-
-  @Override
-  public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
-    if (!methodDeclaration.isNative()) {
-      return false;
-    }
-
-    // Handle JSNI block
-    String jsniCode = getJSNICode(methodDeclaration);
-    if (jsniCode == null) {
-      return false;
-    }
-    if (jsniCode.indexOf('@') < 0) {
-      // short cut: if there are no at signs, there are no JSNI refs
-      return false;
-    }
-
-    findJsniRefsAccurately(methodDeclaration, jsniCode);
-    return false;
-  }
-
-  private void findJsniRefsAccurately(MethodDeclaration methodDeclaration, String jsniCode)
-      throws InternalCompilerException {
-    JsProgram jsProgram = new JsProgram();
-
-    String syntheticFnHeader = "function(";
-    boolean first = true;
-    if (methodDeclaration.arguments != null) {
-      for (int i = 0, c = methodDeclaration.arguments.length; i < c; ++i) {
-        Argument arg = methodDeclaration.arguments[i];
-        if (first) {
-          first = false;
-        } else {
-          syntheticFnHeader += ',';
-        }
-        syntheticFnHeader += String.valueOf(arg.name);
-      }
-    }
-    syntheticFnHeader += ')';
-    StringReader sr = new StringReader(syntheticFnHeader + '\n' + jsniCode);
-    try {
-      // start at -1 to avoid counting our synthetic header
-      List<JsStatement> result = JsParser.parse(SourceOrigin.UNKNOWN, jsProgram.getScope(), sr);
-      new JsVisitor() {
-        @Override
-        public void endVisit(JsNameRef x, JsContext ctx) {
-          String ident = x.getIdent();
-          if (ident.charAt(0) == '@') {
-            jsniRefs.add(ident.substring(1));
-          }
-        }
-      }.acceptList(result);
-    } catch (IOException e) {
-      throw new InternalCompilerException(e.getMessage(), e);
-    } catch (JsParserException e) {
-      // ignore, we only care about finding valid references
-    }
-  }
-
-  private String getJSNICode(MethodDeclaration methodDeclaration) {
-    char[] source = methodDeclaration.compilationResult().getCompilationUnit().getContents();
-    String jsniCode =
-        String.valueOf(source, methodDeclaration.bodyStart, methodDeclaration.bodyEnd
-            - methodDeclaration.bodyStart + 1);
-    int startPos = jsniCode.indexOf(JsniCollector.JSNI_BLOCK_START);
-    int endPos = jsniCode.lastIndexOf(JsniCollector.JSNI_BLOCK_END);
-    if (startPos < 0 || endPos < 0) {
-      return null; // ignore the error
-    }
-
-    // move up to open brace
-    startPos += JsniCollector.JSNI_BLOCK_START.length() - 1;
-    // move past close brace
-    endPos += 1;
-
-    jsniCode = jsniCode.substring(startPos, endPos);
-    return jsniCode;
-  }
-
-}
diff --git a/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java b/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java
deleted file mode 100644
index 3492108..0000000
--- a/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jdt;
-
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.dev.javac.ArtificialRescueChecker;
-import com.google.gwt.dev.jdt.FindDeferredBindingSitesVisitor.MessageSendSite;
-import com.google.gwt.dev.jjs.impl.TypeLinker;
-import com.google.gwt.dev.util.Empty;
-import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
-
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Provides a reusable front-end based on the JDT compiler that incorporates
- * GWT-specific concepts such as JSNI and deferred binding.
- */
-public class WebModeCompilerFrontEnd extends BasicWebModeCompiler {
-
-  public static CompilationResults getCompilationUnitDeclarations(TreeLogger logger,
-      String[] seedTypeNames, RebindPermutationOracle rebindPermOracle, TypeLinker linker,
-      ICompilationUnit... additionalUnits) throws UnableToCompleteException {
-    Event getCompilationUnitsEvent =
-        SpeedTracerLogger.start(CompilerEventType.GET_COMPILATION_UNITS);
-    CompilationResults results =
-        new WebModeCompilerFrontEnd(rebindPermOracle, linker).getCompilationUnitDeclarations(
-            logger, seedTypeNames, additionalUnits);
-    getCompilationUnitsEvent.end();
-    return results;
-  }
-
-  private final RebindPermutationOracle rebindPermOracle;
-
-  /**
-   * Construct a WebModeCompilerFrontEnd.
-   */
-  private WebModeCompilerFrontEnd(RebindPermutationOracle rebindPermOracle, TypeLinker linker) {
-    super(rebindPermOracle.getCompilationState(), linker);
-    this.rebindPermOracle = rebindPermOracle;
-  }
-
-  @Override
-  protected String[] doFindAdditionalTypesUsingArtificialRescues(TreeLogger logger,
-      CompilationUnitDeclaration cud) {
-    List<String> types = ArtificialRescueChecker.collectReferencedTypes(cud);
-    return types.isEmpty() ? Empty.STRINGS : types.toArray(new String[types.size()]);
-  }
-
-  /**
-   * Pull in types implicitly referenced through rebind answers.
-   */
-  @Override
-  protected String[] doFindAdditionalTypesUsingRebinds(TreeLogger logger,
-      CompilationUnitDeclaration cud) {
-    Set<String> dependentTypeNames = new LinkedHashSet<String>();
-
-    // Find all the deferred binding request types.
-    FindDeferredBindingSitesVisitor v = new FindDeferredBindingSitesVisitor();
-    cud.traverse(v, cud.scope);
-    Map<String, MessageSendSite> requestedTypes = v.getSites();
-    Map<String, String[]> rebindAnswers = new HashMap<String, String[]>();
-    boolean doFinish = false;
-
-    // For each, ask the host for every possible deferred binding answer.
-    for (Map.Entry<String, MessageSendSite> entry : requestedTypes.entrySet()) {
-      String reqType = entry.getKey();
-      MessageSendSite site = entry.getValue();
-      try {
-        String[] resultTypes = rebindPermOracle.getAllPossibleRebindAnswers(logger, reqType);
-        rebindAnswers.put(reqType, resultTypes);
-        Collections.addAll(dependentTypeNames, resultTypes);
-        doFinish = true;
-      } catch (UnableToCompleteException e) {
-        FindDeferredBindingSitesVisitor.reportRebindProblem(site, "Failed to resolve '" + reqType
-            + "' via deferred binding");
-        rebindAnswers.put(reqType, new String[0]);
-      }
-    }
-
-    if (doFinish) {
-      rebindPermOracle.getGeneratorContext().finish(logger);
-    }
-
-    // Sanity check all rebind answers.
-    for (Map.Entry<String, MessageSendSite> entry : requestedTypes.entrySet()) {
-      String reqType = entry.getKey();
-      MessageSendSite site = entry.getValue();
-      String[] resultTypes = rebindAnswers.get(reqType);
-      // Check that each result is instantiable.
-      for (String typeName : resultTypes) {
-        checkRebindResultInstantiable(site, typeName);
-      }
-    }
-
-    return dependentTypeNames.toArray(new String[dependentTypeNames.size()]);
-  }
-
-  private void checkRebindResultInstantiable(MessageSendSite site, String typeName) {
-    /*
-     * This causes the compiler to find the additional type, possibly winding
-     * its back to ask for the compilation unit from the source oracle.
-     */
-    ReferenceBinding type = resolvePossiblyNestedType(typeName);
-
-    // Sanity check rebind results.
-    if (type == null) {
-      FindDeferredBindingSitesVisitor.reportRebindProblem(site, "Rebind result '" + typeName
-          + "' could not be found");
-      return;
-    }
-    if (!type.isClass()) {
-      FindDeferredBindingSitesVisitor.reportRebindProblem(site, "Rebind result '" + typeName
-          + "' must be a class");
-      return;
-    }
-    if (type.isAbstract()) {
-      FindDeferredBindingSitesVisitor.reportRebindProblem(site, "Rebind result '" + typeName
-          + "' cannot be abstract");
-      return;
-    }
-    if (type.isNestedType() && !type.isStatic()) {
-      FindDeferredBindingSitesVisitor.reportRebindProblem(site, "Rebind result '" + typeName
-          + "' cannot be a non-static nested class");
-      return;
-    }
-    if (type.isLocalType()) {
-      FindDeferredBindingSitesVisitor.reportRebindProblem(site, "Rebind result '" + typeName
-          + "' cannot be a local class");
-      return;
-    }
-    // Look for a noArg ctor.
-    MethodBinding noArgCtor = type.getExactConstructor(Binding.NO_PARAMETERS);
-    if (noArgCtor == null) {
-      FindDeferredBindingSitesVisitor.reportRebindProblem(site, "Rebind result '" + typeName
-          + "' has no default (zero argument) constructors");
-      return;
-    }
-  }
-}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/AstConstructor.java b/dev/core/src/com/google/gwt/dev/jjs/AstConstructor.java
index 4b4c7f7..8826981 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/AstConstructor.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/AstConstructor.java
@@ -20,12 +20,10 @@
 import com.google.gwt.dev.javac.CompilationState;
 import com.google.gwt.dev.javac.StandardGeneratorContext;
 import com.google.gwt.dev.jdt.RebindPermutationOracle;
-import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory;
 import com.google.gwt.dev.jjs.ast.JProgram;
 import com.google.gwt.dev.jjs.impl.AssertionNormalizer;
 import com.google.gwt.dev.jjs.impl.AssertionRemover;
 import com.google.gwt.dev.jjs.impl.FixAssignmentToUnbox;
-import com.google.gwt.dev.jjs.impl.GwtAstBuilder;
 import com.google.gwt.dev.jjs.impl.ImplementClassLiteralsAsFields;
 import com.google.gwt.dev.jjs.impl.ReplaceRunAsyncs;
 import com.google.gwt.dev.jjs.impl.UnifyAst;
@@ -66,9 +64,8 @@
       }
     };
 
-    JProgram jprogram = new JProgram(DummyCorrelationFactory.INSTANCE);
-    JsProgram jsProgram = new JsProgram(DummyCorrelationFactory.INSTANCE);
-    assert GwtAstBuilder.ENABLED;
+    JProgram jprogram = new JProgram();
+    JsProgram jsProgram = new JsProgram();
     UnifyAst unifyAst = new UnifyAst(jprogram, jsProgram, options, rpo);
     unifyAst.buildEverything(logger);
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index 67d86c7..db7f4f7 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -41,12 +41,8 @@
 import com.google.gwt.dev.cfg.ConfigurationProperty;
 import com.google.gwt.dev.cfg.ModuleDef;
 import com.google.gwt.dev.javac.CompilationProblemReporter;
-import com.google.gwt.dev.javac.CompilationProblemReporter.SourceFetcher;
 import com.google.gwt.dev.javac.typemodel.TypeOracle;
 import com.google.gwt.dev.jdt.RebindPermutationOracle;
-import com.google.gwt.dev.jdt.WebModeCompilerFrontEnd;
-import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory;
-import com.google.gwt.dev.jjs.CorrelationFactory.RealCorrelationFactory;
 import com.google.gwt.dev.jjs.UnifiedAst.AST;
 import com.google.gwt.dev.jjs.ast.Context;
 import com.google.gwt.dev.jjs.ast.JBinaryOperation;
@@ -68,7 +64,6 @@
 import com.google.gwt.dev.jjs.impl.AssertionNormalizer;
 import com.google.gwt.dev.jjs.impl.AssertionRemover;
 import com.google.gwt.dev.jjs.impl.AstDumper;
-import com.google.gwt.dev.jjs.impl.BuildTypeMap;
 import com.google.gwt.dev.jjs.impl.CastNormalizer;
 import com.google.gwt.dev.jjs.impl.CatchBlockNormalizer;
 import com.google.gwt.dev.jjs.impl.CodeSplitter;
@@ -79,9 +74,7 @@
 import com.google.gwt.dev.jjs.impl.EqualityNormalizer;
 import com.google.gwt.dev.jjs.impl.Finalizer;
 import com.google.gwt.dev.jjs.impl.FixAssignmentToUnbox;
-import com.google.gwt.dev.jjs.impl.GenerateJavaAST;
 import com.google.gwt.dev.jjs.impl.GenerateJavaScriptAST;
-import com.google.gwt.dev.jjs.impl.GwtAstBuilder;
 import com.google.gwt.dev.jjs.impl.HandleCrossFragmentReferences;
 import com.google.gwt.dev.jjs.impl.ImplementClassLiteralsAsFields;
 import com.google.gwt.dev.jjs.impl.JavaToJavaScriptMap;
@@ -100,13 +93,10 @@
 import com.google.gwt.dev.jjs.impl.RecordRebinds;
 import com.google.gwt.dev.jjs.impl.RemoveEmptySuperCalls;
 import com.google.gwt.dev.jjs.impl.ReplaceGetClassOverrides;
-import com.google.gwt.dev.jjs.impl.ReplaceRebinds;
 import com.google.gwt.dev.jjs.impl.ReplaceRunAsyncs;
 import com.google.gwt.dev.jjs.impl.ResolveRebinds;
 import com.google.gwt.dev.jjs.impl.SameParameterValueOptimizer;
 import com.google.gwt.dev.jjs.impl.SourceInfoCorrelator;
-import com.google.gwt.dev.jjs.impl.TypeLinker;
-import com.google.gwt.dev.jjs.impl.TypeMap;
 import com.google.gwt.dev.jjs.impl.TypeTightener;
 import com.google.gwt.dev.jjs.impl.UnifyAst;
 import com.google.gwt.dev.jjs.impl.gflow.DataflowOptimizer;
@@ -145,9 +135,6 @@
 import com.google.gwt.soyc.SoycDashboard;
 import com.google.gwt.soyc.io.ArtifactsOutputDirectory;
 
-import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.xml.sax.SAXException;
 
 import java.io.ByteArrayOutputStream;
@@ -533,94 +520,36 @@
 
     Memory.maybeDumpMemory("CompStateBuilt");
 
-    CorrelationFactory correlator =
-        options.isSoycExtra() ? RealCorrelationFactory.INSTANCE : DummyCorrelationFactory.INSTANCE;
-    JProgram jprogram = new JProgram(correlator);
-    JsProgram jsProgram = new JsProgram(correlator);
+    JProgram jprogram = new JProgram();
+    JsProgram jsProgram = new JsProgram();
 
     try {
-      if (GwtAstBuilder.ENABLED) {
-        UnifyAst unifyAst = new UnifyAst(jprogram, jsProgram, options, rpo);
-        unifyAst.addRootTypes(allRootTypes);
-        // TODO: errors.
-        // TODO: move this into UnifyAst.
-        findEntryPoints(logger, rpo, declEntryPts, jprogram);
-        unifyAst.exec(logger);
-        // TODO: errors.
+      // (2) Assemble the Java AST.
+      UnifyAst unifyAst = new UnifyAst(jprogram, jsProgram, options, rpo);
+      unifyAst.addRootTypes(allRootTypes);
+      // TODO: move this into UnifyAst?
+      findEntryPoints(logger, rpo, declEntryPts, jprogram);
+      unifyAst.exec(logger);
 
-        List<String> finalTypeOracleTypes = Lists.create();
-        if (precompilationMetrics != null) {
-          for (com.google.gwt.core.ext.typeinfo.JClassType type : typeOracle.getTypes()) {
-            finalTypeOracleTypes =
-                Lists.add(finalTypeOracleTypes, type.getPackage().getName() + "." + type.getName());
-          }
-          precompilationMetrics.setFinalTypeOracleTypes(finalTypeOracleTypes);
+      List<String> finalTypeOracleTypes = Lists.create();
+      if (precompilationMetrics != null) {
+        for (com.google.gwt.core.ext.typeinfo.JClassType type : typeOracle.getTypes()) {
+          finalTypeOracleTypes =
+              Lists.add(finalTypeOracleTypes, type.getPackage().getName() + "." + type.getName());
         }
-
-        // Free up memory.
-        rpo.clear();
-
-        if (options.isSoycEnabled()) {
-          SourceInfoCorrelator.exec(jprogram);
-        }
-
-        // Compute all super type/sub type info
-        jprogram.typeOracle.computeBeforeAST();
-      } else {
-
-        // Compile the source and get the compiler so we can get the parse tree
-        CompilationUnitDeclaration[] goldenCuds =
-            WebModeCompilerFrontEnd.getCompilationUnitDeclarations(logger, allRootTypes
-                .toArray(new String[allRootTypes.size()]), rpo, TypeLinker.NULL_TYPE_LINKER).compiledUnits;
-
-        List<String> finalTypeOracleTypes = Lists.create();
-        if (precompilationMetrics != null) {
-          for (com.google.gwt.core.ext.typeinfo.JClassType type : typeOracle.getTypes()) {
-            finalTypeOracleTypes =
-                Lists.add(finalTypeOracleTypes, type.getPackage().getName() + "." + type.getName());
-          }
-          precompilationMetrics.setFinalTypeOracleTypes(finalTypeOracleTypes);
-        }
-
-        // Free up memory.
-        rpo.clear();
-        Memory.maybeDumpMemory("GoldenCudsBuilt");
-
-        /*
-         * Check for compilation problems. We don't log here because any
-         * problems found here will have already been logged by
-         * AbstractCompiler.
-         */
-        checkForErrors(logger, goldenCuds, false);
-
-        /*
-         * (1) Build a flattened map of TypeDeclarations => JType. The resulting
-         * map contains entries for all reference types. BuildTypeMap also
-         * parses all JSNI.
-         */
-        TypeMap typeMap = new TypeMap(jprogram);
-        TypeDeclaration[] allTypeDeclarations = BuildTypeMap.exec(typeMap, goldenCuds, jsProgram);
-
-        // BuildTypeMap can uncover syntactic JSNI errors; report & abort
-        checkForErrors(logger, goldenCuds, true);
-
-        // Compute all super type/sub type info
-        jprogram.typeOracle.computeBeforeAST();
-
-        // (2) Create our own Java AST from the JDT AST.
-        GenerateJavaAST.exec(allTypeDeclarations, typeMap, jprogram, options);
-
-        // GenerateJavaAST can uncover semantic JSNI errors; report & abort
-        checkForErrors(logger, goldenCuds, true);
-
-        Memory.maybeDumpMemory("AstBuilt");
-
-        // Allow GC
-        goldenCuds = null;
-        typeMap = null;
-        allTypeDeclarations = null;
+        precompilationMetrics.setFinalTypeOracleTypes(finalTypeOracleTypes);
       }
 
+      // Free up memory.
+      rpo.clear();
+
+      if (options.isSoycEnabled()) {
+        SourceInfoCorrelator.exec(jprogram);
+      }
+
+      // Compute all super type/sub type info
+      jprogram.typeOracle.computeBeforeAST();
+
       Memory.maybeDumpMemory("AstOnly");
       AstDumper.maybeDumpAST(jprogram);
 
@@ -649,22 +578,12 @@
         AssertionRemover.exec(jprogram);
       }
 
-      if (!GwtAstBuilder.ENABLED) {
-        // Replace GWT.create calls with JGwtCreate nodes.
-        ReplaceRebinds.exec(logger, jprogram, rpo);
-      }
-
       // Fix up GWT.runAsync()
       if (module != null && options.isRunAsyncEnabled()) {
         ReplaceRunAsyncs.exec(logger, jprogram);
         CodeSplitter.pickInitialLoadSequence(logger, jprogram, module.getProperties());
       }
 
-      if (!GwtAstBuilder.ENABLED) {
-        // Resolve entry points, rebinding non-static entry points.
-        findEntryPoints(logger, rpo, declEntryPts, jprogram);
-      }
-
       ImplementClassLiteralsAsFields.exec(jprogram);
 
       /*
@@ -875,48 +794,6 @@
     return stats;
   }
 
-  /**
-   * Look through the list of compiled units for errors and log them to the
-   * console.
-   * 
-   * @param logger logger to use for compilation errors
-   * @param cuds compiled units to analyze for errors.
-   * @param itemizeErrors log each error or simply log one message if the build
-   *          failed.
-   * @throws UnableToCompleteException if a compilation error is found in the
-   *           cuds argument.
-   */
-  static void checkForErrors(TreeLogger logger, CompilationUnitDeclaration[] cuds,
-      boolean itemizeErrors) throws UnableToCompleteException {
-    Event checkForErrorsEvent = SpeedTracerLogger.start(CompilerEventType.CHECK_FOR_ERRORS);
-    boolean compilationFailed = false;
-    if (cuds.length == 0) {
-      compilationFailed = true;
-    }
-    for (CompilationUnitDeclaration cud : cuds) {
-      final CompilationResult result = cud.compilationResult();
-      if (result.hasErrors()) {
-        compilationFailed = true;
-        // Early out if we don't need to itemize.
-        if (!itemizeErrors) {
-          break;
-        }
-        String typeName = new String(cud.getMainTypeName());
-        CompilationProblemReporter.reportErrors(logger, result.getErrors(), new String(cud
-            .getFileName()), true, new SourceFetcher() {
-          public String getSource() {
-            return new String(result.getCompilationUnit().getContents());
-          }
-        }, typeName, false);
-      }
-    }
-    checkForErrorsEvent.end();
-    if (compilationFailed) {
-      logger.log(TreeLogger.ERROR, "Cannot proceed due to previous errors", null);
-      throw new UnableToCompleteException();
-    }
-  }
-
   private static MultipleDependencyGraphRecorder chooseDependencyRecorder(boolean soycEnabled,
       OutputStream out) {
     MultipleDependencyGraphRecorder dependencyRecorder = CodeSplitter.NULL_RECORDER;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
index 0ed7343..7b127d2 100755
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
@@ -83,15 +83,6 @@
   }
 
   /**
-   * TODO: remove me, just for source compatibility.
-   */
-  @Deprecated
-  public void addField(int index, JField field) {
-    assert field.getEnclosingType() == this;
-    fields = Lists.add(fields, index, field);
-  }
-
-  /**
    * Adds a field to this type.
    */
   public void addField(JField field) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
index 63351a5..95aba96 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
@@ -16,14 +16,10 @@
 package com.google.gwt.dev.jjs.ast;
 
 import com.google.gwt.dev.jjs.Correlation.Literal;
-import com.google.gwt.dev.jjs.CorrelationFactory;
-import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory;
 import com.google.gwt.dev.jjs.InternalCompilerException;
 import com.google.gwt.dev.jjs.SourceInfo;
 import com.google.gwt.dev.jjs.SourceOrigin;
-import com.google.gwt.dev.jjs.ast.JField.Disposition;
 import com.google.gwt.dev.jjs.ast.js.JsCastMap;
-import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
 import com.google.gwt.dev.jjs.impl.CodeSplitter;
 import com.google.gwt.dev.util.collect.Lists;
 
@@ -333,11 +329,6 @@
 
   private Map<JType, JField> classLiteralFields;
 
-  /**
-   * A factory to create correlations.
-   */
-  private final CorrelationFactory correlator;
-
   private final List<JMethod> entryMethods = new ArrayList<JMethod>();
 
   private final Map<String, JField> indexedFields = new HashMap<String, JField>();
@@ -379,10 +370,6 @@
 
   private JClassType typeString;
 
-  public JProgram() {
-    this(DummyCorrelationFactory.INSTANCE);
-  }
-
   /**
    * Constructor.
    * 
@@ -391,10 +378,8 @@
    *          will collect extra data during the compilation cycle, but at a
    *          cost of memory and object allocations.
    */
-  public JProgram(CorrelationFactory correlator) {
-    super(correlator.makeSourceInfo(SourceOrigin.create(0, JProgram.class.getName())));
-
-    this.correlator = correlator;
+  public JProgram() {
+    super(SourceOrigin.UNKNOWN);
   }
 
   public void addEntryMethod(JMethod entryPoint) {
@@ -445,115 +430,6 @@
     }
   }
 
-  public JClassType createClass(SourceInfo info, String name, boolean isAbstract, boolean isFinal) {
-    JClassType x = new JClassType(info, name, isAbstract, isFinal);
-    addType(x);
-    return x;
-  }
-
-  public JConstructor createConstructor(SourceInfo info, JClassType enclosingType) {
-    JConstructor x = new JConstructor(info, enclosingType);
-    x.setBody(new JMethodBody(info));
-    if (indexedTypes.containsValue(enclosingType)) {
-      indexedMethods.put(enclosingType.getShortName() + '.' + enclosingType.getShortName(), x);
-    }
-
-    enclosingType.addMethod(x);
-    return x;
-  }
-
-  public JEnumType createEnum(SourceInfo info, String name, boolean isAbstract) {
-    JEnumType x = new JEnumType(info, name, isAbstract);
-    x.setSuperClass(getTypeJavaLangEnum());
-
-    allTypes.add(x);
-    putIntoTypeMap(name, x);
-
-    return x;
-  }
-
-  public JField createEnumField(SourceInfo info, String name, JEnumType enclosingType,
-      JClassType type, int ordinal) {
-    assert (name != null);
-    assert (type != null);
-    assert (ordinal >= 0);
-
-    JEnumField x = new JEnumField(info, name, ordinal, enclosingType, type);
-    enclosingType.addField(x);
-    return x;
-  }
-
-  public JField createField(SourceInfo info, String name, JDeclaredType enclosingType, JType type,
-      boolean isStatic, Disposition disposition) {
-    assert (name != null);
-    assert (enclosingType != null);
-    assert (type != null);
-
-    JField x = new JField(info, name, enclosingType, type, isStatic, disposition);
-
-    if (indexedTypes.containsValue(enclosingType)) {
-      indexedFields.put(enclosingType.getShortName() + '.' + name, x);
-    }
-
-    enclosingType.addField(x);
-    return x;
-  }
-
-  public JInterfaceType createInterface(SourceInfo info, String name) {
-    JInterfaceType x = new JInterfaceType(info, name);
-    addType(x);
-    return x;
-  }
-
-  public JMethod createMethod(SourceInfo info, String name, JDeclaredType enclosingType,
-      JType returnType, boolean isAbstract, boolean isStatic, boolean isFinal,
-      AccessModifier access, boolean isNative) {
-    assert (name != null);
-    assert (enclosingType != null);
-    assert (returnType != null);
-    assert (!isAbstract || !isNative);
-    JMethod x =
-        new JMethod(info, name, enclosingType, returnType, isAbstract, isStatic, isFinal, access);
-    if (isNative) {
-      x.setBody(new JsniMethodBody(info));
-    } else if (!isAbstract) {
-      x.setBody(new JMethodBody(info));
-    }
-
-    if (access != AccessModifier.PRIVATE && indexedTypes.containsValue(enclosingType)) {
-      indexedMethods.put(enclosingType.getShortName() + '.' + name, x);
-    }
-
-    enclosingType.addMethod(x);
-    return x;
-  }
-
-  /**
-   * Create a SourceInfo object when the source is derived from a physical
-   * location.
-   */
-  public SourceInfo createSourceInfo(int startPos, int endPos, int startLine, String fileName) {
-    return correlator.makeSourceInfo(SourceOrigin.create(startPos, endPos, startLine, fileName));
-  }
-
-  /**
-   * Create a SourceInfo object when the source is derived from a physical
-   * location.
-   */
-  public SourceInfo createSourceInfo(int startLine, String fileName) {
-    return correlator.makeSourceInfo(SourceOrigin.create(startLine, fileName));
-  }
-
-  /**
-   * Create a SourceInfo object when the source is created by the compiler
-   * itself.
-   */
-  public SourceInfo createSourceInfoSynthetic(Class<?> caller) {
-    // TODO: consider using Java stack frames to discover the caller's file
-    // and line number.
-    return createSourceInfo(0, caller.getName());
-  }
-
   /**
    * Return the least upper bound of a set of types. That is, the smallest type
    * that is a supertype of all the input types.
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
deleted file mode 100644
index 83bd75d..0000000
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
+++ /dev/null
@@ -1,1010 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jjs.impl;
-
-import com.google.gwt.dev.javac.JsniCollector;
-import com.google.gwt.dev.jdt.AbstractCompiler.CompilationResults;
-import com.google.gwt.dev.jdt.SafeASTVisitor;
-import com.google.gwt.dev.jjs.HasSourceInfo;
-import com.google.gwt.dev.jjs.InternalCompilerException;
-import com.google.gwt.dev.jjs.SourceInfo;
-import com.google.gwt.dev.jjs.SourceOrigin;
-import com.google.gwt.dev.jjs.ast.AccessModifier;
-import com.google.gwt.dev.jjs.ast.JClassType;
-import com.google.gwt.dev.jjs.ast.JConstructor;
-import com.google.gwt.dev.jjs.ast.JDeclaredType;
-import com.google.gwt.dev.jjs.ast.JEnumType;
-import com.google.gwt.dev.jjs.ast.JField;
-import com.google.gwt.dev.jjs.ast.JField.Disposition;
-import com.google.gwt.dev.jjs.ast.JInterfaceType;
-import com.google.gwt.dev.jjs.ast.JLocal;
-import com.google.gwt.dev.jjs.ast.JMethod;
-import com.google.gwt.dev.jjs.ast.JMethodBody;
-import com.google.gwt.dev.jjs.ast.JNullType;
-import com.google.gwt.dev.jjs.ast.JParameter;
-import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.jjs.ast.JReferenceType;
-import com.google.gwt.dev.jjs.ast.JType;
-import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
-import com.google.gwt.dev.js.JsAbstractSymbolResolver;
-import com.google.gwt.dev.js.ast.JsFunction;
-import com.google.gwt.dev.js.ast.JsName;
-import com.google.gwt.dev.js.ast.JsNameRef;
-import com.google.gwt.dev.js.ast.JsNode;
-import com.google.gwt.dev.js.ast.JsParameter;
-import com.google.gwt.dev.js.ast.JsProgram;
-import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
-
-import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
-import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Expression;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Statement;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
-import org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.util.Util;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * This is a Builder for {@link TypeMap}. The whole point of this pass is to
- * create raw unfinished, unlinked AST nodes for types, methods, fields, and
- * parameters, and to map the original JDT nodes to these AST nodes. That way
- * when GenerateJavaDom runs, it just uses the TypeMap output from this Builder
- * to retrieve whatever referenceable nodes it needs without worrying about
- * whether they need to be created. Building our AST from JDT starts here.
- */
-public class BuildTypeMap {
-
-  /**
-   * Creates JNodes for every method, field, initializer, parameter, and local
-   * and memorizes the mapping from the JDT Binding to the corresponding JNode
-   * for each thing created. Note that this pass also 1) sets up the super
-   * type(s) for any member or local types created in BuildTypeMapVisitor (see
-   * the comments there about why it had to be deferred). 2) adds each
-   * user-defined type to a flat list. 3) Creates JNodes for all methods and
-   * variables and memorizes the mapping from the JDT Binding to the
-   * corresponding JNode for each created method and variable. 4) Maps all
-   * synthetic arguments and fields for nested and local classes. 5) Slurps in
-   * JSNI code for native methods as an opaque string.
-   * 
-   * Note that methods and fields are not added to their classes here, that
-   * isn't done until {@link GenerateJavaAST}.
-   */
-  private class BuildDeclMapVisitor extends SafeASTVisitor {
-
-    private String currentFileName;
-    private int[] currentSeparatorPositions;
-    private final List<TypeDeclaration> typeDecls = new ArrayList<TypeDeclaration>();
-
-    public TypeDeclaration[] getTypeDeclarataions() {
-      return typeDecls.toArray(new TypeDeclaration[typeDecls.size()]);
-    }
-
-    @Override
-    public boolean visit(AnnotationMethodDeclaration methodDeclaration, ClassScope scope) {
-      return visit((MethodDeclaration) methodDeclaration, scope);
-    }
-
-    @Override
-    public boolean visit(Argument argument, BlockScope scope) {
-      try {
-        if (scope == scope.methodScope()) {
-          return true;
-        }
-
-        JMethodBody enclosingBody = findEnclosingMethod(scope);
-        if (enclosingBody == null) {
-          // Happens in the case of external types
-          return true;
-        }
-        SourceInfo info = makeSourceInfo(argument, enclosingBody.getMethod());
-        LocalVariableBinding b = argument.binding;
-        JType localType = getType(b.type);
-        JLocal newLocal =
-            JProgram.createLocal(info, String.valueOf(argument.name), localType, b.isFinal(),
-                enclosingBody);
-        typeMap.put(b, newLocal);
-        return true;
-      } catch (Throwable e) {
-        throw translateException(argument, e);
-      }
-    }
-
-    @Override
-    public boolean visit(ConstructorDeclaration ctorDecl, ClassScope scope) {
-      try {
-        MethodBinding b = ctorDecl.binding;
-        JClassType enclosingType = (JClassType) getType(scope.enclosingSourceType());
-        SourceInfo info = makeSourceInfo(ctorDecl, enclosingType);
-        processConstructor(b, ctorDecl, info);
-        return true;
-      } catch (Throwable e) {
-        throw translateException(ctorDecl, e);
-      }
-    }
-
-    @Override
-    public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
-      try {
-        FieldBinding b = fieldDeclaration.binding;
-        JDeclaredType enclosingType = (JDeclaredType) getType(scope.enclosingSourceType());
-        SourceInfo info = makeSourceInfo(fieldDeclaration, enclosingType);
-        Expression initialization = fieldDeclaration.initialization;
-        if (initialization != null && initialization instanceof AllocationExpression
-            && ((AllocationExpression) initialization).enumConstant != null) {
-          createEnumField(info, b, enclosingType);
-        } else {
-          createField(info, b, enclosingType);
-        }
-        return true;
-      } catch (Throwable e) {
-        throw translateException(fieldDeclaration, e);
-      }
-    }
-
-    @Override
-    public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
-      try {
-        LocalVariableBinding b = localDeclaration.binding;
-        TypeBinding resolvedType = localDeclaration.type.resolvedType;
-        JType localType;
-        if (resolvedType.constantPoolName() != null) {
-          localType = getType(resolvedType);
-        } else {
-          // Special case, a statically unreachable local type.
-          localType = JNullType.INSTANCE;
-        }
-        JMethodBody enclosingBody = findEnclosingMethod(scope);
-        if (enclosingBody == null) {
-          // Happens in the case of external types
-          return true;
-        }
-        SourceInfo info = makeSourceInfo(localDeclaration, enclosingBody.getMethod());
-        JLocal newLocal =
-            JProgram.createLocal(info, String.valueOf(localDeclaration.name), localType, b
-                .isFinal(), enclosingBody);
-        typeMap.put(b, newLocal);
-        return true;
-      } catch (Throwable e) {
-        throw translateException(localDeclaration, e);
-      }
-    }
-
-    @Override
-    public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
-      try {
-        MethodBinding b = methodDeclaration.binding;
-        JDeclaredType enclosingType = (JDeclaredType) getType(scope.enclosingSourceType());
-        SourceInfo info = makeSourceInfo(methodDeclaration, enclosingType);
-        JMethod newMethod = processMethodBinding(b, enclosingType, info);
-        SourceInfo methodInfo = makeSourceInfo(methodDeclaration, newMethod);
-        mapParameters(newMethod, methodDeclaration, methodInfo);
-        info.addCorrelation(info.getCorrelator().by(newMethod));
-
-        if (newMethod.isNative()) {
-          processNativeMethod(methodDeclaration, info, enclosingType, newMethod);
-        }
-
-        return true;
-      } catch (Throwable e) {
-        throw translateException(methodDeclaration, e);
-      }
-    }
-
-    @Override
-    public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
-      return process(memberTypeDeclaration);
-    }
-
-    @Override
-    public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
-      return process(typeDeclaration);
-    }
-
-    @Override
-    public boolean visitValid(TypeDeclaration localTypeDeclaration, BlockScope scope) {
-      return process(localTypeDeclaration);
-    }
-
-    private JField createEnumField(SourceInfo info, FieldBinding binding,
-        JReferenceType enclosingType) {
-      JType type = getType(binding.type);
-      JField field =
-          program.createEnumField(info, String.valueOf(binding.name), (JEnumType) enclosingType,
-              (JClassType) type, binding.original().id);
-      info.addCorrelation(info.getCorrelator().by(field));
-      typeMap.put(binding, field);
-      return field;
-    }
-
-    private JMethodBody findEnclosingMethod(BlockScope scope) {
-      JMethod method;
-      MethodScope methodScope = scope.methodScope();
-      if (methodScope.isInsideInitializer()) {
-        JDeclaredType enclosingType =
-            (JDeclaredType) getType(scope.classScope().referenceContext.binding);
-        if (methodScope.isStatic) {
-          // clinit
-          method = enclosingType.getMethods().get(0);
-        } else {
-          // init
-          assert (enclosingType instanceof JClassType);
-          method = enclosingType.getMethods().get(1);
-        }
-      } else {
-        AbstractMethodDeclaration referenceMethod = methodScope.referenceMethod();
-        method = (JMethod) typeMap.get(referenceMethod.binding);
-      }
-      assert !method.isNative() && !method.isAbstract();
-      return (JMethodBody) (method.isExternal() ? null : method.getBody());
-    }
-
-    private SourceInfo makeSourceInfo(AbstractMethodDeclaration methodDecl, HasSourceInfo enclosing) {
-      int startLine =
-          Util.getLineNumber(methodDecl.sourceStart, currentSeparatorPositions, 0,
-              currentSeparatorPositions.length - 1);
-      SourceOrigin toReturn =
-          SourceOrigin.create(methodDecl.sourceStart, methodDecl.bodyEnd, startLine,
-              currentFileName);
-      if (enclosing != null) {
-        return enclosing.getSourceInfo().makeChild(toReturn);
-      }
-      return toReturn;
-    }
-
-    private SourceInfo makeSourceInfo(Statement stmt, HasSourceInfo enclosing) {
-      int startLine =
-          Util.getLineNumber(stmt.sourceStart, currentSeparatorPositions, 0,
-              currentSeparatorPositions.length - 1);
-      SourceOrigin toReturn =
-          SourceOrigin.create(stmt.sourceStart, stmt.sourceEnd, startLine, currentFileName);
-      if (enclosing != null) {
-        return enclosing.getSourceInfo().makeChild(toReturn);
-      }
-      return toReturn;
-    }
-
-    /**
-     * Add synthetic fields, setup super types. You'll notice that we DON'T have
-     * any concept of "inner" or "outer" types in our AST. Truth is, we found it
-     * easier to simply model everything as flat classes and emulate the nesting
-     * behavior (and final local access on local classes). It's much closer to
-     * how we'll eventually be generating JavaScript code (code generation is
-     * more straightforward), it makes for fewer kinds of things to worry about
-     * when optimizing (more aggressive optimizations), and it's how Java
-     * actually implements the stuff under the hood anyway.
-     */
-    private boolean process(TypeDeclaration typeDeclaration) {
-      CompilationResult compResult = typeDeclaration.compilationResult;
-      currentSeparatorPositions = compResult.lineSeparatorPositions;
-      currentFileName = String.valueOf(compResult.fileName);
-
-      if (BuildTypeMap.this.process(typeDeclaration.binding)) {
-        if (!linker.isExternalType(dotify(typeDeclaration.binding.compoundName))) {
-          typeDecls.add(typeDeclaration);
-        }
-        return true;
-      }
-
-      return false;
-    }
-
-    private void processNativeMethod(MethodDeclaration methodDeclaration, SourceInfo info,
-        JDeclaredType enclosingType, JMethod newMethod) {
-      // TODO: use existing parsed JSNI functions from CompilationState.
-      // Handle JSNI block
-      char[] source = methodDeclaration.compilationResult().getCompilationUnit().getContents();
-      String unitSource = String.valueOf(source);
-      JsFunction jsFunction =
-          JsniCollector.parseJsniFunction(methodDeclaration, unitSource, enclosingType.getName(),
-              info, jsProgram.getScope());
-      if (jsFunction != null) {
-        jsFunction.setFromJava(true);
-        ((JsniMethodBody) newMethod.getBody()).setFunc(jsFunction);
-        // Ensure that we've resolved the parameter and local references within
-        // the JSNI method for later pruning.
-        JsParameterResolver localResolver = new JsParameterResolver(jsFunction);
-        localResolver.accept(jsFunction);
-      }
-    }
-
-    private InternalCompilerException translateException(AbstractMethodDeclaration amd, Throwable e) {
-      if (e instanceof VirtualMachineError) {
-        // Always rethrow VM errors (an attempt to wrap may fail).
-        throw (VirtualMachineError) e;
-      }
-      InternalCompilerException ice;
-      if (e instanceof InternalCompilerException) {
-        ice = (InternalCompilerException) e;
-      } else {
-        ice = new InternalCompilerException("Error building type map", e);
-      }
-      ice.addNode(amd.getClass().getName(), amd.toString(), makeSourceInfo(amd, null));
-      return ice;
-    }
-
-    private InternalCompilerException translateException(Statement stmt, Throwable e) {
-      if (e instanceof VirtualMachineError) {
-        // Always rethrow VM errors (an attempt to wrap may fail).
-        throw (VirtualMachineError) e;
-      }
-      InternalCompilerException ice;
-      if (e instanceof InternalCompilerException) {
-        ice = (InternalCompilerException) e;
-      } else {
-        ice = new InternalCompilerException("Error building type map", e);
-      }
-      ice.addNode(stmt.getClass().getName(), stmt.toString(), makeSourceInfo(stmt, null));
-      return ice;
-    }
-  }
-
-  /**
-   * Creates JNodes for every type and memorizes the mapping from the JDT
-   * Binding to the corresponding JNode for each created type. Note that since
-   * there could be forward references, it is not possible to set up super
-   * types; it must be done is a subsequent pass.
-   */
-  private class BuildTypeMapVisitor extends SafeASTVisitor {
-
-    @Override
-    public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
-      return process(memberTypeDeclaration);
-    }
-
-    @Override
-    public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
-      return process(typeDeclaration);
-    }
-
-    @Override
-    public boolean visitValid(TypeDeclaration localTypeDeclaration, BlockScope scope) {
-      assert (TypeDeclaration.kind(localTypeDeclaration.modifiers) != TypeDeclaration.INTERFACE_DECL);
-      return process(localTypeDeclaration);
-    }
-
-    private SourceInfo makeSourceInfo(TypeDeclaration typeDecl) {
-      CompilationResult compResult = typeDecl.compilationResult;
-      int[] indexes = compResult.lineSeparatorPositions;
-      String fileName = String.valueOf(compResult.fileName);
-      int startLine = Util.getLineNumber(typeDecl.sourceStart, indexes, 0, indexes.length - 1);
-      return program.createSourceInfo(typeDecl.sourceStart, typeDecl.bodyEnd, startLine, fileName);
-    }
-
-    private boolean process(TypeDeclaration typeDeclaration) {
-      try {
-        SourceTypeBinding binding = typeDeclaration.binding;
-        String name = dotify(binding.compoundName);
-        if (binding instanceof LocalTypeBinding) {
-          char[] localName = binding.constantPoolName();
-          name = new String(localName).replace('/', '.');
-        }
-
-        SourceInfo info = makeSourceInfo(typeDeclaration);
-        typeMap.put(binding, createType(name, info, binding));
-        return true;
-      } catch (Throwable e) {
-        throw translateException(typeDeclaration, e);
-      }
-    }
-
-    private InternalCompilerException translateException(TypeDeclaration typeDecl, Throwable e) {
-      if (e instanceof VirtualMachineError) {
-        // Always rethrow VM errors (an attempt to wrap may fail).
-        throw (VirtualMachineError) e;
-      }
-      InternalCompilerException ice;
-      if (e instanceof InternalCompilerException) {
-        ice = (InternalCompilerException) e;
-      } else {
-        ice = new InternalCompilerException("Error building type map", e);
-      }
-      ice.addNode(typeDecl.getClass().getName(), typeDecl.toString(), makeSourceInfo(typeDecl));
-      return ice;
-    }
-  }
-
-  private class ExternalTypeCreator implements ExternalTypeTask {
-
-    public void process(String klass, BinaryTypeBinding binding) {
-      if (program.getFromTypeMap(klass) == null) {
-        // NB(tobyr) There are a few cases where certain compiler intrinsic
-        // types are only needed if the program references them
-        // (e.g. boxed numeric types). If we don't have the binding for those
-        // types, we can safely ignore it.
-        createExternalType(klass, binding);
-      }
-    }
-  }
-
-  private class ExternalTypeResolver implements ExternalTypeTask {
-
-    public void process(String klass, BinaryTypeBinding binding) {
-      if (binding != null) {
-        JDeclaredType type = program.getFromTypeMap(klass);
-        resolve(type, binding);
-      }
-    }
-  }
-
-  private interface ExternalTypeTask {
-
-    void process(String klass, BinaryTypeBinding binding);
-  }
-
-  /**
-   * Resolves the scope of JS identifiers solely within the scope of a method.
-   */
-  private static class JsParameterResolver extends JsAbstractSymbolResolver {
-    private final JsFunction jsFunction;
-
-    public JsParameterResolver(JsFunction jsFunction) {
-      this.jsFunction = jsFunction;
-    }
-
-    @Override
-    public void resolve(JsNameRef x) {
-      // Only resolve unqualified names
-      if (x.getQualifier() == null) {
-        JsName name = getScope().findExistingName(x.getIdent());
-
-        // Ensure that we're resolving a name from the function's parameters
-        JsNode node = name == null ? null : name.getStaticRef();
-        if (node instanceof JsParameter) {
-          JsParameter param = (JsParameter) node;
-          if (jsFunction.getParameters().contains(param)) {
-            x.resolve(name);
-          }
-        }
-      }
-    }
-  }
-
-  // TODO: Remove this overload altogether at some point.
-
-  public static TypeDeclaration[] exec(TypeMap typeMap, CompilationResults results,
-      JsProgram jsProgram, TypeLinker linker) {
-    BuildTypeMap btm = new BuildTypeMap(typeMap, jsProgram, linker, results.compiledUnits);
-    Event buildTypeMapEvent = SpeedTracerLogger.start(CompilerEventType.BUILD_TYPE_MAP_FOR_AST);
-    btm.createPeersForUnits();
-    btm.resolveExternalTypes(results.binaryBindings);
-    TypeDeclaration[] result = btm.createPeersForNonTypeDecls();
-    buildTypeMapEvent.end();
-    return result;
-  }
-
-  public static TypeDeclaration[] exec(TypeMap typeMap, CompilationUnitDeclaration[] unitDecls,
-      JsProgram jsProgram) {
-    CompilationResults results =
-        new CompilationResults(unitDecls, new HashMap<String, BinaryTypeBinding>(0));
-    return exec(typeMap, results, jsProgram, TypeLinker.NULL_TYPE_LINKER);
-  }
-
-  static String dotify(char[][] name) {
-    StringBuffer result = new StringBuffer();
-    for (int i = 0; i < name.length; ++i) {
-      if (i > 0) {
-        result.append('.');
-      }
-
-      result.append(name[i]);
-    }
-    return result.toString();
-  }
-
-  private final JsProgram jsProgram;
-  private final TypeLinker linker;
-  private final JProgram program;
-  private final TypeMap typeMap;
-  private final CompilationUnitDeclaration[] unitDecls;
-
-  private BuildTypeMap(TypeMap typeMap, JsProgram jsProgram, TypeLinker linker,
-      CompilationUnitDeclaration[] unitDecls) {
-    this.typeMap = typeMap;
-    this.program = typeMap.getProgram();
-    this.jsProgram = jsProgram;
-    this.linker = linker;
-    this.unitDecls = unitDecls;
-  }
-
-  private void addThrownExceptions(MethodBinding methodBinding, JMethod method) {
-    for (ReferenceBinding thrownBinding : methodBinding.thrownExceptions) {
-      JClassType type = (JClassType) getType(thrownBinding.erasure());
-      method.addThrownException(type);
-    }
-  }
-
-  private JDeclaredType createExternalType(String name, ReferenceBinding binding) {
-    char[] chars = binding.getFileName();
-    String fileName = chars == null ? "" : String.valueOf(chars);
-    SourceInfo sourceInfo = SourceOrigin.create(0, fileName);
-    JDeclaredType type = createType(name, sourceInfo, binding);
-    typeMap.put(binding, type);
-    return type;
-  }
-
-  private JField createField(SourceInfo info, FieldBinding binding, JDeclaredType enclosingType) {
-    JType type = getType(binding.type);
-    JField field =
-        program.createField(info, String.valueOf(binding.name), enclosingType, type, binding
-            .isStatic(), GwtAstBuilder.getFieldDisposition(binding));
-    typeMap.put(binding, field);
-    info.addCorrelation(info.getCorrelator().by(field));
-    return field;
-  }
-
-  private JField createField(SyntheticArgumentBinding binding, JDeclaredType enclosingType,
-      Disposition disposition) {
-    JType type = getType(binding.type);
-    SourceInfo info = enclosingType.getSourceInfo().makeChild();
-    JField field =
-        program.createField(info, String.valueOf(binding.name), enclosingType, type, false,
-            disposition);
-    info.addCorrelation(info.getCorrelator().by(field));
-    if (binding.matchingField != null) {
-      typeMap.put(binding.matchingField, field);
-    }
-    typeMap.put(binding, field);
-    return field;
-  }
-
-  private void createMethod(MethodBinding binding, SourceInfo info) {
-    JDeclaredType enclosingType = (JDeclaredType) getType(binding.declaringClass);
-    JMethod newMethod = processMethodBinding(binding, enclosingType, info);
-    mapParameters(newMethod, binding, info);
-  }
-
-  private JParameter createParameter(LocalVariableBinding binding, JMethod enclosingMethod,
-      SourceInfo info) {
-    JType type = getType(binding.type);
-    JParameter param =
-        JProgram.createParameter(info, String.valueOf(binding.name), type, binding.isFinal(),
-            false, enclosingMethod);
-    typeMap.put(binding, param);
-    return param;
-  }
-
-  private JParameter createParameter(SyntheticArgumentBinding arg, String argName,
-      JMethod enclosingMethod) {
-    JType type = getType(arg.type);
-    JParameter param =
-        JProgram.createParameter(enclosingMethod.getSourceInfo(), argName, type, true, false,
-            enclosingMethod);
-    return param;
-  }
-
-  private JParameter createParameter(TypeBinding paramType, JMethod enclosingMethod,
-      SourceInfo info, int argPosition) {
-    JType type = getType(paramType);
-    // TODO(tobyr) Get the actual param name if it's present in debug info
-    // or otherwise.
-    String syntheticParamName = "arg" + argPosition;
-    JParameter param =
-        JProgram.createParameter(info, syntheticParamName, type, true, false, enclosingMethod);
-    // Don't need to put the parameter in the TypeMap as it won't be looked
-    // up for binary types.
-    return param;
-  }
-
-  private TypeDeclaration[] createPeersForNonTypeDecls() {
-    // Traverse to create our JNode peers for each method, field,
-    // parameter, and local
-    BuildDeclMapVisitor v = new BuildDeclMapVisitor();
-    for (CompilationUnitDeclaration unitDecl : unitDecls) {
-      unitDecl.traverse(v, unitDecl.scope);
-    }
-    return v.getTypeDeclarataions();
-  }
-
-  private void createPeersForUnits() {
-    // Traverse to create our JNode peers for each type
-    BuildTypeMapVisitor v = new BuildTypeMapVisitor();
-    for (CompilationUnitDeclaration unitDecl : unitDecls) {
-      unitDecl.traverse(v, unitDecl.scope);
-    }
-  }
-
-  private JDeclaredType createType(String name, SourceInfo info, ReferenceBinding binding) {
-
-    JDeclaredType newType;
-    if (binding.isClass()) {
-      newType = program.createClass(info, name, binding.isAbstract(), binding.isFinal());
-    } else if (binding.isInterface() || binding.isAnnotationType()) {
-      newType = program.createInterface(info, name);
-    } else if (binding.isEnum()) {
-      if (binding.isAnonymousType()) {
-        // Don't model an enum subclass as a JEnumType.
-        newType = program.createClass(info, name, false, true);
-      } else {
-        newType = program.createEnum(info, name, binding.isAbstract());
-      }
-    } else {
-      throw new InternalCompilerException("ReferenceBinding is not a class, interface, or enum.");
-    }
-
-    info.addCorrelation(info.getCorrelator().by(newType));
-
-    /**
-     * We emulate static initializers and instance initializers as methods. As
-     * in other cases, this gives us: simpler AST, easier to optimize, more like
-     * output JavaScript. Clinit is always in slot 0, init (if it exists) is
-     * always in slot 1.
-     */
-    SourceInfo child = info.makeChild();
-    JMethod clinit =
-        program.createMethod(child, "$clinit", newType, program.getTypeVoid(), false, true, true,
-            AccessModifier.PRIVATE, false);
-    clinit.freezeParamTypes();
-    clinit.setSynthetic();
-    child.addCorrelation(info.getCorrelator().by(clinit));
-
-    if (newType instanceof JClassType) {
-      child = info.makeChild();
-      JMethod init =
-          program.createMethod(child, "$init", newType, program.getTypeVoid(), false, false, true,
-              AccessModifier.PRIVATE, false);
-      init.freezeParamTypes();
-      init.setSynthetic();
-      child.addCorrelation(info.getCorrelator().by(init));
-    }
-
-    newType.setExternal(linker.isExternalType(newType.getName()));
-    return newType;
-  }
-
-  private void forEachExternalType(Map<String, BinaryTypeBinding> bindings, ExternalTypeTask task) {
-    for (Map.Entry<String, BinaryTypeBinding> entry : bindings.entrySet()) {
-      String klass = entry.getKey();
-      if (linker.isExternalType(klass)) {
-        BinaryTypeBinding binding = bindings.get(klass);
-        if (binding != null) {
-          task.process(klass, binding);
-        }
-      }
-    }
-  }
-
-  private JType getType(TypeBinding binding) {
-    JType type = (JType) typeMap.tryGet(binding);
-
-    if (type != null) {
-      return type;
-    }
-
-    if (binding instanceof ArrayBinding) {
-      binding = ((ArrayBinding) binding).leafComponentType;
-    }
-
-    if (!(binding instanceof ReferenceBinding)) {
-      throw new InternalCompilerException("Expected a ReferenceBinding but received a "
-          + binding.getClass());
-    }
-
-    ReferenceBinding refBinding = (ReferenceBinding) binding;
-    String name = dotify(refBinding.compoundName);
-    if (!linker.isExternalType(name)) {
-      // typeMap.get() will fail with an appropriate exception
-      return (JType) typeMap.get(binding);
-    }
-
-    type = createExternalType(name, refBinding);
-    resolve((JDeclaredType) type, refBinding);
-    return type;
-  }
-
-  private void mapParameters(JMethod method, AbstractMethodDeclaration x, SourceInfo info) {
-    MethodBinding b = x.binding;
-    int paramCount = (b.parameters != null ? b.parameters.length : 0);
-    if (paramCount > 0) {
-      for (int i = 0, n = x.arguments.length; i < n; ++i) {
-        createParameter(x.arguments[i].binding, method, info);
-      }
-    }
-    method.freezeParamTypes();
-  }
-
-  private void mapParameters(JMethod method, MethodBinding binding, SourceInfo info) {
-    int paramCount = binding.parameters != null ? binding.parameters.length : 0;
-    if (paramCount > 0) {
-      int counter = 0;
-      for (TypeBinding argType : binding.parameters) {
-        createParameter(argType, method, info, counter++);
-      }
-    }
-    method.freezeParamTypes();
-  }
-
-  private boolean process(ReferenceBinding binding) {
-    JDeclaredType type = (JDeclaredType) getType(binding);
-
-    try {
-      // Create an override for getClass().
-      if (type instanceof JClassType && type != program.getTypeJavaLangObject()) {
-
-        SourceInfo info = type.getSourceInfo().makeChild();
-        JMethod getClassMethod =
-            program.createMethod(info, "getClass", type, program.getTypeJavaLangClass(), false,
-                false, false, AccessModifier.PUBLIC, false);
-        assert (type.getMethods().get(2) == getClassMethod);
-        getClassMethod.freezeParamTypes();
-        getClassMethod.setSynthetic();
-        info.addCorrelation(info.getCorrelator().by(getClassMethod));
-      }
-
-      if (binding.isNestedType() && !binding.isStatic() && !(binding instanceof BinaryTypeBinding)) {
-        // TODO(tobyr) Do something here for binary types?
-
-        // add synthetic fields for outer this and locals
-        assert (type instanceof JClassType);
-        NestedTypeBinding nestedBinding = (NestedTypeBinding) binding;
-        if (nestedBinding.enclosingInstances != null) {
-          for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
-            SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
-            createField(arg, type, Disposition.THIS_REF);
-          }
-        }
-
-        if (nestedBinding.outerLocalVariables != null) {
-          for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) {
-            SyntheticArgumentBinding arg = nestedBinding.outerLocalVariables[i];
-            // See InnerClassTest.testOuterThisFromSuperCall().
-            boolean isReallyThisRef = false;
-            if (arg.actualOuterLocalVariable instanceof SyntheticArgumentBinding) {
-              SyntheticArgumentBinding outer =
-                  (SyntheticArgumentBinding) arg.actualOuterLocalVariable;
-              if (outer.matchingField != null) {
-                JField field = (JField) typeMap.get(outer.matchingField);
-                if (field.isThisRef()) {
-                  isReallyThisRef = true;
-                }
-              }
-            }
-            createField(arg, type, isReallyThisRef ? Disposition.THIS_REF : Disposition.FINAL);
-          }
-        }
-      }
-
-      ReferenceBinding superClassBinding = binding.superclass();
-      if (type instanceof JClassType && superClassBinding != null) {
-        // TODO: handle separately?
-        assert (binding.superclass().isClass() || binding.superclass().isEnum());
-        JClassType superClass = (JClassType) getType(superClassBinding);
-        ((JClassType) type).setSuperClass(superClass);
-      }
-
-      ReferenceBinding[] superInterfaces = binding.superInterfaces();
-      for (ReferenceBinding superInterfaceBinding : superInterfaces) {
-        assert (superInterfaceBinding.isInterface());
-        JInterfaceType superInterface = (JInterfaceType) getType(superInterfaceBinding);
-        type.addImplements(superInterface);
-      }
-
-      ReferenceBinding enclosingBinding = binding.enclosingType();
-      if (enclosingBinding != null) {
-        type.setEnclosingType((JDeclaredType) getType(enclosingBinding));
-      }
-
-      if (type instanceof JEnumType) {
-        processEnumType(binding, (JEnumType) type);
-      }
-
-      return true;
-    } catch (VirtualMachineError e) {
-      // Always rethrow VM errors (an attempt to wrap may fail).
-      throw e;
-    } catch (InternalCompilerException ice) {
-      ice.addNode(type);
-      throw ice;
-    } catch (Throwable e) {
-      throw new InternalCompilerException(type, "Error building type map", e);
-    }
-  }
-
-  private JConstructor processConstructor(MethodBinding b, ConstructorDeclaration decl,
-      SourceInfo info) {
-    JClassType enclosingType = (JClassType) getType(b.declaringClass);
-    JConstructor newCtor = program.createConstructor(info, enclosingType);
-
-    // Enums have hidden arguments for name and value
-    if (enclosingType.isEnumOrSubclass() != null) {
-      JProgram.createParameter(info, "enum$name", program.getTypeJavaLangString(), true, false,
-          newCtor);
-      JProgram.createParameter(info, "enum$ordinal", program.getTypePrimitiveInt(), true, false,
-          newCtor);
-    }
-
-    ReferenceBinding declaringClass = b.declaringClass;
-    Set<String> alreadyNamedVariables = new HashSet<String>();
-    if (declaringClass.isNestedType() && !declaringClass.isStatic()) {
-      // TODO(tobyr) Do we have to do the equivalent for binary types here
-      // or will this just fall out correctly?
-
-      // add synthetic args for outer this
-      NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
-      if (nestedBinding.enclosingInstances != null) {
-        for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
-          SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
-          String argName = String.valueOf(arg.name);
-          if (alreadyNamedVariables.contains(argName)) {
-            argName += "_" + i;
-          }
-          createParameter(arg, argName, newCtor);
-          alreadyNamedVariables.add(argName);
-        }
-      }
-    }
-
-    // user args
-    if (decl == null) {
-      mapParameters(newCtor, b, info);
-    } else {
-      mapParameters(newCtor, decl, info);
-    }
-    // original params are now frozen
-
-    addThrownExceptions(b, newCtor);
-
-    info.addCorrelation(info.getCorrelator().by(newCtor));
-
-    if (declaringClass.isNestedType() && !declaringClass.isStatic()) {
-      // add synthetic args for locals
-      NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
-      // add synthetic args for outer this and locals
-      if (nestedBinding.outerLocalVariables != null) {
-        for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) {
-          SyntheticArgumentBinding arg = nestedBinding.outerLocalVariables[i];
-          String argName = String.valueOf(arg.name);
-          if (alreadyNamedVariables.contains(argName)) {
-            argName += "_" + i;
-          }
-          createParameter(arg, argName, newCtor);
-          alreadyNamedVariables.add(argName);
-        }
-      }
-    }
-
-    if (enclosingType.isExternal()) {
-      newCtor.setBody(null);
-    }
-
-    typeMap.put(b, newCtor);
-    return newCtor;
-  }
-
-  private void processEnumType(ReferenceBinding binding, JEnumType type) {
-    // Visit the synthetic values() and valueOf() methods.
-    for (MethodBinding methodBinding : binding.methods()) {
-      if (methodBinding instanceof SyntheticMethodBinding) {
-        JMethod newMethod = processMethodBinding(methodBinding, type, type.getSourceInfo());
-        TypeBinding[] parameters = methodBinding.parameters;
-        if (parameters.length == 0) {
-          assert newMethod.getName().equals("values");
-        } else if (parameters.length == 1) {
-          assert newMethod.getName().equals("valueOf");
-          assert typeMap.get(parameters[0]) == program.getTypeJavaLangString();
-          JProgram.createParameter(newMethod.getSourceInfo(), "name", program
-              .getTypeJavaLangString(), true, false, newMethod);
-        } else {
-          assert false;
-        }
-        newMethod.freezeParamTypes();
-      }
-    }
-  }
-
-  private void processExternalMethod(MethodBinding binding, JDeclaredType type) {
-    if (binding.isPrivate()
-        || (type.getName().startsWith("java.") && !binding.isPublic() && !binding.isProtected())) {
-      return;
-    }
-    if (binding.isConstructor()) {
-      processConstructor(binding, null, type.getSourceInfo());
-    } else {
-      createMethod(binding, type.getSourceInfo());
-    }
-  }
-
-  private JMethod processMethodBinding(MethodBinding b, JDeclaredType enclosingType, SourceInfo info) {
-    JType returnType = getType(b.returnType);
-    JMethod newMethod =
-        program.createMethod(info, String.valueOf(b.selector), enclosingType, returnType, b
-            .isAbstract(), b.isStatic(), b.isFinal(), AccessModifier.fromMethodBinding(b), b
-            .isNative());
-    addThrownExceptions(b, newMethod);
-    if (b.isSynthetic()) {
-      newMethod.setSynthetic();
-    }
-
-    if (enclosingType.isExternal()) {
-      newMethod.setBody(null);
-    }
-    typeMap.put(b, newMethod);
-    return newMethod;
-  }
-
-  private void resolve(JDeclaredType type, ReferenceBinding binding) {
-    process(binding);
-
-    for (FieldBinding fieldBinding : binding.fields()) {
-      if (fieldBinding.isPrivate()
-          || (type.getName().startsWith("java.") && !fieldBinding.isPublic() && !fieldBinding
-              .isProtected())) {
-        continue;
-      }
-
-      createField(type.getSourceInfo(), fieldBinding, type);
-    }
-
-    for (MethodBinding methodBinding : binding.methods()) {
-      processExternalMethod(methodBinding, type);
-    }
-
-    if (binding instanceof BinaryTypeBinding) {
-      // Unlike SourceTypeBindings, we have to explicitly ask for bridge methods
-      // for BinaryTypeBindings.
-      try {
-        // TODO(tobyr) Fix so we don't have to use reflection.
-        Method m = BinaryTypeBinding.class.getDeclaredMethod("bridgeMethods");
-        MethodBinding[] bridgeMethods = (MethodBinding[]) m.invoke(binding);
-
-        for (MethodBinding methodBinding : bridgeMethods) {
-          processExternalMethod(methodBinding, type);
-        }
-      } catch (Exception e) {
-        throw new InternalCompilerException("Unexpected failure", e);
-      }
-    }
-  }
-
-  /**
-   * Creates and resolves all external types.
-   */
-  private void resolveExternalTypes(Map<String, BinaryTypeBinding> bindings) {
-    forEachExternalType(bindings, new ExternalTypeCreator());
-    forEachExternalType(bindings, new ExternalTypeResolver());
-  }
-}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
deleted file mode 100644
index 3c4883f..0000000
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
+++ /dev/null
@@ -1,3010 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jjs.impl;
-
-import com.google.gwt.dev.javac.ArtificialRescueChecker.RescueData;
-import com.google.gwt.dev.javac.JsniCollector;
-import com.google.gwt.dev.jjs.InternalCompilerException;
-import com.google.gwt.dev.jjs.JJSOptions;
-import com.google.gwt.dev.jjs.SourceInfo;
-import com.google.gwt.dev.jjs.SourceOrigin;
-import com.google.gwt.dev.jjs.ast.AccessModifier;
-import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.JArrayLength;
-import com.google.gwt.dev.jjs.ast.JArrayRef;
-import com.google.gwt.dev.jjs.ast.JArrayType;
-import com.google.gwt.dev.jjs.ast.JAssertStatement;
-import com.google.gwt.dev.jjs.ast.JBinaryOperation;
-import com.google.gwt.dev.jjs.ast.JBinaryOperator;
-import com.google.gwt.dev.jjs.ast.JBlock;
-import com.google.gwt.dev.jjs.ast.JBooleanLiteral;
-import com.google.gwt.dev.jjs.ast.JBreakStatement;
-import com.google.gwt.dev.jjs.ast.JCaseStatement;
-import com.google.gwt.dev.jjs.ast.JCastOperation;
-import com.google.gwt.dev.jjs.ast.JCharLiteral;
-import com.google.gwt.dev.jjs.ast.JClassLiteral;
-import com.google.gwt.dev.jjs.ast.JClassType;
-import com.google.gwt.dev.jjs.ast.JConditional;
-import com.google.gwt.dev.jjs.ast.JConstructor;
-import com.google.gwt.dev.jjs.ast.JContinueStatement;
-import com.google.gwt.dev.jjs.ast.JDeclarationStatement;
-import com.google.gwt.dev.jjs.ast.JDeclaredType;
-import com.google.gwt.dev.jjs.ast.JDoStatement;
-import com.google.gwt.dev.jjs.ast.JDoubleLiteral;
-import com.google.gwt.dev.jjs.ast.JEnumField;
-import com.google.gwt.dev.jjs.ast.JEnumType;
-import com.google.gwt.dev.jjs.ast.JExpression;
-import com.google.gwt.dev.jjs.ast.JExpressionStatement;
-import com.google.gwt.dev.jjs.ast.JField;
-import com.google.gwt.dev.jjs.ast.JField.Disposition;
-import com.google.gwt.dev.jjs.ast.JFieldRef;
-import com.google.gwt.dev.jjs.ast.JFloatLiteral;
-import com.google.gwt.dev.jjs.ast.JForStatement;
-import com.google.gwt.dev.jjs.ast.JIfStatement;
-import com.google.gwt.dev.jjs.ast.JInstanceOf;
-import com.google.gwt.dev.jjs.ast.JIntLiteral;
-import com.google.gwt.dev.jjs.ast.JInterfaceType;
-import com.google.gwt.dev.jjs.ast.JLabel;
-import com.google.gwt.dev.jjs.ast.JLabeledStatement;
-import com.google.gwt.dev.jjs.ast.JLiteral;
-import com.google.gwt.dev.jjs.ast.JLocal;
-import com.google.gwt.dev.jjs.ast.JLocalRef;
-import com.google.gwt.dev.jjs.ast.JLongLiteral;
-import com.google.gwt.dev.jjs.ast.JMethod;
-import com.google.gwt.dev.jjs.ast.JMethodBody;
-import com.google.gwt.dev.jjs.ast.JMethodCall;
-import com.google.gwt.dev.jjs.ast.JModVisitor;
-import com.google.gwt.dev.jjs.ast.JNewArray;
-import com.google.gwt.dev.jjs.ast.JNewInstance;
-import com.google.gwt.dev.jjs.ast.JNode;
-import com.google.gwt.dev.jjs.ast.JNonNullType;
-import com.google.gwt.dev.jjs.ast.JParameter;
-import com.google.gwt.dev.jjs.ast.JParameterRef;
-import com.google.gwt.dev.jjs.ast.JPostfixOperation;
-import com.google.gwt.dev.jjs.ast.JPrefixOperation;
-import com.google.gwt.dev.jjs.ast.JPrimitiveType;
-import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.jjs.ast.JReferenceType;
-import com.google.gwt.dev.jjs.ast.JReturnStatement;
-import com.google.gwt.dev.jjs.ast.JStatement;
-import com.google.gwt.dev.jjs.ast.JStringLiteral;
-import com.google.gwt.dev.jjs.ast.JSwitchStatement;
-import com.google.gwt.dev.jjs.ast.JThisRef;
-import com.google.gwt.dev.jjs.ast.JThrowStatement;
-import com.google.gwt.dev.jjs.ast.JTryStatement;
-import com.google.gwt.dev.jjs.ast.JType;
-import com.google.gwt.dev.jjs.ast.JTypeOracle;
-import com.google.gwt.dev.jjs.ast.JUnaryOperator;
-import com.google.gwt.dev.jjs.ast.JVariable;
-import com.google.gwt.dev.jjs.ast.JVariableRef;
-import com.google.gwt.dev.jjs.ast.JWhileStatement;
-import com.google.gwt.dev.jjs.ast.js.JsniClassLiteral;
-import com.google.gwt.dev.jjs.ast.js.JsniFieldRef;
-import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
-import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;
-import com.google.gwt.dev.js.ast.JsContext;
-import com.google.gwt.dev.js.ast.JsExpression;
-import com.google.gwt.dev.js.ast.JsModVisitor;
-import com.google.gwt.dev.js.ast.JsNameRef;
-import com.google.gwt.dev.util.JsniRef;
-import com.google.gwt.dev.util.collect.Maps;
-import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
-
-import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression;
-import org.eclipse.jdt.internal.compiler.ast.ASTNode;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
-import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
-import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
-import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
-import org.eclipse.jdt.internal.compiler.ast.AssertStatement;
-import org.eclipse.jdt.internal.compiler.ast.Assignment;
-import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
-import org.eclipse.jdt.internal.compiler.ast.Block;
-import org.eclipse.jdt.internal.compiler.ast.BreakStatement;
-import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
-import org.eclipse.jdt.internal.compiler.ast.CastExpression;
-import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
-import org.eclipse.jdt.internal.compiler.ast.CombinedBinaryExpression;
-import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
-import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
-import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ContinueStatement;
-import org.eclipse.jdt.internal.compiler.ast.DoStatement;
-import org.eclipse.jdt.internal.compiler.ast.EmptyStatement;
-import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
-import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
-import org.eclipse.jdt.internal.compiler.ast.Expression;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.FieldReference;
-import org.eclipse.jdt.internal.compiler.ast.ForStatement;
-import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
-import org.eclipse.jdt.internal.compiler.ast.IfStatement;
-import org.eclipse.jdt.internal.compiler.ast.Initializer;
-import org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression;
-import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
-import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.MessageSend;
-import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
-import org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression;
-import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
-import org.eclipse.jdt.internal.compiler.ast.PostfixExpression;
-import org.eclipse.jdt.internal.compiler.ast.PrefixExpression;
-import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
-import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
-import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
-import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
-import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
-import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
-import org.eclipse.jdt.internal.compiler.ast.Statement;
-import org.eclipse.jdt.internal.compiler.ast.SuperReference;
-import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
-import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement;
-import org.eclipse.jdt.internal.compiler.ast.ThisReference;
-import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
-import org.eclipse.jdt.internal.compiler.ast.TryStatement;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
-import org.eclipse.jdt.internal.compiler.ast.WhileStatement;
-import org.eclipse.jdt.internal.compiler.impl.BooleanConstant;
-import org.eclipse.jdt.internal.compiler.impl.ByteConstant;
-import org.eclipse.jdt.internal.compiler.impl.CharConstant;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
-import org.eclipse.jdt.internal.compiler.impl.DoubleConstant;
-import org.eclipse.jdt.internal.compiler.impl.FloatConstant;
-import org.eclipse.jdt.internal.compiler.impl.IntConstant;
-import org.eclipse.jdt.internal.compiler.impl.LongConstant;
-import org.eclipse.jdt.internal.compiler.impl.ShortConstant;
-import org.eclipse.jdt.internal.compiler.impl.StringConstant;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
-import org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
-import org.eclipse.jdt.internal.compiler.util.Util;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This is the big kahuna where most of the nitty gritty of creating our AST
- * happens. BuildTypeMap must have already run so we have valid mappings between
- * JDT nodes and our already-created AST nodes.
- */
-public class GenerateJavaAST {
-
-  /**
-   * Visit the JDT AST and produce our own AST into the passed-in TypeMap's
-   * JProgram. By the end of this pass, the produced AST should contain every
-   * piece of information we'll ever need about the code. The JDT nodes should
-   * never again be referenced after this.
-   * 
-   * This is implemented as a reflective visitor for JDT's AST. The advantage of
-   * doing it reflectively is that if we run into any JDT nodes we can't handle,
-   * we'll automatically throw an exception. If we had subclassed
-   * {@link org.eclipse.jdt.internal.compiler.ast.ASTNode} we'd have to override
-   * every single method and explicitly throw an exception to get the same
-   * behavior.
-   * 
-   * NOTE ON JDT FORCED OPTIMIZATIONS - If JDT statically determines that a
-   * section of code in unreachable, it won't fully resolve that section of
-   * code. This invalid-state code causes us major problems. As a result, we
-   * have to optimize out those dead blocks early and never try to translate
-   * them to our AST.
-   */
-  // Reflective invocation causes unused warnings.
-  @SuppressWarnings("unused")
-  private static class JavaASTGenerationVisitor {
-
-    /**
-     * Used to cache {@link Method} lookups.
-     */
-    private static class MethodKey {
-      private final Class<? extends Object> childClass;
-      private final String name;
-
-      public MethodKey(String name, Class<? extends Object> childClass) {
-        this.name = name;
-        this.childClass = childClass;
-      }
-
-      @Override
-      public boolean equals(Object obj) {
-        if (obj instanceof MethodKey) {
-          MethodKey otherKey = (MethodKey) obj;
-          return name.equals(otherKey.name) && childClass.equals(otherKey.childClass);
-        }
-        return super.equals(obj);
-      }
-
-      @Override
-      public int hashCode() {
-        return name.hashCode() + (101 * childClass.hashCode());
-      }
-    }
-
-    /**
-     * Used to cache {@link Method} lookups.
-     */
-    private static class MethodValue {
-      private final NoSuchMethodException ex;
-      private final Method method;
-
-      public MethodValue(Method method) {
-        this.method = method;
-        this.ex = null;
-      }
-
-      public MethodValue(NoSuchMethodException ex) {
-        this.ex = ex;
-        this.method = null;
-      }
-
-      public Method getMethod() throws NoSuchMethodException {
-        if (this.ex != null) {
-          throw (ex);
-        }
-        return method;
-      }
-    }
-
-    /**
-     * The literal for the JLS identifier that represents the length field on an
-     * array.
-     */
-    private static final String ARRAY_LENGTH_FIELD = "length";
-
-    private static InternalCompilerException translateException(JNode node, Throwable e) {
-      if (e instanceof VirtualMachineError) {
-        // Always rethrow VM errors (an attempt to wrap may fail).
-        throw (VirtualMachineError) e;
-      }
-      InternalCompilerException ice;
-      if (e instanceof InternalCompilerException) {
-        ice = (InternalCompilerException) e;
-        ice.addNode(node);
-      } else {
-        ice = new InternalCompilerException(node, "Error constructing Java AST", e);
-      }
-      return ice;
-    }
-
-    private final AutoboxUtils autoboxUtils;
-
-    private JDeclaredType currentClass;
-
-    private ClassScope currentClassScope;
-
-    private String currentFileName;
-
-    private JMethod currentMethod;
-
-    private JMethodBody currentMethodBody;
-
-    private MethodScope currentMethodScope;
-
-    private Map<JField, JParameter> currentOuterThisRefParams;
-
-    private int[] currentSeparatorPositions;
-
-    private final boolean disableClassMetadata;
-
-    private final boolean enableAsserts;
-
-    private final Map<JsniMethodBody, AbstractMethodDeclaration> jsniMethodMap =
-        new HashMap<JsniMethodBody, AbstractMethodDeclaration>();
-
-    private final Map<JMethod, Map<String, JLabel>> labelMap =
-        new IdentityHashMap<JMethod, Map<String, JLabel>>();
-
-    private final Map<MethodKey, MethodValue> methodCache = new HashMap<MethodKey, MethodValue>();
-
-    private final JProgram program;
-
-    private final TypeMap typeMap;
-
-    public JavaASTGenerationVisitor(TypeMap typeMap, JProgram program, JJSOptions options) {
-      this.typeMap = typeMap;
-      this.program = program;
-      this.enableAsserts = options.isEnableAssertions();
-
-      /*
-       * TODO: Determine if this should be controlled by a compiler flag or a
-       * module property.
-       */
-      this.disableClassMetadata = options.isClassMetadataDisabled();
-      autoboxUtils = new AutoboxUtils(program);
-    }
-
-    /**
-     * <p>
-     * Add a bridge method to <code>clazzBinding</code> for any method it
-     * inherits that implements an interface method but that has a different
-     * erased signature from the interface method.
-     * </p>
-     * 
-     * <p>
-     * The need for these bridges was pointed out in issue 3064. The goal is
-     * that virtual method calls through an interface type are translated to
-     * JavaScript that will function correctly. If the interface signature
-     * matches the signature of the implementing method, then nothing special
-     * needs to be done. If they are different, due to the use of generics, then
-     * GenerateJavaScriptAST is careful to do the right thing. There is a
-     * remaining case, though, that GenerateJavaScriptAST is not in a good
-     * position to fix: a method could be inherited from a superclass, used to
-     * implement an interface method that has a different type signature, and
-     * does not have the interface method in its list of overrides. In that
-     * case, a bridge method should be added that overrides the interface method
-     * and then calls the implementation method.
-     * </p>
-     * 
-     * <p>
-     * This method should only be called once all regular, non-bridge methods
-     * have been installed on the GWT types.
-     * </p>
-     */
-    public void addBridgeMethods(SourceTypeBinding clazzBinding) {
-      if (clazzBinding.isInterface()) {
-        // Only add bridges in classes, to simplify matters.
-        return;
-      }
-
-      JClassType clazz = (JClassType) typeMap.get(clazzBinding);
-
-      /*
-       * The JDT adds bridge methods in all the places GWT needs them. Look
-       * through the bridge methods the JDT added.
-       */
-      if (clazzBinding.syntheticMethods() != null) {
-        for (SyntheticMethodBinding synthmeth : clazzBinding.syntheticMethods()) {
-          if (synthmeth.purpose == SyntheticMethodBinding.BridgeMethod && !synthmeth.isStatic()) {
-            JMethod implmeth = (JMethod) typeMap.get(synthmeth.targetMethod);
-
-            createBridgeMethod(clazz, synthmeth, implmeth);
-          }
-        }
-      }
-    }
-
-    public void processEnumType(JEnumType type) {
-      // Generate the synthetic values() method.
-      JField valuesField = null;
-      for (JMethod method : type.getMethods()) {
-        currentMethod = method;
-        if ("values".equals(method.getName())) {
-          if (method.getParams().size() != 0) {
-            continue;
-          }
-          currentMethodBody = (JMethodBody) method.getBody();
-          valuesField = writeEnumValuesMethod(type);
-        }
-        currentMethodBody = null;
-        currentMethod = null;
-      }
-      // Generate the synthetic valueOf() method.
-      if (isScript(program)) {
-        for (JMethod method : type.getMethods()) {
-          currentMethod = method;
-          if ("valueOf".equals(method.getName())) {
-            if (method.getParams().size() != 1) {
-              continue;
-            }
-            if (method.getParams().get(0).getType() != program.getTypeJavaLangString()) {
-              continue;
-            }
-            currentMethodBody = (JMethodBody) method.getBody();
-            writeEnumValueOfMethod(type, valuesField);
-          }
-          currentMethodBody = null;
-          currentMethod = null;
-        }
-      }
-    }
-
-    /**
-     * We emulate static initializers and instance initializers as methods. As
-     * in other cases, this gives us: simpler AST, easier to optimize, more like
-     * output JavaScript.
-     */
-    public void processType(TypeDeclaration x) {
-      currentClass = (JDeclaredType) typeMap.get(x.binding);
-      processArtificialRescues(x.annotations);
-      try {
-        currentClassScope = x.scope;
-        currentSeparatorPositions = x.compilationResult.lineSeparatorPositions;
-        currentFileName = String.valueOf(x.compilationResult.fileName);
-
-        /*
-         * Make clinits chain to super class (JDT doesn't write code to do
-         * this). Call super class $clinit; $clinit is always in position 0.
-         */
-        if (currentClass.getSuperClass() != null) {
-          JMethod myClinit = currentClass.getMethods().get(0);
-          JMethod superClinit = currentClass.getSuperClass().getMethods().get(0);
-          JMethodCall superClinitCall =
-              new JMethodCall(myClinit.getSourceInfo(), null, superClinit);
-          JMethodBody body = (JMethodBody) myClinit.getBody();
-          body.getBlock().addStmt(0, superClinitCall.makeStatement());
-        }
-
-        if (x.fields != null) {
-          // Process fields
-          for (int i = 0, n = x.fields.length; i < n; ++i) {
-            FieldDeclaration fieldDeclaration = x.fields[i];
-            if (fieldDeclaration.isStatic()) {
-              // clinit
-              currentMethod = currentClass.getMethods().get(0);
-              currentMethodBody = (JMethodBody) currentMethod.getBody();
-              currentMethodScope = x.staticInitializerScope;
-            } else {
-              // init
-              currentMethod = currentClass.getMethods().get(1);
-              currentMethodBody = (JMethodBody) currentMethod.getBody();
-              currentMethodScope = x.initializerScope;
-            }
-
-            if (fieldDeclaration instanceof Initializer) {
-              assert (currentClass instanceof JClassType);
-              processInitializer((Initializer) fieldDeclaration);
-            } else {
-              processField(fieldDeclaration);
-            }
-          }
-        }
-
-        currentMethodScope = null;
-        currentMethod = null;
-
-        if (x.methods != null) {
-          // Process methods
-          for (int i = 0, n = x.methods.length; i < n; ++i) {
-            if (x.methods[i].isConstructor()) {
-              assert (currentClass instanceof JClassType);
-              processConstructor((ConstructorDeclaration) x.methods[i]);
-            } else if (x.methods[i].isClinit()) {
-              // nothing to do
-            } else {
-              processMethod(x.methods[i]);
-            }
-          }
-        }
-
-        // Write the body of the getClass() override.
-        if (currentClass instanceof JClassType && currentClass != program.getTypeJavaLangObject()) {
-          JMethod method = currentClass.getMethods().get(2);
-          assert ("getClass".equals(method.getName()));
-
-          if (program.isJavaScriptObject(currentClass)
-              && currentClass != program.getJavaScriptObject()) {
-            // Just use JavaScriptObject's implementation for all subclasses.
-            currentClass.getMethods().remove(2);
-          } else {
-            if (currentClass == program.getIndexedType("Array")) {
-              /*
-              * Don't implement, fall through to Object.getClass(). Array emulation code
-              * in com.google.gwt.lang.Array invokes Array.getClass() and expects to get the
-              * class literal for the actual runtime type of the array (e.g. Foo[].class) and
-              * not Array.class.
-              */
-              currentClass.getMethods().remove(2);
-            } else {
-              tryFindUpRefs(method);
-              SourceInfo info = method.getSourceInfo();
-              implementMethod(method, new JClassLiteral(info.makeChild(), currentClass));
-            }
-          }
-        }
-
-        // Reimplement GWT.isClient(), GWT.isProdMode(), GWT.isScript().
-        if (currentClass == program.getIndexedType("GWT")) {
-          JMethod method = program.getIndexedMethod("GWT.isClient");
-          implementMethod(method, program.getLiteralBoolean(true));
-
-          method = program.getIndexedMethod("GWT.isProdMode");
-          implementMethod(method, program.getLiteralBoolean(true));
-
-          method = program.getIndexedMethod("GWT.isScript");
-          implementMethod(method, program.getLiteralBoolean(isScript(program)));
-        }
-
-        // Implement various methods on Class
-        if (currentClass == program.getTypeJavaLangClass()) {
-          JMethod method = program.getIndexedMethod("Class.desiredAssertionStatus");
-          implementMethod(method, program.getLiteralBoolean(enableAsserts));
-
-          if (disableClassMetadata) {
-            JMethod isMetadataEnabledMethod =
-                program.getIndexedMethod("Class.isClassMetadataEnabled");
-            implementMethod(isMetadataEnabledMethod, program.getLiteralBoolean(false));
-          }
-        }
-
-        if (currentClass instanceof JEnumType) {
-          processEnumType((JEnumType) currentClass);
-        }
-
-        currentClassScope = null;
-        currentClass = null;
-        currentSeparatorPositions = null;
-        currentFileName = null;
-      } catch (Throwable e) {
-        throw translateException(currentClass, e);
-      }
-    }
-
-    /**
-     * This is the guts of the "reflective" part of this visitor. Try to find a
-     * "process" method that exactly matches the run-time type of the argument.
-     */
-    protected JNode dispatch(String name, Object child) {
-      if (child == null) {
-        return null;
-      }
-
-      try {
-        Method method = getCachedMethod(name, child.getClass());
-        return (JNode) method.invoke(this, child);
-      } catch (Throwable e) {
-        if (e instanceof InvocationTargetException) {
-          e = ((InvocationTargetException) e).getTargetException();
-        }
-        throw translateException(child, e);
-      }
-    }
-
-    /**
-     * Process an Expression type node reflectively; must return a JExpression.
-     */
-    protected JExpression dispProcessExpression(Expression x) {
-      /*
-       * Note that we always prefer a JDT-computed constant value to the actual
-       * written expression. (Let's hope JDT is always right.) This means we
-       * don't have to write processExpression methods for the numerous JDT
-       * literal nodes because they ALWAYS have a constant value.
-       */
-      JExpression result = null;
-      if (x != null && x.constant != null && x.constant != Constant.NotAConstant) {
-        result = (JExpression) dispatch("processConstant", x.constant);
-      }
-
-      if (result == null) {
-        // The expression was not a constant, so use the general logic.
-        result = (JExpression) dispatch("processExpression", x);
-      }
-
-      // Check if we need to box the resulting expression.
-      if (x != null) {
-        if ((x.implicitConversion & TypeIds.BOXING) != 0) {
-          result = autoboxUtils.box(result, implicitConversionTargetType(x));
-        } else if ((x.implicitConversion & TypeIds.UNBOXING) != 0) {
-          // This code can actually leave an unbox operation in
-          // an lvalue position, for example ++(x.intValue()).
-          // Such trees are cleaned up in FixAssignmentToUnbox.
-          JType typeToUnbox = (JType) typeMap.get(x.resolvedType);
-          if (!(typeToUnbox instanceof JClassType)) {
-            throw new InternalCompilerException(result, "Attempt to unbox a non-class type: "
-                + typeToUnbox.getName(), null);
-          }
-
-          result = unbox(result, (JClassType) typeToUnbox);
-        }
-      }
-      return result;
-    }
-
-    /**
-     * Process an Statement type node reflectively; must return a JStatement.
-     */
-    protected JStatement dispProcessStatement(Statement x) {
-      JStatement stmt;
-      if (x instanceof Expression) {
-        JExpression expr = dispProcessExpression((Expression) x);
-        if (expr == null) {
-          return null;
-        }
-        stmt = expr.makeStatement();
-      } else {
-        stmt = (JStatement) dispatch("processStatement", x);
-      }
-      return stmt;
-    }
-
-    Map<JsniMethodBody, AbstractMethodDeclaration> getJsniMethodMap() {
-      return jsniMethodMap;
-    }
-
-    JBooleanLiteral processConstant(BooleanConstant x) {
-      return program.getLiteralBoolean(x.booleanValue());
-    }
-
-    JIntLiteral processConstant(ByteConstant x) {
-      return program.getLiteralInt(x.byteValue());
-    }
-
-    JCharLiteral processConstant(CharConstant x) {
-      return program.getLiteralChar(x.charValue());
-    }
-
-    JDoubleLiteral processConstant(DoubleConstant x) {
-      return program.getLiteralDouble(x.doubleValue());
-    }
-
-    JFloatLiteral processConstant(FloatConstant x) {
-      return program.getLiteralFloat(x.floatValue());
-    }
-
-    JIntLiteral processConstant(IntConstant x) {
-      return program.getLiteralInt(x.intValue());
-    }
-
-    JLongLiteral processConstant(LongConstant x) {
-      return program.getLiteralLong(x.longValue());
-    }
-
-    JIntLiteral processConstant(ShortConstant x) {
-      return program.getLiteralInt(x.shortValue());
-    }
-
-    JStringLiteral processConstant(StringConstant x) {
-      // May be processing an annotation
-      SourceInfo info =
-          currentMethod == null ? currentClass.getSourceInfo() : currentMethod.getSourceInfo();
-      return program.getLiteralString(info.makeChild(), x.stringValue().toCharArray());
-    }
-
-    /**
-     * This is slightly different from the normal Java language. Specifically,
-     * we explicitly handle synthetic fields that are part of nested/local
-     * classes. It boils down to the fact that we really HAVE to assign
-     * synthetic arguments to synthetic fields BEFORE calling the superclass
-     * constructor (because it might call you back polymorphically). In straight
-     * Java that glue code is a semantic error, because a this/super call must
-     * be the first statement of your constructor. On the upside, optimizations
-     * work the same on our synthetic fields as with any user fields.
-     * 
-     * The order of emulation is: - assign all synthetic fields from synthetic
-     * args - call our super constructor emulation method - call our instance
-     * initializer emulation method - run user code
-     */
-    void processConstructor(ConstructorDeclaration x) {
-      JConstructor ctor = (JConstructor) typeMap.get(x.binding);
-      try {
-        SourceInfo info = ctor.getSourceInfo();
-
-        currentMethod = ctor;
-        currentMethodBody = ctor.getBody();
-        currentMethodScope = x.scope;
-
-        /*
-         * Determine if we have an explicit this call. The presence of an
-         * explicit this call indicates we can skip certain initialization steps
-         * (as the callee will perform those steps for us). These skippable
-         * steps are 1) assigning synthetic args to fields and 2) running
-         * initializers.
-         */
-        boolean hasExplicitThis = (x.constructorCall != null) && !x.constructorCall.isSuperAccess();
-
-        JClassType enclosingType = ctor.getEnclosingType();
-        JBlock block = currentMethodBody.getBlock();
-        currentOuterThisRefParams = Maps.create();
-
-        /*
-         * All synthetic fields must be assigned, unless we have an explicit
-         * this constructor call, in which case the callee will assign them for
-         * us.
-         */
-        ReferenceBinding declaringClass = x.binding.declaringClass;
-        if (declaringClass instanceof NestedTypeBinding) {
-          Iterator<JParameter> paramIt = currentMethod.getParams().iterator();
-          NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
-          if (nestedBinding.enclosingInstances != null) {
-            for (SyntheticArgumentBinding arg : nestedBinding.enclosingInstances) {
-              JParameter param = paramIt.next();
-              JField field = (JField) typeMap.get(arg);
-              if (!hasExplicitThis) {
-                block.addStmt(JProgram.createAssignmentStmt(info, createVariableRef(info, field),
-                    createVariableRef(info, param)));
-              }
-              currentOuterThisRefParams = Maps.put(currentOuterThisRefParams, field, param);
-            }
-          }
-
-          if (!hasExplicitThis) {
-            paramIt = getSyntheticLocalsIterator();
-            if (nestedBinding.outerLocalVariables != null) {
-              for (SyntheticArgumentBinding arg : nestedBinding.outerLocalVariables) {
-                JParameter param = paramIt.next();
-                JField field = (JField) typeMap.get(arg);
-                block.addStmt(JProgram.createAssignmentStmt(info, createVariableRef(info, field),
-                    createVariableRef(info, param)));
-              }
-            }
-          }
-        }
-
-        // optional this or super constructor call
-        if (x.constructorCall != null) {
-          JMethodCall superOrThisCall =
-              (JMethodCall) dispatch("processExpression", x.constructorCall);
-          // Enums: wire up synthetic name/ordinal params to the super method.
-          if (enclosingType.isEnumOrSubclass() != null) {
-            JVariableRef enumNameRef =
-                createVariableRef(superOrThisCall.getSourceInfo(), ctor.getParams().get(0));
-            superOrThisCall.addArg(0, enumNameRef);
-            JVariableRef enumOrdinalRef =
-                createVariableRef(superOrThisCall.getSourceInfo(), ctor.getParams().get(1));
-            superOrThisCall.addArg(1, enumOrdinalRef);
-          }
-
-          superOrThisCall.setStaticDispatchOnly();
-          block.addStmt(superOrThisCall.makeStatement());
-        }
-
-        JExpression thisRef = createThisRef(info, enclosingType);
-
-        /*
-         * Call the synthetic instance initializer method, unless we have an
-         * explicit this constructor call, in which case the callee will.
-         */
-        if (!hasExplicitThis) {
-          // $init is always in position 1 (clinit is in 0)
-          JMethod initMethod = enclosingType.getMethods().get(1);
-          JMethodCall initCall = new JMethodCall(info, thisRef, initMethod);
-          block.addStmt(initCall.makeStatement());
-        }
-
-        // user code (finally!)
-        block.addStmts(processStatements(x.statements));
-
-        currentOuterThisRefParams = null;
-        currentMethodScope = null;
-        currentMethod = null;
-      } catch (Throwable e) {
-        throw translateException(ctor, e);
-      }
-    }
-
-    JExpression processExpression(AllocationExpression x) {
-      SourceInfo info = makeSourceInfo(x);
-      TypeBinding typeBinding = erasure(x.resolvedType);
-      if (typeBinding.constantPoolName() == null) {
-        /*
-         * Weird case: if JDT determines that this local class is totally
-         * uninstantiable, it won't bother allocating a local name.
-         */
-        return program.getLiteralNull();
-      }
-      JClassType newType = (JClassType) typeMap.get(typeBinding);
-      MethodBinding b = x.binding;
-      JConstructor ctor = (JConstructor) typeMap.get(b);
-      JMethodCall call;
-      JClassType javaLangString = program.getTypeJavaLangString();
-      if (newType == javaLangString && !newType.isExternal()) {
-        /*
-         * MAGIC: java.lang.String is implemented as a JavaScript String
-         * primitive with a modified prototype. This requires funky handling of
-         * constructor calls. We find a method named _String() whose signature
-         * matches the requested constructor
-         */
-        int ctorArgc = ctor.getParams().size();
-        JMethod targetMethod = null;
-        outer : for (JMethod method : javaLangString.getMethods()) {
-          if (method.getName().equals("_String") && method.getParams().size() == ctorArgc) {
-            for (int i = 0; i < ctorArgc; ++i) {
-              JParameter mparam = method.getParams().get(i);
-              JParameter cparam = ctor.getParams().get(i);
-              if (mparam.getType() != cparam.getType()) {
-                continue outer;
-              }
-            }
-            targetMethod = method;
-            break;
-          }
-        }
-        if (targetMethod == null) {
-          throw new InternalCompilerException(
-              "String constructor error; no matching implementation.");
-        }
-        call = new JMethodCall(makeSourceInfo(x), null, targetMethod);
-      } else {
-        call = new JNewInstance(info, ctor, currentClass);
-      }
-
-      // Enums: hidden arguments for the name and id.
-      if (x.enumConstant != null) {
-        call.addArgs(program.getLiteralString(info, x.enumConstant.name), program
-            .getLiteralInt(x.enumConstant.binding.original().id));
-      }
-
-      // Synthetic args for inner classes
-      ReferenceBinding targetBinding = b.declaringClass;
-      if (targetBinding.isNestedType() && !targetBinding.isStatic()) {
-        NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(targetBinding);
-        // Synthetic this args for inner classes
-        if (nestedBinding.enclosingInstances != null) {
-          for (SyntheticArgumentBinding arg : nestedBinding.enclosingInstances) {
-            JClassType syntheticThisType = (JClassType) typeMap.get(arg.type);
-            call.addArg(createThisRef(info, syntheticThisType));
-          }
-        }
-      }
-
-      // Plain old regular user arguments
-      addCallArgs(x.arguments, call, b);
-
-      // Synthetic args for inner classes
-      if (targetBinding.isNestedType() && !targetBinding.isStatic()) {
-        NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(targetBinding);
-        // Synthetic locals for local classes
-        if (nestedBinding.outerLocalVariables != null) {
-          for (SyntheticArgumentBinding arg : nestedBinding.outerLocalVariables) {
-            JVariable variable = (JVariable) typeMap.get(arg.actualOuterLocalVariable);
-            call.addArg(createVariableRef(info, variable, arg.actualOuterLocalVariable));
-          }
-        }
-      }
-
-      return call;
-    }
-
-    JExpression processExpression(AND_AND_Expression x) {
-      JType type = (JType) typeMap.get(x.resolvedType);
-      SourceInfo info = makeSourceInfo(x);
-      return processBinaryOperation(info, JBinaryOperator.AND, type, x.left, x.right);
-    }
-
-    JExpression processExpression(ArrayAllocationExpression x) {
-      SourceInfo info = makeSourceInfo(x);
-      JArrayType type = (JArrayType) typeMap.get(x.resolvedType);
-
-      if (x.initializer != null) {
-        List<JExpression> initializers = new ArrayList<JExpression>();
-        if (x.initializer.expressions != null) {
-          for (Expression expression : x.initializer.expressions) {
-            initializers.add(dispProcessExpression(expression));
-          }
-        }
-        return JNewArray.createInitializers(info, type, initializers);
-      } else {
-        List<JExpression> dims = new ArrayList<JExpression>();
-        for (Expression dimension : x.dimensions) {
-          // can be null if index expression was empty
-          if (dimension == null) {
-            dims.add(program.getLiteralAbsentArrayDimension());
-          } else {
-            dims.add(dispProcessExpression(dimension));
-          }
-        }
-        return JNewArray.createDims(info, type, dims);
-      }
-    }
-
-    JExpression processExpression(ArrayInitializer x) {
-      SourceInfo info = makeSourceInfo(x);
-      JArrayType type = (JArrayType) typeMap.get(x.resolvedType);
-
-      List<JExpression> initializers = new ArrayList<JExpression>();
-      if (x.expressions != null) {
-        for (Expression expression : x.expressions) {
-          initializers.add(dispProcessExpression(expression));
-        }
-      }
-      return JNewArray.createInitializers(info, type, initializers);
-    }
-
-    JExpression processExpression(ArrayReference x) {
-      SourceInfo info = makeSourceInfo(x);
-      JArrayRef arrayRef =
-          new JArrayRef(info, dispProcessExpression(x.receiver), dispProcessExpression(x.position));
-      return arrayRef;
-    }
-
-    JExpression processExpression(Assignment x) {
-      JType type = (JType) typeMap.get(x.resolvedType);
-      SourceInfo info = makeSourceInfo(x);
-      return processBinaryOperation(info, JBinaryOperator.ASG, type, x.lhs, x.expression);
-    }
-
-    JExpression processExpression(BinaryExpression x) {
-      JBinaryOperator op;
-
-      int binOp = (x.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
-      switch (binOp) {
-        case OperatorIds.LEFT_SHIFT:
-          op = JBinaryOperator.SHL;
-          break;
-        case OperatorIds.RIGHT_SHIFT:
-          op = JBinaryOperator.SHR;
-          break;
-        case OperatorIds.UNSIGNED_RIGHT_SHIFT:
-          op = JBinaryOperator.SHRU;
-          break;
-        case OperatorIds.PLUS:
-          if (program.isJavaLangString((JType) typeMap.get(x.resolvedType))) {
-            op = JBinaryOperator.CONCAT;
-          } else {
-            op = JBinaryOperator.ADD;
-          }
-          break;
-        case OperatorIds.MINUS:
-          op = JBinaryOperator.SUB;
-          break;
-        case OperatorIds.REMAINDER:
-          op = JBinaryOperator.MOD;
-          break;
-        case OperatorIds.XOR:
-          op = JBinaryOperator.BIT_XOR;
-          break;
-        case OperatorIds.AND:
-          op = JBinaryOperator.BIT_AND;
-          break;
-        case OperatorIds.MULTIPLY:
-          op = JBinaryOperator.MUL;
-          break;
-        case OperatorIds.OR:
-          op = JBinaryOperator.BIT_OR;
-          break;
-        case OperatorIds.DIVIDE:
-          op = JBinaryOperator.DIV;
-          break;
-        case OperatorIds.LESS_EQUAL:
-          op = JBinaryOperator.LTE;
-          break;
-        case OperatorIds.GREATER_EQUAL:
-          op = JBinaryOperator.GTE;
-          break;
-        case OperatorIds.GREATER:
-          op = JBinaryOperator.GT;
-          break;
-        case OperatorIds.LESS:
-          op = JBinaryOperator.LT;
-          break;
-        default:
-          throw new InternalCompilerException("Unexpected operator for BinaryExpression");
-      }
-
-      JType type = (JType) typeMap.get(x.resolvedType);
-      SourceInfo info = makeSourceInfo(x);
-      return processBinaryOperation(info, op, type, x.left, x.right);
-    }
-
-    JExpression processExpression(CastExpression x) {
-      SourceInfo info = makeSourceInfo(x);
-      JType type = (JType) typeMap.get(x.resolvedType);
-      JCastOperation cast = new JCastOperation(info, type, dispProcessExpression(x.expression));
-      return cast;
-    }
-
-    JExpression processExpression(ClassLiteralAccess x) {
-      SourceInfo info = makeSourceInfo(x);
-      JType type = (JType) typeMap.get(x.targetType);
-      return new JClassLiteral(info, type);
-    }
-
-    JExpression processExpression(CombinedBinaryExpression x) {
-      return processExpression((BinaryExpression) x);
-    }
-
-    JExpression processExpression(CompoundAssignment x) {
-      JBinaryOperator op;
-
-      switch (x.operator) {
-        case OperatorIds.PLUS:
-          if (program.isJavaLangString((JType) typeMap.get(x.resolvedType))) {
-            op = JBinaryOperator.ASG_CONCAT;
-          } else {
-            op = JBinaryOperator.ASG_ADD;
-          }
-          break;
-        case OperatorIds.MINUS:
-          op = JBinaryOperator.ASG_SUB;
-          break;
-        case OperatorIds.MULTIPLY:
-          op = JBinaryOperator.ASG_MUL;
-          break;
-        case OperatorIds.DIVIDE:
-          op = JBinaryOperator.ASG_DIV;
-          break;
-        case OperatorIds.AND:
-          op = JBinaryOperator.ASG_BIT_AND;
-          break;
-        case OperatorIds.OR:
-          op = JBinaryOperator.ASG_BIT_OR;
-          break;
-        case OperatorIds.XOR:
-          op = JBinaryOperator.ASG_BIT_XOR;
-          break;
-        case OperatorIds.REMAINDER:
-          op = JBinaryOperator.ASG_MOD;
-          break;
-        case OperatorIds.LEFT_SHIFT:
-          op = JBinaryOperator.ASG_SHL;
-          break;
-        case OperatorIds.RIGHT_SHIFT:
-          op = JBinaryOperator.ASG_SHR;
-          break;
-        case CompoundAssignment.UNSIGNED_RIGHT_SHIFT:
-          op = JBinaryOperator.ASG_SHRU;
-          break;
-        default:
-          throw new InternalCompilerException("Unexpected operator for CompoundAssignment");
-      }
-
-      JType type = (JType) typeMap.get(x.resolvedType);
-      SourceInfo info = makeSourceInfo(x);
-      return processBinaryOperation(info, op, type, x.lhs, x.expression);
-    }
-
-    JExpression processExpression(ConditionalExpression x) {
-      SourceInfo info = makeSourceInfo(x);
-      JType type = (JType) typeMap.get(x.resolvedType);
-      JExpression ifTest = dispProcessExpression(x.condition);
-      JExpression thenExpr = dispProcessExpression(x.valueIfTrue);
-      JExpression elseExpr = dispProcessExpression(x.valueIfFalse);
-      JConditional conditional = new JConditional(info, type, ifTest, thenExpr, elseExpr);
-      return conditional;
-    }
-
-    JExpression processExpression(EqualExpression x) {
-      JBinaryOperator op;
-      switch ((x.bits & BinaryExpression.OperatorMASK) >> BinaryExpression.OperatorSHIFT) {
-        case BinaryExpression.EQUAL_EQUAL:
-          op = JBinaryOperator.EQ;
-          break;
-        case BinaryExpression.NOT_EQUAL:
-          op = JBinaryOperator.NEQ;
-          break;
-        default:
-          throw new InternalCompilerException("Unexpected operator for EqualExpression");
-      }
-
-      JType type = (JType) typeMap.get(x.resolvedType);
-      SourceInfo info = makeSourceInfo(x);
-      return processBinaryOperation(info, op, type, x.left, x.right);
-    }
-
-    /**
-     * How we have to treat super calls vs. this calls is so different, they may
-     * as well have been two different JDT nodes.
-     */
-    JMethodCall processExpression(ExplicitConstructorCall x) {
-      if (x.isSuperAccess()) {
-        return processSuperConstructorCall(x);
-      } else {
-        return processThisConstructorCall(x);
-      }
-    }
-
-    JExpression processExpression(FieldReference x) {
-      FieldBinding fieldBinding = x.binding;
-      SourceInfo info = makeSourceInfo(x);
-      JExpression instance = dispProcessExpression(x.receiver);
-      JExpression expr;
-      if (fieldBinding.declaringClass == null) {
-        if (!ARRAY_LENGTH_FIELD.equals(String.valueOf(fieldBinding.name))) {
-          throw new InternalCompilerException("Expected [array].length.");
-        }
-        expr = new JArrayLength(info, instance);
-      } else {
-        JField field = (JField) typeMap.get(fieldBinding);
-        expr = new JFieldRef(info, instance, field, currentClass);
-      }
-
-      if (x.genericCast != null) {
-        JType castType = (JType) typeMap.get(x.genericCast);
-        /*
-         * Note, this may result in an invalid AST due to an LHS cast operation.
-         * We fix this up in FixAssignmentToUnbox.
-         */
-        return maybeCast(castType, expr);
-      }
-      return expr;
-    }
-
-    JExpression processExpression(InstanceOfExpression x) {
-      SourceInfo info = makeSourceInfo(x);
-      JExpression expr = dispProcessExpression(x.expression);
-      JReferenceType testType = (JReferenceType) typeMap.get(x.type.resolvedType);
-      return new JInstanceOf(info, testType, expr);
-    }
-
-    JExpression processExpression(MessageSend x) {
-      SourceInfo info = makeSourceInfo(x);
-      JMethod method = (JMethod) typeMap.get(x.binding);
-
-      JExpression qualifier;
-      if (x.receiver instanceof ThisReference) {
-        if (method.isStatic()) {
-          // don't bother qualifying it, it's a no-op
-          qualifier = null;
-        } else if (x.receiver instanceof QualifiedThisReference) {
-          // use the supplied qualifier
-          qualifier = dispProcessExpression(x.receiver);
-        } else {
-          /*
-           * In cases where JDT had to synthesize a this ref for us, it could
-           * actually be the wrong type, if the target method is in an enclosing
-           * class. We have to synthesize our own ref of the correct type.
-           */
-          qualifier = createThisRef(info, method.getEnclosingType());
-        }
-      } else {
-        qualifier = dispProcessExpression(x.receiver);
-      }
-
-      JMethodCall call = new JMethodCall(info, qualifier, method);
-
-      // On a super ref, don't allow polymorphic dispatch. Oddly enough,
-      // QualifiedSuperReference not derived from SuperReference!
-      boolean isSuperRef =
-          x.receiver instanceof SuperReference || x.receiver instanceof QualifiedSuperReference;
-      if (isSuperRef) {
-        call.setStaticDispatchOnly();
-      }
-
-      // The arguments come first...
-      addCallArgs(x.arguments, call, x.binding);
-
-      if (x.valueCast != null) {
-        JType castType = (JType) typeMap.get(x.valueCast);
-        return maybeCast(castType, call);
-      }
-      return call;
-    }
-
-    JExpression processExpression(NullLiteral x) {
-      return program.getLiteralNull();
-    }
-
-    JExpression processExpression(OR_OR_Expression x) {
-      JType type = (JType) typeMap.get(x.resolvedType);
-      SourceInfo info = makeSourceInfo(x);
-      return processBinaryOperation(info, JBinaryOperator.OR, type, x.left, x.right);
-    }
-
-    JExpression processExpression(PostfixExpression x) {
-      SourceInfo info = makeSourceInfo(x);
-      JUnaryOperator op;
-
-      switch (x.operator) {
-        case PostfixExpression.MINUS:
-          op = JUnaryOperator.DEC;
-          break;
-
-        case PostfixExpression.PLUS:
-          op = JUnaryOperator.INC;
-          break;
-
-        default:
-          throw new InternalCompilerException("Unexpected postfix operator");
-      }
-
-      JPostfixOperation postOp = new JPostfixOperation(info, op, dispProcessExpression(x.lhs));
-      return postOp;
-    }
-
-    JExpression processExpression(PrefixExpression x) {
-      SourceInfo info = makeSourceInfo(x);
-      JUnaryOperator op;
-
-      switch (x.operator) {
-        case PrefixExpression.MINUS:
-          op = JUnaryOperator.DEC;
-          break;
-
-        case PrefixExpression.PLUS:
-          op = JUnaryOperator.INC;
-          break;
-
-        default:
-          throw new InternalCompilerException("Unexpected prefix operator");
-      }
-
-      JPrefixOperation preOp = new JPrefixOperation(info, op, dispProcessExpression(x.lhs));
-      return preOp;
-    }
-
-    JExpression processExpression(QualifiedAllocationExpression x) {
-      /*
-       * Weird: sometimes JDT will create a QualifiedAllocationExpression with
-       * no qualifier. I guess this is supposed to let us know that we need to
-       * synthesize a synthetic this arg based on our own current "this"? But
-       * plain old regular AllocationExpression also must be treated as if it
-       * might be be implicitly qualified, so I'm not sure what the point is.
-       * Let's just defer to the AllocationExpression logic if there's no
-       * qualifier.
-       */
-      if (x.enclosingInstance() == null) {
-        return processExpression((AllocationExpression) x);
-      }
-
-      SourceInfo info = makeSourceInfo(x);
-      MethodBinding b = x.binding;
-      JConstructor ctor = (JConstructor) typeMap.get(b);
-      JNewInstance newInstance = new JNewInstance(info, ctor, currentClass);
-      JExpression qualifier = dispProcessExpression(x.enclosingInstance);
-      List<JExpression> qualList = new ArrayList<JExpression>();
-      qualList.add(qualifier);
-
-      /*
-       * Really weird: Sometimes an allocation expression needs both its
-       * explicit qualifier AND its implicit enclosing class! We add this second
-       * because the explicit qualifier takes precedence.
-       */
-      if (!currentMethod.isStatic()) {
-        JExpression implicitOuter = new JThisRef(info, (JClassType) currentClass);
-        qualList.add(implicitOuter);
-      }
-
-      // Synthetic this args for inner classes
-      ReferenceBinding targetBinding = b.declaringClass;
-      if (targetBinding.isNestedType() && !targetBinding.isStatic()) {
-        NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(targetBinding);
-        if (nestedBinding.enclosingInstances != null) {
-          for (SyntheticArgumentBinding arg : nestedBinding.enclosingInstances) {
-            JClassType syntheticThisType = (JClassType) typeMap.get(arg.type);
-            newInstance.addArg(createThisRef(syntheticThisType, qualList));
-          }
-        }
-      }
-
-      // Plain old regular arguments
-      addCallArgs(x.arguments, newInstance, b);
-
-      // Synthetic locals for local classes
-      if (targetBinding.isNestedType() && !targetBinding.isStatic()) {
-        NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(targetBinding);
-        if (nestedBinding.outerLocalVariables != null) {
-          for (SyntheticArgumentBinding arg : nestedBinding.outerLocalVariables) {
-            JVariable variable = (JVariable) typeMap.get(arg.actualOuterLocalVariable);
-            newInstance.addArg(createVariableRef(info, variable, arg.actualOuterLocalVariable));
-          }
-        }
-      }
-
-      return newInstance;
-    }
-
-    JExpression processExpression(QualifiedNameReference x) {
-      SourceInfo info = makeSourceInfo(x);
-      Binding binding = x.binding;
-      JNode node = typeMap.get(binding);
-      if (!(node instanceof JVariable)) {
-        return null;
-      }
-      JVariable variable = (JVariable) node;
-
-      JExpression curRef = createVariableRef(info, variable, binding);
-      if (x.genericCast != null) {
-        JType castType = (JType) typeMap.get(x.genericCast);
-        curRef = maybeCast(castType, curRef);
-      }
-
-      /*
-       * Wackiness: JDT represents multiple field access as an array of fields,
-       * each qualified by everything to the left. So each subsequent item in
-       * otherBindings takes the current expression as a qualifier.
-       */
-      if (x.otherBindings != null) {
-        for (int i = 0; i < x.otherBindings.length; ++i) {
-          FieldBinding fieldBinding = x.otherBindings[i];
-          if (fieldBinding.declaringClass == null) {
-            // probably array.length
-            if (!ARRAY_LENGTH_FIELD.equals(String.valueOf(fieldBinding.name))) {
-              throw new InternalCompilerException("Expected [array].length.");
-            }
-            curRef = new JArrayLength(info, curRef);
-          } else {
-            JField field = (JField) typeMap.get(fieldBinding);
-            curRef = new JFieldRef(info, curRef, field, currentClass);
-          }
-          if (x.otherGenericCasts != null && x.otherGenericCasts[i] != null) {
-            JType castType = (JType) typeMap.get(x.otherGenericCasts[i]);
-            curRef = maybeCast(castType, curRef);
-          }
-        }
-      }
-
-      return curRef;
-    }
-
-    JExpression processExpression(QualifiedSuperReference x) {
-      JClassType refType = (JClassType) typeMap.get(x.resolvedType);
-      JClassType qualType = (JClassType) typeMap.get(x.qualification.resolvedType);
-      assert (refType == qualType.getSuperClass());
-      // Oddly enough, super refs can be modeled as this refs, because whatever
-      // expression they qualify has already been resolved.
-      return processQualifiedThisOrSuperRef(x, qualType);
-    }
-
-    JExpression processExpression(QualifiedThisReference x) {
-      JClassType refType = (JClassType) typeMap.get(x.resolvedType);
-      JClassType qualType = (JClassType) typeMap.get(x.qualification.resolvedType);
-      assert (refType == qualType);
-      return processQualifiedThisOrSuperRef(x, qualType);
-    }
-
-    JExpression processExpression(SingleNameReference x) {
-      SourceInfo info = makeSourceInfo(x);
-      Binding binding = x.binding;
-      Object target = typeMap.get(binding);
-      if (!(target instanceof JVariable)) {
-        return null;
-      }
-      JVariable variable = (JVariable) target;
-
-      /*
-       * Wackiness: if a field happens to have synthetic accessors (only fields
-       * can have them, apparently), this is a ref to a field in an enclosing
-       * instance. CreateThisRef should compute a "this" access of the
-       * appropriate type, unless the field is static.
-       */
-      JExpression result = null;
-      if (x.syntheticAccessors != null) {
-        JField field = (JField) variable;
-        if (!field.isStatic()) {
-          JExpression instance = createThisRef(info, field.getEnclosingType());
-          result = new JFieldRef(info, instance, field, currentClass);
-        }
-      }
-      if (result == null) {
-        result = createVariableRef(info, variable, binding);
-      }
-      if (x.genericCast != null) {
-        JType castType = (JType) typeMap.get(x.genericCast);
-        result = maybeCast(castType, result);
-      }
-      return result;
-    }
-
-    JExpression processExpression(SuperReference x) {
-      JClassType type = (JClassType) typeMap.get(x.resolvedType);
-      assert (type == currentClass.getSuperClass());
-      SourceInfo info = makeSourceInfo(x);
-      // Oddly enough, super refs can be modeled as a this refs.
-      JExpression superRef = createThisRef(info, currentClass);
-      return superRef;
-    }
-
-    JExpression processExpression(ThisReference x) {
-      JClassType type = (JClassType) typeMap.get(x.resolvedType);
-      assert (type == currentClass);
-      SourceInfo info = makeSourceInfo(x);
-      JExpression thisRef = createThisRef(info, currentClass);
-      return thisRef;
-    }
-
-    JExpression processExpression(UnaryExpression x) {
-      SourceInfo info = makeSourceInfo(x);
-      JUnaryOperator op;
-      int operator = ((x.bits & UnaryExpression.OperatorMASK) >> UnaryExpression.OperatorSHIFT);
-
-      switch (operator) {
-        case UnaryExpression.MINUS:
-          op = JUnaryOperator.NEG;
-          break;
-
-        case UnaryExpression.NOT:
-          op = JUnaryOperator.NOT;
-          break;
-
-        case UnaryExpression.PLUS:
-          // Odd case.. a useless + operator; just return the operand
-          return dispProcessExpression(x.expression);
-
-        case UnaryExpression.TWIDDLE:
-          op = JUnaryOperator.BIT_NOT;
-          break;
-
-        default:
-          throw new InternalCompilerException("Unexpected operator for unary expression");
-      }
-
-      JPrefixOperation preOp = new JPrefixOperation(info, op, dispProcessExpression(x.expression));
-      return preOp;
-    }
-
-    List<JExpressionStatement> processExpressionStatements(Statement[] statements) {
-      List<JExpressionStatement> jstatements = new ArrayList<JExpressionStatement>();
-      if (statements != null) {
-        for (int i = 0, n = statements.length; i < n; ++i) {
-          JStatement jstmt = dispProcessStatement(statements[i]);
-          if (jstmt != null) {
-            jstatements.add((JExpressionStatement) jstmt);
-          }
-        }
-      }
-      return jstatements;
-    }
-
-    void processField(FieldDeclaration declaration) {
-      JField field = (JField) typeMap.tryGet(declaration.binding);
-      if (field == null) {
-        /*
-         * When anonymous classes declare constant fields, the field declaration
-         * is not visited by JDT. Just bail since any references to that field
-         * are guaranteed to be replaced with literals.
-         */
-        return;
-      }
-      try {
-        JExpression initializer = null;
-        if (declaration.initialization != null) {
-          initializer = dispProcessExpression(declaration.initialization);
-        }
-
-        if (field instanceof JEnumField) {
-          // An enum field must be initialized!
-          assert (initializer instanceof JMethodCall);
-        }
-
-        if (initializer != null) {
-          SourceInfo info = makeSourceInfo(declaration);
-          // JDeclarationStatement's ctor sets up the field's initializer.
-          JStatement decl =
-              new JDeclarationStatement(info, createVariableRef(info, field), initializer);
-          // will either be init or clinit
-          currentMethodBody.getBlock().addStmt(decl);
-        }
-      } catch (Throwable e) {
-        throw translateException(field, e);
-      }
-    }
-
-    void processInitializer(Initializer initializer) {
-      JBlock block = (JBlock) dispProcessStatement(initializer.block);
-      try {
-        // will either be init or clinit
-        currentMethodBody.getBlock().addStmt(block);
-      } catch (Throwable e) {
-        throw translateException(initializer, e);
-      }
-    }
-
-    void processMethod(AbstractMethodDeclaration x) {
-      MethodBinding b = x.binding;
-      JMethod method = (JMethod) typeMap.get(b);
-      try {
-        if (!b.isStatic() && (b.isImplementing() || b.isOverriding())) {
-          tryFindUpRefs(method, b);
-        }
-
-        if (x.isNative()) {
-          processNativeMethod(x, (JsniMethodBody) method.getBody());
-          return;
-        }
-
-        currentMethod = method;
-        currentMethodBody = (JMethodBody) method.getBody();
-        currentMethodScope = x.scope;
-
-        if (currentMethodBody != null) {
-          currentMethodBody.getBlock().addStmts(processStatements(x.statements));
-        }
-        currentMethodScope = null;
-        currentMethodBody = null;
-        currentMethod = null;
-      } catch (Throwable e) {
-        throw translateException(method, e);
-      }
-    }
-
-    void processNativeMethod(AbstractMethodDeclaration x, JsniMethodBody nativeMethodBody) {
-      // Squirrel away a reference to the JDT node to enable error reporting.
-      jsniMethodMap.put(nativeMethodBody, x);
-    }
-
-    JStatement processStatement(AssertStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-      JExpression expr = dispProcessExpression(x.assertExpression);
-      JExpression arg = dispProcessExpression(x.exceptionArgument);
-      return new JAssertStatement(info, expr, arg);
-    }
-
-    JBlock processStatement(Block x) {
-      if (x == null) {
-        return null;
-      }
-
-      SourceInfo info = makeSourceInfo(x);
-      JBlock block = new JBlock(info);
-      block.addStmts(processStatements(x.statements));
-      return block;
-    }
-
-    JStatement processStatement(BreakStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-      return new JBreakStatement(info, getOrCreateLabel(info, currentMethod, x.label));
-    }
-
-    JStatement processStatement(CaseStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-      JExpression expression = dispProcessExpression(x.constantExpression);
-      if (expression != null && x.constantExpression.resolvedType.isEnum()) {
-        // TODO: propagate enum information?
-        assert (expression instanceof JFieldRef);
-        JFieldRef fieldRef = (JFieldRef) expression;
-        JEnumField field = (JEnumField) fieldRef.getField();
-        return new JCaseStatement(info, program.getLiteralInt(field.ordinal()));
-      } else {
-        return new JCaseStatement(info, (JLiteral) expression);
-      }
-    }
-
-    JStatement processStatement(ContinueStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-      return new JContinueStatement(info, getOrCreateLabel(info, currentMethod, x.label));
-    }
-
-    JStatement processStatement(DoStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-      JExpression loopTest = dispProcessExpression(x.condition);
-      JStatement loopBody = dispProcessStatement(x.action);
-      JDoStatement stmt = new JDoStatement(info, loopTest, loopBody);
-      return stmt;
-    }
-
-    JStatement processStatement(EmptyStatement x) {
-      return null;
-    }
-
-    JStatement processStatement(ForeachStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-
-      JBlock body;
-      JStatement action = dispProcessStatement(x.action);
-      if (action instanceof JBlock) {
-        body = (JBlock) action;
-      } else {
-        body = new JBlock(info);
-        if (action != null) {
-          body.addStmt(action);
-        }
-      }
-
-      JLocal elementVar = (JLocal) typeMap.get(x.elementVariable.binding);
-      String elementVarName = elementVar.getName();
-
-      JDeclarationStatement elementDecl =
-          (JDeclarationStatement) processStatement(x.elementVariable);
-      assert (elementDecl.initializer == null);
-
-      JForStatement result;
-      if (x.collectionVariable != null) {
-        /**
-         * <pre>
-         * for (final T[] i$array = collection,
-         *          int i$index = 0,
-         *          final int i$max = i$array.length;
-         *      i$index < i$max; ++i$index) {
-         *   T elementVar = i$array[i$index];
-         *   // user action
-         * }
-         * </pre>
-         */
-        JLocal arrayVar =
-            JProgram.createLocal(info, elementVarName + "$array", ((JType) typeMap
-                .get(x.collection.resolvedType)), true, currentMethodBody);
-        JLocal indexVar =
-            JProgram.createLocal(info, elementVarName + "$index", program.getTypePrimitiveInt(),
-                false, currentMethodBody);
-        JLocal maxVar =
-            JProgram.createLocal(info, elementVarName + "$max", program.getTypePrimitiveInt(),
-                true, currentMethodBody);
-
-        List<JStatement> initializers = new ArrayList<JStatement>(3);
-        // T[] i$array = arr
-        initializers.add(createDeclaration(info, arrayVar, dispProcessExpression(x.collection)));
-        // int i$index = 0
-        initializers.add(createDeclaration(info, indexVar, program.getLiteralInt(0)));
-        // int i$max = i$array.length
-        initializers.add(createDeclaration(info, maxVar, new JArrayLength(info, new JLocalRef(info,
-            arrayVar))));
-
-        // i$index < i$max
-        JExpression condition =
-            new JBinaryOperation(info, program.getTypePrimitiveBoolean(), JBinaryOperator.LT,
-                createVariableRef(info, indexVar), createVariableRef(info, maxVar));
-
-        // ++i$index
-        List<JExpressionStatement> increments = new ArrayList<JExpressionStatement>(1);
-        increments.add(new JPrefixOperation(info, JUnaryOperator.INC, createVariableRef(info,
-            indexVar)).makeStatement());
-
-        // T elementVar = i$array[i$index];
-        elementDecl.initializer =
-            new JArrayRef(info, createVariableRef(info, arrayVar),
-                createVariableRef(info, indexVar));
-        body.addStmt(0, elementDecl);
-
-        result = new JForStatement(info, initializers, condition, increments, body);
-      } else {
-        /**
-         * <pre>
-         * for (Iterator<T> i$iterator = collection.iterator(); i$iterator.hasNext();) {
-         *   T elementVar = i$iterator.next();
-         *   // user action
-         * }
-         * </pre>
-         */
-        JLocal iteratorVar =
-            JProgram.createLocal(info, (elementVarName + "$iterator"), program
-                .getIndexedType("Iterator"), false, currentMethodBody);
-
-        List<JStatement> initializers = new ArrayList<JStatement>(1);
-        // Iterator<T> i$iterator = collection.iterator()
-        initializers.add(createDeclaration(info, iteratorVar, new JMethodCall(info,
-            dispProcessExpression(x.collection), program.getIndexedMethod("Iterable.iterator"))));
-
-        // i$iterator.hasNext()
-        JExpression condition =
-            new JMethodCall(info, createVariableRef(info, iteratorVar), program
-                .getIndexedMethod("Iterator.hasNext"));
-
-        // T elementVar = (T) i$iterator.next();
-        elementDecl.initializer =
-            new JMethodCall(info, createVariableRef(info, iteratorVar), program
-                .getIndexedMethod("Iterator.next"));
-
-        // Perform any implicit reference type casts (due to generics).
-        // Note this occurs before potential unboxing.
-        if (elementVar.getType() != program.getTypeJavaLangObject()) {
-          TypeBinding collectionType;
-          try {
-            // TODO: This is slow! Cache lookup.
-            Field privateField = ForeachStatement.class.getDeclaredField("collectionElementType");
-            privateField.setAccessible(true);
-            collectionType = (TypeBinding) privateField.get(x);
-          } catch (Exception e) {
-            throw new InternalCompilerException(elementDecl,
-                "Failed to retreive collectionElementType through reflection", e);
-          }
-          JType toType = (JType) typeMap.get(collectionType);
-          assert (toType instanceof JReferenceType);
-          elementDecl.initializer = maybeCast(toType, elementDecl.initializer);
-        }
-
-        body.addStmt(0, elementDecl);
-
-        result =
-            new JForStatement(info, initializers, condition, Collections
-                .<JExpressionStatement> emptyList(), body);
-      }
-
-      // May need to box or unbox the element assignment.
-      if (x.elementVariableImplicitWidening != -1) {
-        if ((x.elementVariableImplicitWidening & TypeIds.BOXING) != 0) {
-          /*
-           * Boxing is necessary. In this special case of autoboxing, the boxed
-           * expression cannot be a constant, so the box type must be exactly
-           * that associated with the expression.
-           */
-          elementDecl.initializer =
-              autoboxUtils.box(elementDecl.initializer, ((JPrimitiveType) elementDecl.initializer
-                  .getType()));
-        } else if ((x.elementVariableImplicitWidening & TypeIds.UNBOXING) != 0) {
-          elementDecl.initializer =
-              unbox(elementDecl.initializer, (JClassType) elementDecl.initializer.getType());
-        }
-      }
-      return result;
-    }
-
-    JStatement processStatement(ForStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-      // SEE NOTE ON JDT FORCED OPTIMIZATIONS
-      // If the condition is false, don't process the body
-      boolean removeBody = isOptimizedFalse(x.condition);
-
-      List<JStatement> init = processStatements(x.initializations);
-      JExpression expr = dispProcessExpression(x.condition);
-      List<JExpressionStatement> incr = processExpressionStatements(x.increments);
-      JStatement body = removeBody ? null : dispProcessStatement(x.action);
-      return new JForStatement(info, init, expr, incr, body);
-    }
-
-    JStatement processStatement(IfStatement x) {
-      // SEE NOTE ON JDT FORCED OPTIMIZATIONS
-      // If the condition is false, don't process the then statement
-      // If the condition is false, don't process the else statement
-      boolean removeThen = isOptimizedFalse(x.condition);
-      boolean removeElse = isOptimizedTrue(x.condition);
-
-      SourceInfo info = makeSourceInfo(x);
-      JExpression expr = dispProcessExpression(x.condition);
-      JStatement thenStmt = removeThen ? null : dispProcessStatement(x.thenStatement);
-      JStatement elseStmt = removeElse ? null : dispProcessStatement(x.elseStatement);
-      JIfStatement ifStmt = new JIfStatement(info, expr, thenStmt, elseStmt);
-      return ifStmt;
-    }
-
-    JStatement processStatement(LabeledStatement x) {
-      JStatement body = dispProcessStatement(x.statement);
-      if (body == null) {
-        return null;
-      }
-      SourceInfo info = makeSourceInfo(x);
-      return new JLabeledStatement(info, getOrCreateLabel(info, currentMethod, x.label), body);
-    }
-
-    JStatement processStatement(LocalDeclaration x) {
-      SourceInfo info = makeSourceInfo(x);
-      JLocal local = (JLocal) typeMap.get(x.binding);
-      JLocalRef localRef = new JLocalRef(info, local);
-      JExpression initializer = dispProcessExpression(x.initialization);
-      return new JDeclarationStatement(info, localRef, initializer);
-    }
-
-    JStatement processStatement(ReturnStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-      return new JReturnStatement(info, dispProcessExpression(x.expression));
-    }
-
-    JStatement processStatement(SwitchStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-      JExpression expression = dispProcessExpression(x.expression);
-      if (isEnumType(expression.getType())) {
-        // Must be an enum; synthesize a call to ordinal().
-        expression = new JMethodCall(info, expression, program.getIndexedMethod("Enum.ordinal"));
-      }
-      JBlock block = new JBlock(info);
-      // Don't use processStatements here, because it stops at control breaks
-      if (x.statements != null) {
-        for (Statement stmt : x.statements) {
-          JStatement jstmt = dispProcessStatement(stmt);
-          if (jstmt != null) {
-            block.addStmt(jstmt);
-          }
-        }
-      }
-      return new JSwitchStatement(info, expression, block);
-    }
-
-    JStatement processStatement(SynchronizedStatement x) {
-      JBlock block = (JBlock) dispProcessStatement(x.block);
-      JExpression expr = dispProcessExpression(x.expression);
-      block.addStmt(0, expr.makeStatement());
-      return block;
-    }
-
-    JStatement processStatement(ThrowStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-      JExpression toThrow = dispProcessExpression(x.exception);
-      return new JThrowStatement(info, toThrow);
-    }
-
-    JStatement processStatement(TryStatement x) {
-      SourceInfo info = makeSourceInfo(x);
-      JBlock tryBlock = (JBlock) dispProcessStatement(x.tryBlock);
-      List<JLocalRef> catchArgs = new ArrayList<JLocalRef>();
-      List<JBlock> catchBlocks = new ArrayList<JBlock>();
-      if (x.catchBlocks != null) {
-        for (int i = 0, c = x.catchArguments.length; i < c; ++i) {
-          JLocal local = (JLocal) typeMap.get(x.catchArguments[i].binding);
-          catchArgs.add((JLocalRef) createVariableRef(info, local));
-        }
-        for (int i = 0, c = x.catchBlocks.length; i < c; ++i) {
-          catchBlocks.add((JBlock) dispProcessStatement(x.catchBlocks[i]));
-        }
-      }
-      JBlock finallyBlock = (JBlock) dispProcessStatement(x.finallyBlock);
-      return new JTryStatement(info, tryBlock, catchArgs, catchBlocks, finallyBlock);
-    }
-
-    JStatement processStatement(TypeDeclaration x) {
-      // do nothing -- the local class is treated at the program level
-      return null;
-    }
-
-    JStatement processStatement(WhileStatement x) {
-      // SEE NOTE ON JDT FORCED OPTIMIZATIONS
-      // If the condition is false, don't process the body
-      boolean removeBody = isOptimizedFalse(x.condition);
-
-      SourceInfo info = makeSourceInfo(x);
-      JExpression loopTest = dispProcessExpression(x.condition);
-      JStatement loopBody = removeBody ? null : dispProcessStatement(x.action);
-      JWhileStatement stmt = new JWhileStatement(info, loopTest, loopBody);
-      return stmt;
-    }
-
-    List<JStatement> processStatements(Statement[] statements) {
-      List<JStatement> jstatements = new ArrayList<JStatement>();
-      if (statements != null) {
-        for (Statement stmt : statements) {
-          JStatement jstmt = dispProcessStatement(stmt);
-          if (jstmt != null) {
-            jstatements.add(jstmt);
-            if (jstmt.unconditionalControlBreak()) {
-              /*
-               * Stop processing statements, because the remaining ones are
-               * unreachable. The JDT compiler might not have fully fleshed out
-               * the unreachable statements.
-               */
-              break;
-            }
-          }
-        }
-      }
-
-      return jstatements;
-    }
-
-    JMethodCall processSuperConstructorCall(ExplicitConstructorCall x) {
-      SourceInfo info = makeSourceInfo(x);
-      JMethod ctor = (JMethod) typeMap.get(x.binding);
-      JExpression trueQualifier = createThisRef(info, currentClass);
-      JMethodCall call = new JMethodCall(info, trueQualifier, ctor);
-
-      // We have to find and pass through any synthetics our supertype needs
-      ReferenceBinding superClass = x.binding.declaringClass;
-      if (superClass.isNestedType() && !superClass.isStatic()) {
-        ReferenceBinding myBinding = currentClassScope.referenceType().binding;
-        ReferenceBinding superBinding = superClass;
-
-        // enclosing types
-        if (superBinding.syntheticEnclosingInstanceTypes() != null) {
-          JExpression qualifier = dispProcessExpression(x.qualification);
-          for (ReferenceBinding arg : superBinding.syntheticEnclosingInstanceTypes()) {
-            JClassType classType = (JClassType) typeMap.get(arg);
-            if (qualifier == null) {
-              /*
-               * Got to be one of my params; it would be illegal to use a this
-               * ref at this moment-- we would most likely be passing in a
-               * supertype field that HASN'T BEEN INITIALIZED YET.
-               * 
-               * Unfortunately, my params might not work as-is, so we have to
-               * check each one to see if any will make a suitable this ref.
-               */
-              List<JExpression> workList = new ArrayList<JExpression>();
-              Iterator<JParameter> paramIt = currentMethod.getParams().iterator();
-              for (ReferenceBinding b : myBinding.syntheticEnclosingInstanceTypes()) {
-                workList.add(createVariableRef(info, paramIt.next()));
-              }
-              call.addArg(createThisRef(classType, workList));
-            } else {
-              call.addArg(createThisRef(classType, qualifier));
-            }
-          }
-        }
-      }
-
-      addCallArgs(x.arguments, call, x.binding);
-
-      // We have to find and pass through any synthetics our supertype needs
-      if (superClass.isNestedType() && !superClass.isStatic()) {
-        ReferenceBinding superBinding = superClass;
-
-        // outer locals
-        if (superBinding.syntheticOuterLocalVariables() != null) {
-          for (SyntheticArgumentBinding arg : superBinding.syntheticOuterLocalVariables()) {
-            // Got to be one of my params
-            JType varType = (JType) typeMap.get(arg.type);
-            String varName = String.valueOf(arg.name);
-            JParameter param = null;
-            for (JParameter paramIt : currentMethod.getParams()) {
-              if (varType == paramIt.getType() && varName.equals(paramIt.getName())) {
-                param = paramIt;
-              }
-            }
-            if (param == null) {
-              throw new InternalCompilerException(
-                  "Could not find matching local arg for explicit super ctor call.");
-            }
-            call.addArg(createVariableRef(info, param));
-          }
-        }
-      }
-
-      return call;
-    }
-
-    JMethodCall processThisConstructorCall(ExplicitConstructorCall x) {
-      SourceInfo info = makeSourceInfo(x);
-      JMethod ctor = (JMethod) typeMap.get(x.binding);
-      JExpression trueQualifier = createThisRef(info, currentClass);
-      JMethodCall call = new JMethodCall(info, trueQualifier, ctor);
-
-      assert (x.qualification == null);
-
-      // All synthetic this args must be passed through to the target ctor
-      ReferenceBinding declaringClass = x.binding.declaringClass;
-      if (declaringClass.isNestedType() && !declaringClass.isStatic()) {
-        Iterator<JParameter> paramIt = currentMethod.getParams().iterator();
-        NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(declaringClass);
-        if (nestedBinding.enclosingInstances != null) {
-          for (SyntheticArgumentBinding unused : nestedBinding.enclosingInstances) {
-            call.addArg(createVariableRef(info, paramIt.next()));
-          }
-        }
-      }
-
-      addCallArgs(x.arguments, call, x.binding);
-
-      // All synthetic locals must be passed through to the target ctor
-      if (declaringClass.isNestedType() && !declaringClass.isStatic()) {
-        Iterator<JParameter> paramIt = getSyntheticLocalsIterator();
-        NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(declaringClass);
-        if (nestedBinding.outerLocalVariables != null) {
-          for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) {
-            call.addArg(createVariableRef(info, paramIt.next()));
-          }
-        }
-      }
-
-      return call;
-    }
-
-    private void addAllOuterThisRefs(List<? super JVariableRef> list, JExpression expr,
-        JClassType classType) {
-      for (JField field : classType.getFields()) {
-        // This fields are always first.
-        if (!field.isThisRef()) {
-          break;
-        }
-        // In a constructor, use the local param instead of the field.
-        JParameter param = null;
-        if (currentOuterThisRefParams != null && expr instanceof JThisRef) {
-          param = currentOuterThisRefParams.get(field);
-        }
-        if (param != null) {
-          list.add(new JParameterRef(expr.getSourceInfo(), param));
-        } else {
-          list.add(new JFieldRef(expr.getSourceInfo(), expr, field, currentClass));
-        }
-      }
-    }
-
-    private void addAllOuterThisRefsPlusSuperChain(List<? super JVariableRef> workList,
-        JExpression expr, JClassType classType) {
-      for (; classType != null; classType = classType.getSuperClass()) {
-        addAllOuterThisRefs(workList, expr, classType);
-      }
-    }
-
-    private void addCallArgs(Expression[] jdtArgs, JMethodCall call, MethodBinding binding) {
-      JExpression[] args = new JExpression[jdtArgs == null ? 0 : jdtArgs.length];
-      for (int i = 0; i < args.length; ++i) {
-        args[i] = dispProcessExpression(jdtArgs[i]);
-      }
-      if (!binding.isVarargs()) {
-        call.addArgs(args);
-        return;
-      }
-
-      // Handle the odd var-arg case.
-      TypeBinding[] params = binding.parameters;
-      int varArg = params.length - 1;
-
-      // Everything but the last arg.
-      for (int i = 0; i < varArg; ++i) {
-        call.addArg(args[i]);
-      }
-
-      // Handle the last arg.
-
-      // See if there's a single varArg which is already an array.
-      if (args.length == params.length) {
-        if (jdtArgs[varArg].resolvedType.isCompatibleWith(params[varArg])) {
-          // Already the correct array type.
-          call.addArg(args[varArg]);
-          return;
-        }
-      }
-
-      // Need to synthesize an appropriately-typed array.
-      List<JExpression> initializers = new ArrayList<JExpression>();
-      for (int i = varArg; i < args.length; ++i) {
-        initializers.add(args[i]);
-      }
-      JArrayType lastParamType = (JArrayType) typeMap.get(params[varArg]);
-      JNewArray newArray =
-          JNewArray.createInitializers(call.getSourceInfo(), lastParamType, initializers);
-      call.addArg(newArray);
-    }
-
-    private void addThrownExceptions(MethodBinding methodBinding, JMethod method) {
-      for (ReferenceBinding exceptionReference : methodBinding.thrownExceptions) {
-        method.addThrownException((JClassType) typeMap.get(exceptionReference.erasure()));
-      }
-    }
-
-    /**
-     * Create a bridge method. It calls a same-named method with the same
-     * arguments, but with a different type signature.
-     * 
-     * @param clazz The class to put the bridge method in
-     * @param jdtBridgeMethod The corresponding bridge method added in the JDT
-     * @param implmeth The implementation method to bridge to
-     */
-    private void createBridgeMethod(JClassType clazz, SyntheticMethodBinding jdtBridgeMethod,
-        JMethod implmeth) {
-      SourceInfo info = implmeth.getSourceInfo().makeChild();
-      // create the method itself
-      JMethod bridgeMethod =
-          program.createMethod(info, String.valueOf(jdtBridgeMethod.selector), clazz,
-              (JType) typeMap.get(jdtBridgeMethod.returnType.erasure()), false, false, implmeth
-                  .isFinal(), implmeth.getAccess(), false);
-      bridgeMethod.setSynthetic();
-      int paramIdx = 0;
-      List<JParameter> implParams = implmeth.getParams();
-      for (TypeBinding jdtParamType : jdtBridgeMethod.parameters) {
-        JParameter param = implParams.get(paramIdx++);
-        JType paramType = (JType) typeMap.get(jdtParamType.erasure());
-        JParameter newParam =
-            new JParameter(info.makeChild(param.getSourceInfo().getOrigin()), param.getName(),
-                paramType, true, false, bridgeMethod);
-        bridgeMethod.addParam(newParam);
-      }
-      addThrownExceptions(jdtBridgeMethod, bridgeMethod);
-      bridgeMethod.freezeParamTypes();
-      info.addCorrelation(info.getCorrelator().by(bridgeMethod));
-
-      // create a call
-      JMethodCall call = new JMethodCall(info, new JThisRef(info, clazz), implmeth);
-
-      for (int i = 0; i < bridgeMethod.getParams().size(); i++) {
-        JParameter param = bridgeMethod.getParams().get(i);
-        JParameterRef paramRef = new JParameterRef(info, param);
-        call.addArg(maybeCast(implParams.get(i).getType(), paramRef));
-      }
-
-      // wrap it in a return if necessary
-      JStatement callOrReturn;
-      if (bridgeMethod.getType() == program.getTypeVoid()) {
-        callOrReturn = call.makeStatement();
-      } else {
-        callOrReturn = new JReturnStatement(info, call);
-      }
-
-      // create a body that is just that call
-      JMethodBody body = (JMethodBody) bridgeMethod.getBody();
-      body.getBlock().addStmt(callOrReturn);
-
-      // Add overrides.
-      List<JMethod> overrides = new ArrayList<JMethod>();
-      tryFindUpRefs(bridgeMethod, overrides);
-      assert !overrides.isEmpty();
-      for (JMethod over : overrides) {
-        bridgeMethod.addOverride(over);
-        /*
-         * TODO(scottb): with a diamond-shape inheritance hierarchy, it may be
-         * possible to get dups in this way. Really, method.overrides should
-         * probably just be an IdentitySet to avoid having to check contains in
-         * various places. Left as a todo because I don't think dups is super
-         * harmful.
-         */
-        bridgeMethod.addOverrides(over.getOverrides());
-      }
-    }
-
-    private JDeclarationStatement createDeclaration(SourceInfo info, JLocal local, JExpression value) {
-      return new JDeclarationStatement(info, new JLocalRef(info, local), value);
-    }
-
-    /**
-     * Helper to create a qualified "this" ref (really a synthetic this field
-     * access) of the appropriate type. Always use this method instead of
-     * creating a naked JThisRef or you won't get the synthetic accesses right.
-     */
-    private JExpression createQualifiedThisRef(SourceInfo info, JClassType targetType) {
-      assert (currentClass instanceof JClassType);
-      JExpression expr = new JThisRef(info, ((JClassType) currentClass));
-      List<JExpression> list = new ArrayList<JExpression>();
-      addAllOuterThisRefsPlusSuperChain(list, expr, (JClassType) currentClass);
-      return createThisRef(targetType, list);
-    }
-
-    /**
-     * Helper to create an expression of the target type, possibly by accessing
-     * synthetic this fields on the passed-in expression. This is needed by a
-     * QualifiedAllocationExpression, because the qualifier may not be the
-     * correct type, and we may need use one of its fields.
-     */
-    private JExpression createThisRef(JReferenceType qualType, JExpression expr) {
-      List<JExpression> list = new ArrayList<JExpression>();
-      list.add(expr);
-      return createThisRef(qualType, list);
-    }
-
-    /**
-     * Helper to create an expression of the target type, possibly by accessing
-     * synthetic this fields on ANY of several passed-in expressions. Why in the
-     * world would we need to do this? It turns out that when making an
-     * unqualified explicit super constructor call to something that needs a
-     * synthetic outer this arg, the correct value to pass in can be one of
-     * several of the calling constructor's own synthetic args. The catch is,
-     * it's possible none of the args are exactly the right type-- we have to
-     * make one of them the right type by following each of their synthetic this
-     * refs up an arbitrarily big tree of enclosing classes and
-     * supertypes-with-enclosing-classes until we find something that's the
-     * right type.
-     * 
-     * We have this implemented as a Breadth-First Search to minimize the number
-     * of derefs required, and this seems to be correct. Note that we explicitly
-     * prefer the current expression as one of its supertypes over a synthetic
-     * this ref rooted off the current expression that happens to be the correct
-     * type. We have observed this to be consistent with how Java handles it.
-     * 
-     * TODO(scottb): could we get this info directly from JDT?
-     */
-    private JExpression createThisRef(JReferenceType qualType, List<JExpression> list) {
-      LinkedList<JExpression> workList = new LinkedList<JExpression>();
-      workList.addAll(list);
-      while (!workList.isEmpty()) {
-        JExpression expr = workList.removeFirst();
-        JClassType classType = (JClassType) ((JReferenceType) expr.getType()).getUnderlyingType();
-        for (; classType != null; classType = classType.getSuperClass()) {
-          // prefer myself or myself-as-supertype over any of my this$ fields
-          // that may have already been added to the work list
-          if (program.typeOracle.canTriviallyCast(classType, qualType)) {
-            return expr;
-          }
-          addAllOuterThisRefs(workList, expr, classType);
-        }
-      }
-
-      throw new InternalCompilerException("Cannot create a ThisRef of the appropriate type.");
-    }
-
-    /**
-     * Helper to creates this ref (or maybe a synthetic this field access) of
-     * the appropriate type. Always use this method instead of creating a naked
-     * JThisRef or you won't get the synthetic accesses right.
-     */
-    private JExpression createThisRef(SourceInfo info, JReferenceType targetType) {
-      assert (currentClass instanceof JClassType);
-      return createThisRef(targetType, new JThisRef(info, ((JClassType) currentClass)));
-    }
-
-    /**
-     * Creates an appropriate JVariableRef for the polymorphic type of the
-     * requested JVariable.
-     */
-    private JVariableRef createVariableRef(SourceInfo info, JVariable variable) {
-      if (variable instanceof JLocal) {
-        JLocal local = (JLocal) variable;
-        if (local.getEnclosingMethod() != currentMethod) {
-          throw new InternalCompilerException("LocalRef referencing local in a different method.");
-        }
-        return new JLocalRef(info, local);
-      } else if (variable instanceof JParameter) {
-        JParameter parameter = (JParameter) variable;
-        if (parameter.getEnclosingMethod() != currentMethod) {
-          throw new InternalCompilerException(
-              "ParameterRef referencing param in a different method.");
-        }
-        return new JParameterRef(info, parameter);
-      } else if (variable instanceof JField) {
-        JField field = (JField) variable;
-        JExpression instance = null;
-        if (!field.isStatic()) {
-          JClassType fieldEnclosingType = (JClassType) field.getEnclosingType();
-          instance = createThisRef(info, fieldEnclosingType);
-          if (!program.typeOracle.canTriviallyCast((JReferenceType) instance.getType(),
-              fieldEnclosingType)) {
-            throw new InternalCompilerException("FieldRef referencing field in a different type.");
-          }
-        }
-        return new JFieldRef(info, instance, field, currentClass);
-      }
-      throw new InternalCompilerException("Unknown JVariable subclass.");
-    }
-
-    /**
-     * Creates an appropriate JVariableRef for the polymorphic type of the
-     * requested JVariable.
-     */
-    private JVariableRef createVariableRef(SourceInfo info, JVariable variable, Binding binding) {
-      // Fix up the reference if it's to an outer local/param
-      variable = possiblyReferenceOuterLocal(variable, binding);
-      if (variable == null) {
-        /*
-         * Strange case: in certain circumstances, JDT will fail to provide an
-         * emulation path to an outer local variable. In the case I know of, the
-         * reference is a spurious qualifier to a static method call. Let's just
-         * return null and ditch the expression.
-         */
-        return null;
-      }
-      return createVariableRef(info, variable);
-    }
-
-    private TypeBinding erasure(TypeBinding typeBinding) {
-      if (typeBinding instanceof ParameterizedTypeBinding) {
-        typeBinding = typeBinding.erasure();
-      }
-      return typeBinding;
-    }
-
-    private Method getCachedMethod(String name, Class<? extends Object> childClass)
-        throws NoSuchMethodException {
-      MethodKey key = new MethodKey(name, childClass);
-      MethodValue value = methodCache.get(key);
-      if (value == null) {
-        try {
-          Method method = getClass().getDeclaredMethod(name, childClass);
-          value = new MethodValue(method);
-        } catch (NoSuchMethodException ex) {
-          value = new MethodValue(ex);
-        }
-        methodCache.put(key, value);
-      }
-      // Might throw an exception here.
-      return value.getMethod();
-    }
-
-    private JInterfaceType getOrCreateExternalType(SourceInfo info, char[][] compoundName) {
-      String name = BuildTypeMap.dotify(compoundName);
-      JInterfaceType external = (JInterfaceType) program.getFromTypeMap(name);
-      if (external == null) {
-        external = program.createInterface(info, name);
-        external.setExternal(true);
-      }
-      return external;
-    }
-
-    /**
-     * Get a new label of a particular name, or create a new one if it doesn't
-     * exist already.
-     */
-    private JLabel getOrCreateLabel(SourceInfo info, JMethod enclosingMethod, char[] name) {
-      if (name == null) {
-        return null;
-      }
-      String sname = String.valueOf(name);
-      Map<String, JLabel> lblMap = this.labelMap.get(enclosingMethod);
-      if (lblMap == null) {
-        lblMap = new HashMap<String, JLabel>();
-        this.labelMap.put(enclosingMethod, lblMap);
-      }
-      JLabel jlabel = lblMap.get(sname);
-      if (jlabel == null) {
-        jlabel = new JLabel(info, sname);
-        lblMap.put(sname, jlabel);
-      }
-      return jlabel;
-    }
-
-    private JPrimitiveType getPrimitiveTypeForWrapperType(JClassType wrapperType) {
-      String wrapperTypeName = wrapperType.getName();
-      if ("java.lang.Integer".equals(wrapperTypeName)) {
-        return program.getTypePrimitiveInt();
-      } else if ("java.lang.Boolean".equals(wrapperTypeName)) {
-        return program.getTypePrimitiveBoolean();
-      } else if ("java.lang.Character".equals(wrapperTypeName)) {
-        return program.getTypePrimitiveChar();
-      } else if ("java.lang.Long".equals(wrapperTypeName)) {
-        return program.getTypePrimitiveLong();
-      } else if ("java.lang.Short".equals(wrapperTypeName)) {
-        return program.getTypePrimitiveShort();
-      } else if ("java.lang.Byte".equals(wrapperTypeName)) {
-        return program.getTypePrimitiveByte();
-      } else if ("java.lang.Double".equals(wrapperTypeName)) {
-        return program.getTypePrimitiveDouble();
-      } else if ("java.lang.Float".equals(wrapperTypeName)) {
-        return program.getTypePrimitiveFloat();
-      } else {
-        return null;
-      }
-    }
-
-    /**
-     * Gets a JParameter iterator for a constructor method over its synthetic
-     * local parameters.
-     */
-    private Iterator<JParameter> getSyntheticLocalsIterator() {
-      return currentMethod.getParams().listIterator(currentMethod.getOriginalParamTypes().size());
-    }
-
-    private void implementMethod(JMethod method, JExpression returnValue) {
-      assert method != null;
-      JMethodBody body = (JMethodBody) method.getBody();
-      JBlock block = body.getBlock();
-
-      SourceInfo info;
-      if (block.getStatements().size() > 0) {
-        info = block.getStatements().get(0).getSourceInfo();
-      } else {
-        info = method.getSourceInfo();
-      }
-
-      block.clear();
-      block.addStmt(new JReturnStatement(info, returnValue));
-    }
-
-    /*
-     * Determine the destination type for an implicit conversion of the given
-     * expression. Beware that when autoboxing, the type of the expression is
-     * not necessarily the same as the type of the box to be created. The JDT
-     * figures out what the necessary conversion is, depending on the context
-     * the expression appears in, and stores it in
-     * <code>x.implicitConversion</code>, so extract it from there.
-     */
-    private JPrimitiveType implicitConversionTargetType(Expression x)
-        throws InternalCompilerException {
-      /*
-       * This algorithm for finding the target type is copied from
-       * org.eclipse.jdt
-       * .internal.compiler.codegen.CodeStream.generateReturnBytecode() .
-       */
-      switch ((x.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) {
-        case TypeIds.T_boolean:
-          return program.getTypePrimitiveBoolean();
-        case TypeIds.T_byte:
-          return program.getTypePrimitiveByte();
-        case TypeIds.T_char:
-          return program.getTypePrimitiveChar();
-        case TypeIds.T_double:
-          return program.getTypePrimitiveDouble();
-        case TypeIds.T_float:
-          return program.getTypePrimitiveFloat();
-        case TypeIds.T_int:
-          return program.getTypePrimitiveInt();
-        case TypeIds.T_long:
-          return program.getTypePrimitiveLong();
-        case TypeIds.T_short:
-          return program.getTypePrimitiveShort();
-        default:
-          throw new InternalCompilerException("Could not determine the desired box type");
-      }
-    }
-
-    /**
-     * Check whether the specified type is definitely for an enum class.
-     * 
-     * @param type The type being tested
-     * @return whether it is certainly an enum
-     */
-    private boolean isEnumType(JType type) {
-      if (type instanceof JClassType) {
-        return ((JClassType) type).isEnumOrSubclass() != null;
-      }
-
-      if (type instanceof JNonNullType) {
-        return isEnumType(((JNonNullType) type).getUnderlyingType());
-      }
-
-      return false;
-    }
-
-    private SourceInfo makeSourceInfo(Statement x) {
-      int startLine =
-          Util.getLineNumber(x.sourceStart, currentSeparatorPositions, 0,
-              currentSeparatorPositions.length - 1);
-      SourceOrigin toReturn =
-          SourceOrigin.create(x.sourceStart, x.sourceEnd, startLine, currentFileName);
-      if (currentMethod != null) {
-        return currentMethod.getSourceInfo().makeChild(toReturn);
-      }
-      return toReturn;
-    }
-
-    private JExpression maybeCast(JType expected, JExpression expression) {
-      if (expected != expression.getType()) {
-        // Must be a generic; insert a cast operation.
-        JReferenceType toType = (JReferenceType) expected;
-        return new JCastOperation(expression.getSourceInfo(), toType, expression);
-      } else {
-        return expression;
-      }
-    }
-
-    /**
-     * Sometimes a variable reference can be to a local or parameter in an an
-     * enclosing method. This is a tricky situation to detect. There's no
-     * obvious way to tell, but the clue we can get from JDT is that the local's
-     * containing method won't be the same as the method we're currently
-     * processing.
-     * 
-     * Once we have this clue, we can use getEmulationPath to compute the
-     * current class's binding for that field.
-     */
-    private JVariable possiblyReferenceOuterLocal(JVariable variable, Binding binding) {
-
-      if (variable instanceof JLocal || variable instanceof JParameter) {
-        LocalVariableBinding localBinding = (LocalVariableBinding) binding;
-        if (localBinding.declaringScope.methodScope() != currentMethodScope) {
-          variable = null;
-          VariableBinding[] vars = currentMethodScope.getEmulationPath(localBinding);
-          if (vars == null) {
-            return null;
-          }
-          assert (vars.length == 1);
-          VariableBinding varBinding = vars[0];
-
-          // See if there's an available parameter
-          if (varBinding instanceof SyntheticArgumentBinding) {
-            JType type = (JType) typeMap.get(varBinding.type);
-            String name = String.valueOf(varBinding.name);
-            for (int i = 0; i < currentMethod.getParams().size(); ++i) {
-              JParameter param = currentMethod.getParams().get(i);
-              if (type == param.getType() && name.equals(param.getName())) {
-                variable = param;
-                break;
-              }
-            }
-          }
-
-          // just use the field
-          if (variable == null) {
-            variable = (JField) typeMap.get(varBinding);
-          }
-
-          // now we have an updated variable that we can create our ref from
-        }
-      } else {
-        assert variable instanceof JField;
-        // In a constructor, prefer the ctor arg rather than the field.
-        if (currentOuterThisRefParams != null) {
-          JParameter ctorArg = currentOuterThisRefParams.get(variable);
-          if (ctorArg != null) {
-            variable = ctorArg;
-          }
-        }
-      }
-      return variable;
-    }
-
-    /**
-     * Process a {@link ArtificialRescue.Rescue} element.
-     */
-    private void processArtificialRescue(RescueData rescue) {
-      JReferenceType classType = (JReferenceType) program.getTypeFromJsniRef(rescue.getClassName());
-      assert classType != null;
-      if (rescue.isInstantiable()) {
-        currentClass.addArtificialRescue(classType);
-      }
-
-      if (classType instanceof JDeclaredType) {
-        List<String> toRescue = new ArrayList<String>();
-        Collections.addAll(toRescue, rescue.getFields());
-        Collections.addAll(toRescue, rescue.getMethods());
-
-        for (String name : toRescue) {
-          JsniRef ref = JsniRef.parse("@" + classType.getName() + "::" + name);
-          final String[] errors = {null};
-          JNode node =
-              JsniRefLookup.findJsniRefTarget(ref, program, new JsniRefLookup.ErrorReporter() {
-                public void reportError(String error) {
-                  errors[0] = error;
-                }
-              });
-          if (errors[0] != null) {
-            // Should have been caught by ArtificialRescueChecker
-            throw new InternalCompilerException("Unable to artificially rescue " + name + ": "
-                + errors[0]);
-          }
-
-          if (node instanceof JType) {
-            // Already added the type above.
-          } else {
-            currentClass.addArtificialRescue(node);
-          }
-          if (node instanceof JField) {
-            JField field = (JField) node;
-            if (!field.isFinal()) {
-              field.setVolatile();
-            }
-          }
-        }
-      }
-    }
-
-    private void processArtificialRescues(Annotation[] annotations) {
-      if (annotations == null) {
-        return;
-      }
-      RescueData[] rescues = RescueData.createFromAnnotations(annotations);
-      for (RescueData rescue : rescues) {
-        processArtificialRescue(rescue);
-      }
-    }
-
-    /**
-     * Helper for creating all JBinaryOperation. Several different JDT nodes can
-     * result in binary operations: AND_AND_Expression, Assignment,
-     * BinaryExpresion, CompoundAssignment, EqualExpression, and
-     * OR_OR_Expression. Hopefully the specific operators that can result in
-     * each different JDT type won't change between releases, because we only
-     * look for the specific operators that we think should match each JDT node,
-     * and throw an error if there's a mismatch.
-     */
-    private JExpression processBinaryOperation(SourceInfo info, JBinaryOperator op, JType type,
-        Expression arg1, Expression arg2) {
-      JExpression exprArg1 = dispProcessExpression(arg1);
-      JExpression exprArg2 = dispProcessExpression(arg2);
-      JBinaryOperation binaryOperation = new JBinaryOperation(info, type, op, exprArg1, exprArg2);
-      return binaryOperation;
-    }
-
-    private JExpression processQualifiedThisOrSuperRef(QualifiedThisReference x, JClassType qualType) {
-      /*
-       * WEIRD: If a thisref or superref is qualified with the EXACT type of the
-       * innermost type (in other words, a needless qualifier), it must refer to
-       * that innermost type, because a class can never be nested inside of
-       * itself. In this case, we must treat it as if it were not qualified.
-       * 
-       * In all other cases, the qualified thisref or superref cannot possibly
-       * refer to the innermost type (even if the innermost type could be cast
-       * to a compatible type), so we must create a reference to some outer
-       * type.
-       */
-      SourceInfo info = makeSourceInfo(x);
-      if (qualType == currentClass) {
-        return createThisRef(info, qualType);
-      } else {
-        return createQualifiedThisRef(info, qualType);
-      }
-    }
-
-    private InternalCompilerException translateException(Object node, Throwable e) {
-      if (e instanceof VirtualMachineError) {
-        // Always rethrow VM errors (an attempt to wrap may fail).
-        throw (VirtualMachineError) e;
-      }
-      InternalCompilerException ice;
-      if (e instanceof InternalCompilerException) {
-        ice = (InternalCompilerException) e;
-      } else {
-        ice = new InternalCompilerException("Error constructing Java AST", e);
-      }
-      String className = node.getClass().getName();
-      String description = node.toString();
-      SourceInfo sourceInfo = null;
-      if (node instanceof Statement) {
-        sourceInfo = makeSourceInfo((Statement) node);
-      }
-      ice.addNode(className, description, sourceInfo);
-      return ice;
-    }
-
-    /**
-     * For a given method, try to find all methods that it overrides/implements.
-     * This version does not use JDT.
-     */
-    private void tryFindUpRefs(JMethod method) {
-      List<JMethod> overrides = new ArrayList<JMethod>();
-      tryFindUpRefs(method, overrides);
-      method.addOverrides(overrides);
-    }
-
-    private void tryFindUpRefs(JMethod method, List<JMethod> overrides) {
-      if (method.getEnclosingType() != null) {
-        tryFindUpRefsRecursive(method, method.getEnclosingType(), overrides);
-      }
-    }
-
-    /**
-     * For a given method(and method binding), try to find all methods that it
-     * overrides/implements.
-     */
-    private void tryFindUpRefs(JMethod method, MethodBinding binding) {
-      // Should never get a parameterized instance here.
-      assert binding == binding.original();
-      tryFindUpRefsRecursive(method, binding, binding.declaringClass);
-    }
-
-    /**
-     * For a given method(and method binding), recursively try to find all
-     * methods that it overrides/implements.
-     */
-    private void tryFindUpRefsRecursive(JMethod method, JDeclaredType searchThisType,
-        List<JMethod> overrides) {
-
-      // See if this class has any uprefs, unless this class is myself
-      if (method.getEnclosingType() != searchThisType) {
-        for (JMethod upRef : searchThisType.getMethods()) {
-          if (JTypeOracle.methodsDoMatch(method, upRef) && !overrides.contains(upRef)) {
-            overrides.add(upRef);
-            break;
-          }
-        }
-      }
-
-      // recurse super class
-      if (searchThisType.getSuperClass() != null) {
-        tryFindUpRefsRecursive(method, searchThisType.getSuperClass(), overrides);
-      }
-
-      // recurse super interfaces
-      for (JInterfaceType intf : searchThisType.getImplements()) {
-        tryFindUpRefsRecursive(method, intf, overrides);
-      }
-    }
-
-    /**
-     * For a given method(and method binding), recursively try to find all
-     * methods that it overrides/implements.
-     */
-    private void tryFindUpRefsRecursive(JMethod method, MethodBinding binding,
-        ReferenceBinding searchThisType) {
-      /*
-       * Always look for uprefs in the original, so we can correctly compare
-       * erased signatures. The general design for uprefs is to model what the
-       * JVM does in terms of matching up overrides based on binary match.
-       */
-      searchThisType = (ReferenceBinding) searchThisType.original();
-
-      // See if this class has any uprefs, unless this class is myself
-      if (binding.declaringClass != searchThisType) {
-        for (MethodBinding tryMethod : searchThisType.getMethods(binding.selector)) {
-          if (binding.returnType.erasure() == tryMethod.returnType.erasure()
-              && binding.areParameterErasuresEqual(tryMethod)) {
-            JMethod upRef = (JMethod) typeMap.get(tryMethod);
-            if (!method.getOverrides().contains(upRef)) {
-              method.addOverride(upRef);
-              break;
-            }
-          }
-        }
-      }
-
-      // recurse super class
-      if (searchThisType.superclass() != null) {
-        tryFindUpRefsRecursive(method, binding, searchThisType.superclass());
-      }
-
-      // recurse super interfaces
-      if (searchThisType.superInterfaces() != null) {
-        for (int i = 0; i < searchThisType.superInterfaces().length; i++) {
-          ReferenceBinding intf = searchThisType.superInterfaces()[i];
-          tryFindUpRefsRecursive(method, binding, intf);
-        }
-      }
-    }
-
-    private JExpression unbox(JExpression toUnbox, JClassType wrapperType) {
-      JPrimitiveType primitiveType = getPrimitiveTypeForWrapperType(wrapperType);
-      if (primitiveType == null) {
-        throw new InternalCompilerException(toUnbox, "Attempt to unbox unexpected type '"
-            + wrapperType.getName() + "'", null);
-      }
-
-      String valueMethodName = primitiveType.getName() + "Value";
-      JMethod valueMethod = null;
-      for (Object element : wrapperType.getMethods()) {
-        JMethod method = (JMethod) element;
-        if (method.getName().equals(valueMethodName)) {
-          if (method.getParams().isEmpty()) {
-            // It's a match!
-            valueMethod = method;
-            break;
-          }
-        }
-      }
-
-      if (valueMethod == null) {
-        throw new InternalCompilerException(toUnbox, "Expected to find a method on '"
-            + wrapperType.getName() + "' whose signature matches 'public "
-            + primitiveType.getName() + " " + valueMethodName + "()'", null);
-      }
-
-      JMethodCall unboxCall = new JMethodCall(toUnbox.getSourceInfo(), toUnbox, valueMethod);
-      return unboxCall;
-    }
-
-    private void writeEnumValueOfMethod(JEnumType type, JField valuesField) {
-      JField mapField;
-      {
-        /*
-         * Make an inner class to hold a lazy-init name-value map. We use a
-         * class to take advantage of its clinit.
-         * 
-         * class Map { $MAP = Enum.createValueOfMap($VALUES); }
-         */
-        SourceInfo typeInfo = type.getSourceInfo().makeChild();
-        JClassType mapClass = program.createClass(typeInfo, type.getName() + "$Map", false, true);
-        typeInfo.addCorrelation(typeInfo.getCorrelator().by(mapClass));
-        mapClass.setSuperClass(program.getTypeJavaLangObject());
-        SourceInfo fieldInfo = typeInfo.makeChild();
-        mapField =
-            program.createField(fieldInfo, "$MAP", mapClass, program.getJavaScriptObject(), true,
-                Disposition.FINAL);
-        fieldInfo.addCorrelation(fieldInfo.getCorrelator().by(mapField));
-
-        SourceInfo methodInfo = typeInfo.makeChild();
-        JMethodCall call =
-            new JMethodCall(methodInfo, null, program.getIndexedMethod("Enum.createValueOfMap"));
-        call.addArg(new JFieldRef(methodInfo, null, valuesField, type));
-        JFieldRef mapRef = new JFieldRef(methodInfo, null, mapField, type);
-        JDeclarationStatement declStmt = new JDeclarationStatement(methodInfo, mapRef, call);
-        JMethod clinit =
-            program.createMethod(methodInfo, "$clinit", mapClass, program.getTypeVoid(), false,
-                true, true, AccessModifier.PRIVATE, false);
-        clinit.freezeParamTypes();
-        methodInfo.addCorrelation(methodInfo.getCorrelator().by(clinit));
-        JBlock clinitBlock = ((JMethodBody) clinit.getBody()).getBlock();
-        clinitBlock.addStmt(declStmt);
-        mapField.setInitializer(declStmt);
-      }
-
-      /*
-       * return Enum.valueOf(Enum$Map.Map.$MAP, name);
-       */
-      {
-        SourceInfo sourceInfo = currentMethodBody.getSourceInfo();
-        JFieldRef mapRef = new JFieldRef(sourceInfo, null, mapField, type);
-        JVariableRef nameRef = createVariableRef(sourceInfo, currentMethod.getParams().get(0));
-        JMethod delegateTo = program.getIndexedMethod("Enum.valueOf");
-        JMethodCall call = new JMethodCall(sourceInfo, null, delegateTo);
-        call.addArgs(mapRef, nameRef);
-
-        currentMethodBody.getBlock().addStmt(new JReturnStatement(sourceInfo, call));
-      }
-    }
-
-    private JField writeEnumValuesMethod(JEnumType type) {
-      JField valuesField;
-      {
-        // $VALUES = new E[]{A,B,B};
-        SourceInfo fieldInfo = type.getSourceInfo().makeChild();
-        JArrayType enumArrayType = program.getTypeArray(type);
-        valuesField =
-            program.createField(fieldInfo, "$VALUES", type, enumArrayType, true, Disposition.FINAL);
-        fieldInfo.addCorrelation(fieldInfo.getCorrelator().by(valuesField));
-        List<JExpression> initializers = new ArrayList<JExpression>();
-        for (JEnumField field : type.getEnumList()) {
-          JFieldRef fieldRef = new JFieldRef(fieldInfo, null, field, type);
-          initializers.add(fieldRef);
-        }
-        JNewArray newExpr = JNewArray.createInitializers(fieldInfo, enumArrayType, initializers);
-        JFieldRef valuesRef = new JFieldRef(fieldInfo, null, valuesField, type);
-        JDeclarationStatement declStmt = new JDeclarationStatement(fieldInfo, valuesRef, newExpr);
-        JBlock clinitBlock = ((JMethodBody) type.getMethods().get(0).getBody()).getBlock();
-
-        /*
-         * HACKY: the $VALUES array must be initialized immediately after all of
-         * the enum fields, but before any user initialization (which might rely
-         * on $VALUES). The "1 + " is the statement containing the call to
-         * Enum.$clinit().
-         */
-        int insertionPoint = 1 + initializers.size();
-        assert clinitBlock.getStatements().size() >= initializers.size() + 1;
-        clinitBlock.addStmt(insertionPoint, declStmt);
-        valuesField.setInitializer(declStmt);
-      }
-      {
-        // return $VALUES;
-        SourceInfo sourceInfo = currentMethod.getSourceInfo();
-        JFieldRef valuesRef = new JFieldRef(sourceInfo, null, valuesField, type);
-        currentMethodBody.getBlock().addStmt(new JReturnStatement(sourceInfo, valuesRef));
-      }
-      return valuesField;
-    }
-  }
-
-  /**
-   * Resolve JSNI refs; replace with compile-time constants where appropriate.
-   */
-  private static class JsniRefGenerationVisitor extends JModVisitor {
-
-    private class JsniRefResolver extends JsModVisitor {
-      private final AbstractMethodDeclaration methodDecl;
-      private final JsniMethodBody nativeMethodBody;
-
-      private JsniRefResolver(AbstractMethodDeclaration methodDecl, JsniMethodBody nativeMethodBody) {
-        this.methodDecl = methodDecl;
-        this.nativeMethodBody = nativeMethodBody;
-      }
-
-      @Override
-      public void endVisit(JsNameRef x, JsContext ctx) {
-        String ident = x.getIdent();
-        if (ident.charAt(0) == '@') {
-          processNameRef(x, ctx);
-        }
-      }
-
-      private JNode findJsniRefTarget(final SourceInfo info, String ident) {
-        JsniRef parsed = JsniRef.parse(ident);
-        if (parsed == null) {
-          JsniCollector.reportJsniError(info, methodDecl, "Badly formatted native reference '"
-              + ident + "'");
-          return null;
-        }
-
-        JProgram prog = program;
-
-        return JsniRefLookup.findJsniRefTarget(parsed, prog, new JsniRefLookup.ErrorReporter() {
-          public void reportError(String error) {
-            JsniCollector.reportJsniError(info, methodDecl, error);
-          }
-        });
-      }
-
-      private void processClassLiteral(JsNameRef nameRef, SourceInfo info, JType type, JsContext ctx) {
-        assert !ctx.isLvalue();
-        JsniClassLiteral classLiteral = new JsniClassLiteral(info, nameRef.getIdent(), type);
-        nativeMethodBody.addClassRef(classLiteral);
-      }
-
-      private void processField(JsNameRef nameRef, SourceInfo info, JField field, JsContext ctx) {
-        /*
-         * We must replace any compile-time constants with the constant value of
-         * the field.
-         */
-        if (field.isCompileTimeConstant()) {
-          assert !ctx.isLvalue();
-          JLiteral initializer = field.getConstInitializer();
-          JType type = initializer.getType();
-          if (type instanceof JPrimitiveType || program.isJavaLangString(type)) {
-            GenerateJavaScriptLiterals generator = new GenerateJavaScriptLiterals();
-            generator.accept(initializer);
-            JsExpression result = generator.peek();
-            assert (result != null);
-            ctx.replaceMe(result);
-            return;
-          }
-        }
-
-        // Normal: create a jsniRef.
-        JsniFieldRef fieldRef =
-            new JsniFieldRef(info, nameRef.getIdent(), field, currentClass, ctx.isLvalue());
-        nativeMethodBody.addJsniRef(fieldRef);
-      }
-
-      private void processMethod(JsNameRef nameRef, SourceInfo info, JMethod method, JsContext ctx) {
-        assert !ctx.isLvalue();
-        JsniMethodRef methodRef =
-            new JsniMethodRef(info, nameRef.getIdent(), method, program.getJavaScriptObject());
-        nativeMethodBody.addJsniRef(methodRef);
-      }
-
-      private void processNameRef(JsNameRef nameRef, JsContext ctx) {
-        SourceInfo info = nativeMethodBody.getSourceInfo();
-        // TODO: make this tighter when we have real source info
-        // JSourceInfo info = translateInfo(nameRef.getInfo());
-        String ident = nameRef.getIdent();
-        JNode node = jsniMap.get(ident);
-        if (node == null) {
-          node = findJsniRefTarget(info, ident);
-          if (node == null) {
-            return; // already reported error
-          }
-          jsniMap.put(ident, node);
-        }
-
-        if (node instanceof JField) {
-          processField(nameRef, info, (JField) node, ctx);
-        } else if (node instanceof JMethod) {
-          processMethod(nameRef, info, (JMethod) node, ctx);
-        } else if (node instanceof JType) {
-          processClassLiteral(nameRef, info, (JType) node, ctx);
-        } else {
-          throw new InternalCompilerException(node,
-              "JSNI reference to something other than a class, field, or method?", null);
-        }
-      }
-    }
-
-    private JDeclaredType currentClass;
-
-    private final Map<String, JNode> jsniMap = new HashMap<String, JNode>();
-
-    private final Map<JsniMethodBody, AbstractMethodDeclaration> jsniMethodMap;
-
-    private final JProgram program;
-
-    public JsniRefGenerationVisitor(JProgram program,
-        Map<JsniMethodBody, AbstractMethodDeclaration> jsniMethodMap) {
-      this.program = program;
-      this.jsniMethodMap = jsniMethodMap;
-    }
-
-    @Override
-    public void endVisit(JClassType x, Context ctx) {
-      currentClass = null;
-    }
-
-    @Override
-    public void endVisit(JsniMethodBody x, Context ctx) {
-      new JsniRefResolver(jsniMethodMap.get(x), x).accept(x.getFunc());
-    }
-
-    @Override
-    public boolean visit(JClassType x, Context ctx) {
-      currentClass = x;
-      return true;
-    }
-
-    @Override
-    public boolean visit(JMethodBody x, Context ctx) {
-      return false;
-    }
-  }
-
-  /**
-   * Combines the information from the JDT type nodes and the type map to create
-   * a JProgram structure.
-   */
-  public static void exec(TypeDeclaration[] types, TypeMap typeMap, JProgram jprogram,
-      JJSOptions options) {
-    Event generateJavaAstEvent = SpeedTracerLogger.start(CompilerEventType.GENERATE_JAVA_AST);
-    // Construct the basic AST.
-    JavaASTGenerationVisitor v = new JavaASTGenerationVisitor(typeMap, jprogram, options);
-    for (TypeDeclaration type : types) {
-      v.processType(type);
-    }
-    for (TypeDeclaration type : types) {
-      v.addBridgeMethods(type.binding);
-    }
-    Collections.sort(jprogram.getDeclaredTypes(), new HasNameSort());
-
-    // Process JSNI.
-    Map<JsniMethodBody, AbstractMethodDeclaration> jsniMethodMap = v.getJsniMethodMap();
-    new JsniRefGenerationVisitor(jprogram, jsniMethodMap).accept(jprogram);
-    generateJavaAstEvent.end();
-  }
-
-  /**
-   * Returns <code>true</code> if JDT optimized the condition to
-   * <code>false</code>.
-   */
-  private static boolean isOptimizedFalse(Expression condition) {
-    if (condition != null) {
-      Constant cst = condition.optimizedBooleanConstant();
-      if (cst != Constant.NotAConstant) {
-        if (cst.booleanValue() == false) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Returns <code>true</code> if JDT optimized the condition to
-   * <code>true</code>.
-   */
-  private static boolean isOptimizedTrue(Expression condition) {
-    if (condition != null) {
-      Constant cst = condition.optimizedBooleanConstant();
-      if (cst != Constant.NotAConstant) {
-        if (cst.booleanValue()) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  private static boolean isScript(JProgram program) {
-    return !program.getTypeJavaLangObject().isExternal();
-  }
-}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index c599720..b059bd8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -1746,7 +1746,7 @@
        * }
        * </pre>
        */
-      SourceInfo sourceInfo = program.createSourceInfoSynthetic(GenerateJavaScriptAST.class);
+      SourceInfo sourceInfo = SourceOrigin.UNKNOWN;
 
       JsName entryName = topScope.declareName("$entry");
       JsVar entryVar = new JsVar(sourceInfo, entryName);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
index 80fb3a3..1a8410c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
@@ -1880,7 +1880,6 @@
        * It's okay to defer creation of synthetic fields, they can't be
        * referenced until we analyze the code.
        */
-      int index = 0;
       SourceTypeBinding binding = x.binding;
       if (isNested(binding)) {
         // add synthetic fields for outer this and locals
@@ -1889,7 +1888,7 @@
         if (nestedBinding.enclosingInstances != null) {
           for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
             SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
-            createSyntheticField(arg, type, index++, Disposition.THIS_REF);
+            createSyntheticField(arg, type, Disposition.THIS_REF);
           }
         }
 
@@ -1908,7 +1907,7 @@
                 }
               }
             }
-            createSyntheticField(arg, type, index++, isReallyThisRef ? Disposition.THIS_REF
+            createSyntheticField(arg, type, isReallyThisRef ? Disposition.THIS_REF
                 : Disposition.FINAL);
           }
         }
@@ -2084,13 +2083,11 @@
     }
 
     private JField createSyntheticField(SyntheticArgumentBinding arg, JDeclaredType enclosingType,
-        int index, Disposition disposition) {
+        Disposition disposition) {
       JType type = typeMap.get(arg.type);
       SourceInfo info = enclosingType.getSourceInfo();
       JField field = new JField(info, intern(arg.name), enclosingType, type, false, disposition);
-      // TODO: remove me, source identical for now!
-      enclosingType.addField(index, field);
-      // enclosingType.addField(field);
+      enclosingType.addField(field);
       curClass.syntheticFields.put(arg, field);
       if (arg.matchingField != null) {
         typeMap.setField(arg.matchingField, field);
@@ -2758,8 +2755,6 @@
     }
   }
 
-  public static boolean ENABLED = true;
-
   /**
    * Manually tracked version count.
    * 
@@ -2803,7 +2798,7 @@
    */
   public static long getSerializationVersion() {
     // TODO(zundel): something much awesomer.
-    return ENABLED ? AST_VERSION : 0L;
+    return AST_VERSION;
   }
 
   static String dotify(char[][] name) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java
index 33684c5..a6cd491 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java
@@ -35,7 +35,10 @@
 
 /**
  * A utility class that can look up a {@link JsniRef} in a {@link JProgram}.
+ * 
+ * @deprecated find alternatives, only a couple of corner cases use this now.
  */
+@Deprecated
 public class JsniRefLookup {
   /**
    * A callback used to indicate the reason for a failed JSNI lookup.
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JsoDevirtualizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JsoDevirtualizer.java
index 31d952b..680e19b 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JsoDevirtualizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JsoDevirtualizer.java
@@ -243,8 +243,10 @@
     jsoMethodInstances.put(polyMethod.getSignature(), methodCount);
     String devirtualName = prefix + "__devirtual$";
     JMethod newMethod =
-        program.createMethod(sourceInfo, devirtualName, jsoType, polyMethod.getType(), false, true,
-            true, AccessModifier.PUBLIC, false);
+        new JMethod(sourceInfo, devirtualName, jsoType, polyMethod.getType(), false, true, true,
+            AccessModifier.PUBLIC);
+    newMethod.setBody(new JMethodBody(sourceInfo));
+    jsoType.addMethod(newMethod);
     newMethod.setSynthetic();
 
     // Setup parameters.
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java
deleted file mode 100644
index 94056ee..0000000
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jjs.impl;
-
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.dev.jdt.RebindPermutationOracle;
-import com.google.gwt.dev.jjs.InternalCompilerException;
-import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.HasName;
-import com.google.gwt.dev.jjs.ast.JClassLiteral;
-import com.google.gwt.dev.jjs.ast.JClassType;
-import com.google.gwt.dev.jjs.ast.JDeclaredType;
-import com.google.gwt.dev.jjs.ast.JExpression;
-import com.google.gwt.dev.jjs.ast.JGwtCreate;
-import com.google.gwt.dev.jjs.ast.JMethod;
-import com.google.gwt.dev.jjs.ast.JMethodCall;
-import com.google.gwt.dev.jjs.ast.JModVisitor;
-import com.google.gwt.dev.jjs.ast.JNameOf;
-import com.google.gwt.dev.jjs.ast.JNode;
-import com.google.gwt.dev.jjs.ast.JNullLiteral;
-import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.jjs.ast.JReferenceType;
-import com.google.gwt.dev.jjs.ast.JStringLiteral;
-import com.google.gwt.dev.util.JsniRef;
-import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Replaces any "GWT.create()" calls with a special node.
- */
-public class ReplaceRebinds {
-
-  private class RebindVisitor extends JModVisitor {
-
-    private JDeclaredType currentClass;
-    private final JMethod nameOfMethod;
-    private final JMethod rebindCreateMethod;
-
-    public RebindVisitor(JMethod nameOfMethod, JMethod rebindCreateMethod) {
-      this.nameOfMethod = nameOfMethod;
-      this.rebindCreateMethod = rebindCreateMethod;
-    }
-
-    @Override
-    public void endVisit(JMethodCall x, Context ctx) {
-      JMethod method = x.getTarget();
-      if (method == nameOfMethod) {
-        replaceImplNameOf(x, ctx);
-
-      } else if (method == rebindCreateMethod) {
-        replaceGwtCreate(x, ctx);
-      }
-    }
-
-    @Override
-    public boolean visit(JMethod x, Context ctx) {
-      currentClass = x.getEnclosingType();
-      return true;
-    }
-
-    private void replaceGwtCreate(JMethodCall x, Context ctx) {
-      assert (x.getArgs().size() == 1);
-      JExpression arg = x.getArgs().get(0);
-      assert (arg instanceof JClassLiteral);
-      JClassLiteral classLiteral = (JClassLiteral) arg;
-      JReferenceType sourceType = (JReferenceType) classLiteral.getRefType();
-      List<JClassType> allRebindResults = getAllPossibleRebindResults(sourceType);
-      JGwtCreate gwtCreate =
-          new JGwtCreate(x.getSourceInfo(), sourceType, allRebindResults, program
-              .getTypeJavaLangObject(), currentClass);
-      if (allRebindResults.size() == 1) {
-        // Just replace with the instantiation expression.
-        ctx.replaceMe(gwtCreate.getInstantiationExpressions().get(0));
-      } else {
-        ctx.replaceMe(gwtCreate);
-      }
-    }
-
-    private void replaceImplNameOf(JMethodCall x, Context ctx) {
-      JExpression arg0 = x.getArgs().get(0);
-      assert arg0 instanceof JStringLiteral;
-      JStringLiteral stringLiteral = (JStringLiteral) arg0;
-      String stringValue = stringLiteral.getValue();
-
-      JNode node = null;
-
-      JDeclaredType refType;
-      JsniRef ref = JsniRef.parse(stringValue);
-
-      if (ref != null) {
-        final List<String> errors = new ArrayList<String>();
-        node = JsniRefLookup.findJsniRefTarget(ref, program, new JsniRefLookup.ErrorReporter() {
-          public void reportError(String error) {
-            errors.add(error);
-          }
-        });
-        if (!errors.isEmpty()) {
-          for (String error : errors) {
-            logger.log(TreeLogger.ERROR, error);
-          }
-        }
-      } else {
-        // See if it's just @foo.Bar, which would result in the class seed
-        node =
-            program.getFromTypeMap(stringValue.charAt(0) == '@' ? stringValue.substring(1)
-                : stringValue);
-      }
-      if (node == null) {
-        // Not found, must be null
-        ctx.replaceMe(JNullLiteral.INSTANCE);
-      } else {
-        ctx.replaceMe(new JNameOf(x.getSourceInfo(), program.getTypeJavaLangString(),
-            (HasName) node));
-      }
-    }
-  }
-
-  public static boolean exec(TreeLogger logger, JProgram program, RebindPermutationOracle rpo) {
-    Event replaceRebindsEvent = SpeedTracerLogger.start(CompilerEventType.REPLACE_REBINDS);
-    boolean didChange = new ReplaceRebinds(logger, program, rpo).execImpl();
-    replaceRebindsEvent.end();
-    return didChange;
-  }
-
-  private final TreeLogger logger;
-  private final JProgram program;
-  private final RebindPermutationOracle rpo;
-
-  private ReplaceRebinds(TreeLogger logger, JProgram program, RebindPermutationOracle rpo) {
-    this.logger = logger;
-    this.program = program;
-    this.rpo = rpo;
-  }
-
-  protected List<JClassType> getAllPossibleRebindResults(JReferenceType type) {
-    // Rebinds are always on a source type name.
-    String reqType = type.getName().replace('$', '.');
-    String[] answers;
-    try {
-      answers = rpo.getAllPossibleRebindAnswers(logger, reqType);
-    } catch (UnableToCompleteException e) {
-      // Should never happen.
-      throw new InternalCompilerException("Unexpected failure to get possible rebind answers for '"
-          + reqType + "'");
-    }
-    List<JClassType> rebindAnswers = new ArrayList<JClassType>();
-    for (String answer : answers) {
-      JReferenceType result = program.getFromTypeMap(answer);
-      assert (result != null);
-      rebindAnswers.add((JClassType) result);
-    }
-    assert rebindAnswers.size() > 0;
-    return rebindAnswers;
-  }
-
-  private boolean execImpl() {
-    RebindVisitor rebinder =
-        new RebindVisitor(program.getIndexedMethod("Impl.getNameOf"), program
-            .getIndexedMethod("GWT.create"));
-    rebinder.accept(program);
-    return rebinder.didChange();
-  }
-
-}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ResolveRebinds.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ResolveRebinds.java
index 87d9b98..ba463cd 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ResolveRebinds.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ResolveRebinds.java
@@ -18,6 +18,7 @@
 import com.google.gwt.dev.jjs.InternalCompilerException;
 import com.google.gwt.dev.jjs.SourceInfo;
 import com.google.gwt.dev.jjs.ast.AccessModifier;
+import com.google.gwt.dev.jjs.SourceOrigin;
 import com.google.gwt.dev.jjs.ast.Context;
 import com.google.gwt.dev.jjs.ast.JBlock;
 import com.google.gwt.dev.jjs.ast.JCaseStatement;
@@ -53,7 +54,8 @@
 
       if (isSoftRebind(x.getSourceType())) {
         JMethod method =
-            rebindMethod(x.getSourceType(), x.getResultTypes(), x.getInstantiationExpressions());
+            rebindMethod(x.getSourceInfo(), x.getSourceType(), x.getResultTypes(), x
+                .getInstantiationExpressions());
         JMethodCall call = new JMethodCall(x.getSourceInfo(), null, method);
         ctx.replaceMe(call);
         return;
@@ -76,7 +78,9 @@
     public void endVisit(JReboundEntryPoint x, Context ctx) {
 
       if (isSoftRebind(x.getSourceType())) {
-        JMethod method = rebindMethod(x.getSourceType(), x.getResultTypes(), x.getEntryCalls());
+        JMethod method =
+            rebindMethod(x.getSourceInfo(), x.getSourceType(), x.getResultTypes(), x
+                .getEntryCalls());
         JMethodCall call = new JMethodCall(x.getSourceInfo(), null, method);
         ctx.replaceMe(call.makeStatement());
         return;
@@ -158,7 +162,7 @@
     return !hardRebindAnswers.containsKey(requestType);
   }
 
-  private JMethod rebindMethod(String requestType, List<String> resultTypes,
+  private JMethod rebindMethod(SourceInfo info, String requestType, List<String> resultTypes,
       List<JExpression> instantiationExpressions) {
     assert resultTypes.size() == instantiationExpressions.size();
 
@@ -196,12 +200,13 @@
     }
     assert mostUsed != null;
 
+    info = info.makeChild(SourceOrigin.UNKNOWN);
     // c_g_g_d_c_i_DOMImpl
-    SourceInfo info = program.createSourceInfoSynthetic(getClass());
     toReturn =
-        program.createMethod(info, requestType.replace("_", "_1").replace('.', '_'), holderType,
-            program.getTypeJavaLangObject().getNonNull(), false, true, true,
-            AccessModifier.PUBLIC, false);
+        new JMethod(info, requestType.replace("_", "_1").replace('.', '_'), holderType, program
+            .getTypeJavaLangObject().getNonNull(), false, true, true, AccessModifier.PUBLIC);
+    toReturn.setBody(new JMethodBody(info));
+    holderType.addMethod(toReturn);
     toReturn.freezeParamTypes();
     info.addCorrelation(info.getCorrelator().by(toReturn));
     rebindMethods.put(requestType, toReturn);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeLinker.java b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeLinker.java
deleted file mode 100644
index fd4ff5b..0000000
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeLinker.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jjs.impl;
-
-/**
- * Provides linking information for types for separate compilation.
- */
-public interface TypeLinker {
-
-  TypeLinker NULL_TYPE_LINKER = new TypeLinker() {
-    public boolean isExternalType(String name) {
-      return false;
-    }
-  };
-
-  /**
-   * Returns true if the type is external (source code not provided) to the
-   * program.
-   */
-  boolean isExternalType(String name);
-}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeMap.java b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeMap.java
deleted file mode 100644
index cb2390d..0000000
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeMap.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jjs.impl;
-
-import com.google.gwt.dev.jjs.InternalCompilerException;
-import com.google.gwt.dev.jjs.ast.JConstructor;
-import com.google.gwt.dev.jjs.ast.JDeclaredType;
-import com.google.gwt.dev.jjs.ast.JField;
-import com.google.gwt.dev.jjs.ast.JMethod;
-import com.google.gwt.dev.jjs.ast.JNode;
-import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.jjs.ast.JType;
-import com.google.gwt.dev.util.collect.IdentityHashSet;
-
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Contains the list of the top-level and array types.
- */
-public class TypeMap {
-
-  /**
-   * Maps Eclipse AST nodes to our JNodes.
-   */
-  private final Map<Binding, JNode> crossRefMap = new IdentityHashMap<Binding, JNode>();
-
-  private final Map<String, JDeclaredType> externalTypesByName =
-      new HashMap<String, JDeclaredType>();
-
-  /**
-   * Centralizes creation and singleton management.
-   */
-  private final JProgram program;
-
-  public TypeMap(JProgram program) {
-    this.program = program;
-  }
-
-  public JNode get(Binding binding) {
-    return get(binding, true);
-  }
-
-  public JProgram getProgram() {
-    return program;
-  }
-
-  public void put(Binding binding, JNode to) {
-    if (binding == null) {
-      throw new InternalCompilerException("Trying to put null into typeMap.");
-    }
-
-    Object old = crossRefMap.put(binding, to);
-    assert (old == null);
-
-    if (to instanceof JDeclaredType) {
-      JDeclaredType type = (JDeclaredType) to;
-      if (type.isExternal()) {
-        externalTypesByName.put(type.getName(), type);
-      }
-    }
-  }
-
-  public JNode tryGet(Binding binding) {
-    return get(binding, false);
-  }
-
-  private boolean equals(MethodBinding binding, JMethod method) {
-    if (!(method instanceof JConstructor && binding.isConstructor())
-        && !method.getName().equals(String.valueOf(binding.constantPoolName()))) {
-      return false;
-    }
-
-    List<JType> paramTypes = method.getOriginalParamTypes();
-    TypeBinding[] bindingParams = binding.parameters;
-
-    if (paramTypes.size() != bindingParams.length) {
-      return false;
-    }
-
-    for (int i = 0; i < bindingParams.length; ++i) {
-      TypeBinding bindingParam = bindingParams[i];
-      if (paramTypes.get(i) != get(bindingParam)) {
-        return false;
-      }
-    }
-
-    return method.getType() == get(binding.returnType);
-  }
-
-  private JNode get(Binding binding, boolean failOnNull) {
-    if (binding instanceof TypeVariableBinding) {
-      TypeVariableBinding tvb = (TypeVariableBinding) binding;
-      return get(tvb.erasure(), failOnNull);
-    } else if (binding instanceof ParameterizedTypeBinding) {
-      ParameterizedTypeBinding ptb = (ParameterizedTypeBinding) binding;
-      return get(ptb.erasure(), failOnNull);
-    } else if (binding instanceof ParameterizedMethodBinding) {
-      ParameterizedMethodBinding pmb = (ParameterizedMethodBinding) binding;
-      return get(pmb.original(), failOnNull);
-    } else if (binding instanceof ParameterizedFieldBinding) {
-      ParameterizedFieldBinding pfb = (ParameterizedFieldBinding) binding;
-      return get(pfb.original(), failOnNull);
-    } else if (binding instanceof WildcardBinding) {
-      WildcardBinding wcb = (WildcardBinding) binding;
-      return get(wcb.erasure(), failOnNull);
-    }
-    JNode result = internalGet(binding, failOnNull);
-    if (result == null && failOnNull) {
-      InternalCompilerException ice = new InternalCompilerException("Failed to get JNode");
-      ice.addNode(binding.getClass().getName(), binding.toString(), null);
-      throw ice;
-    }
-    return result;
-  }
-
-  private JField getFieldForBinding(JDeclaredType type, FieldBinding binding) {
-    for (JField field : type.getFields()) {
-      if (field.getName().equals(String.valueOf(binding.name))) {
-        return field;
-      }
-    }
-
-    return null;
-  }
-
-  private JMethod getMethodForBinding(JDeclaredType type, MethodBinding binding) {
-    for (JMethod method : type.getMethods()) {
-      if (equals(binding, method)) {
-        return method;
-      }
-    }
-
-    return null;
-  }
-
-  /**
-   * Returns a list of JNodes that have the same name as the JDT Binding. This
-   * method is only used during debugging sessions from the interactive
-   * expression evaluator.
-   */
-  @SuppressWarnings("unused")
-  private List<JNode> haveSameName(Binding binding) {
-    IdentityHashSet<JNode> nodes = new IdentityHashSet<JNode>();
-    for (Binding b : crossRefMap.keySet()) {
-      if (String.valueOf(b.readableName()).equals(String.valueOf(binding.readableName()))) {
-        nodes.add(crossRefMap.get(b));
-      }
-    }
-    return new ArrayList<JNode>(nodes);
-  }
-
-  private JNode internalGet(Binding binding, boolean failOnNull) {
-    JNode cached = crossRefMap.get(binding);
-    if (cached != null) {
-      return cached;
-    } else if (binding instanceof BaseTypeBinding) {
-      BaseTypeBinding baseTypeBinding = (BaseTypeBinding) binding;
-      // see org.eclipse.jdt.internal.compiler.lookup.TypeIds constants
-      switch (baseTypeBinding.id) {
-        case TypeIds.T_JavaLangObject:
-          // here for consistency, should already be cached
-          return program.getTypeJavaLangObject();
-        case TypeIds.T_char:
-          return program.getTypePrimitiveChar();
-        case TypeIds.T_byte:
-          return program.getTypePrimitiveByte();
-        case TypeIds.T_short:
-          return program.getTypePrimitiveShort();
-        case TypeIds.T_boolean:
-          return program.getTypePrimitiveBoolean();
-        case TypeIds.T_void:
-          return program.getTypeVoid();
-        case TypeIds.T_long:
-          return program.getTypePrimitiveLong();
-        case TypeIds.T_double:
-          return program.getTypePrimitiveDouble();
-        case TypeIds.T_float:
-          return program.getTypePrimitiveFloat();
-        case TypeIds.T_int:
-          return program.getTypePrimitiveInt();
-        case TypeIds.T_JavaLangString:
-          // here for consistency, should already be cached
-          return program.getTypeJavaLangString();
-        case TypeIds.T_null:
-          return program.getTypeNull();
-        case TypeIds.T_undefined:
-        default:
-          return null;
-      }
-    } else if (binding instanceof ArrayBinding) {
-      ArrayBinding arrayBinding = (ArrayBinding) binding;
-      JType elementType = (JType) get(arrayBinding.elementsType(), failOnNull);
-      if (elementType == null) {
-        return null;
-      }
-      return program.getTypeArray(elementType);
-    } else if (binding instanceof BinaryTypeBinding) {
-      BinaryTypeBinding binaryBinding = (BinaryTypeBinding) binding;
-      String name = BuildTypeMap.dotify(binaryBinding.compoundName);
-
-      // There may be many BinaryTypeBindings for a single binary type
-      JDeclaredType type = externalTypesByName.get(name);
-      if (type != null) {
-        put(binding, type);
-      }
-      return type;
-    } else if (binding instanceof MethodBinding) {
-      MethodBinding b = (MethodBinding) binding;
-      JMethod cachedMethod = (JMethod) crossRefMap.get(b);
-      if (cachedMethod == null) {
-        JDeclaredType type = (JDeclaredType) get(b.declaringClass, failOnNull);
-        if (type == null) {
-          return type;
-        }
-        cachedMethod = getMethodForBinding(type, b);
-        if (cachedMethod != null) {
-          put(b, cachedMethod);
-        }
-      } else {
-        // Happens sometimes when looking up the type to resolve the binding
-        // causes us to also resolve the binding.
-      }
-
-      return cachedMethod;
-    } else if (binding instanceof FieldBinding) {
-      FieldBinding b = (FieldBinding) binding;
-      JField cachedField = (JField) crossRefMap.get(b);
-
-      if (cachedField == null) {
-        JDeclaredType type = (JDeclaredType) get(b.declaringClass, failOnNull);
-        if (type == null) {
-          return null;
-        }
-        cachedField = getFieldForBinding(type, b);
-        if (cachedField != null) {
-          put(b, cachedField);
-        }
-      } else {
-        // Happens sometimes when looking up the type to resolve the binding
-        // causes us to also resolve the binding.
-      }
-
-      return cachedField;
-    }
-
-    return null;
-  }
-}
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java b/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
index a46ae10..06490a1 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
@@ -516,10 +516,13 @@
     this.classFileMapBySource = rpo.getCompilationState().getClassFileMapBySource();
   }
 
-  public void addRootTypes(Collection<String> sourceTypeNames) {
+  public void addRootTypes(Collection<String> sourceTypeNames) throws UnableToCompleteException {
     for (String sourceTypeName : sourceTypeNames) {
       searchForTypeBySource(sourceTypeName);
     }
+    if (errorsFound) {
+      throw new UnableToCompleteException();
+    }
   }
 
   /**
diff --git a/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java b/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java
index 5082227..3ed9a94 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java
@@ -215,30 +215,31 @@
     createSampleProgram();
   }
 
-  private JClassType createClass(String className, JClassType superClass,
-      boolean isAbstract, boolean isFinal) {
-    JClassType clazz = program.createClass(synthSource, className, isAbstract,
-        isFinal);
-    clazz.setSuperClass(superClass);
-    return clazz;
+  private JClassType createClass(String className, JClassType superClass, boolean isAbstract,
+      boolean isFinal) {
+    JClassType x = new JClassType(synthSource, className, isAbstract, isFinal);
+    program.addType(x);
+    x.setSuperClass(superClass);
+    return x;
   }
 
   private JInterfaceType createInterface(String className) {
-    JInterfaceType intf = program.createInterface(synthSource, className);
-    return intf;
+    JInterfaceType x = new JInterfaceType(synthSource, className);
+    program.addType(x);
+    return x;
   }
 
   private void createSampleProgram() {
     // Make the program itself
     program = new JProgram();
     typeOracle = program.typeOracle;
-    synthSource = program.createSourceInfoSynthetic(JjsTypeTest.class);
+    synthSource = SourceOrigin.UNKNOWN;
 
     classObject = createClass("java.lang.Object", null, false, false);
     classString = createClass("java.lang.String", classObject, false, true);
     createClass("com.google.gwt.lang.Array", classObject, false, true);
-    classJso = createClass("com.google.gwt.core.client.JavaScriptObject",
-        classObject, false, false);
+    classJso =
+        createClass("com.google.gwt.core.client.JavaScriptObject", classObject, false, false);
 
     intfSerializable = createInterface("java.io.Serializable");
     intfCloneable = createInterface("java.lang.Cloneable");
@@ -267,7 +268,7 @@
     classJso1.addImplements(intfJ);
     classJso2 = createClass("Jso2", classJso, false, false);
     classJso2.addImplements(intfK);
-    
+
     program.typeOracle.computeBeforeAST();
 
     // Save off some miscellaneous types to test against
@@ -287,8 +288,7 @@
     arrayOfArrayOfB = program.getTypeArray(classB, 2);
   }
 
-  private JReferenceType generalizeTypes(JReferenceType type1,
-      JReferenceType type2) {
+  private JReferenceType generalizeTypes(JReferenceType type1, JReferenceType type2) {
     List<JReferenceType> types = new ArrayList<JReferenceType>(2);
     types.add(type1);
     types.add(type2);
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java b/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
index a1087b0..39c0741 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
@@ -235,17 +235,13 @@
       }
     });
     addBuiltinClasses(sourceOracle);
-    boolean wasEnabled = GwtAstBuilder.ENABLED;
-    try {
-      GwtAstBuilder.ENABLED = true;
-      CompilationState state = CompilationStateBuilder.buildFrom(logger,
-          sourceOracle.getResources(), getAdditionalTypeProviderDelegate());
-      JProgram program = JavaAstConstructor.construct(logger, state,
-          "test.EntryPoint", "com.google.gwt.lang.Exceptions");
-      return program;
-    } finally {
-      GwtAstBuilder.ENABLED = wasEnabled;
-    }
+    CompilationState state =
+        CompilationStateBuilder.buildFrom(logger, sourceOracle.getResources(),
+            getAdditionalTypeProviderDelegate());
+    JProgram program =
+        JavaAstConstructor.construct(logger, state, "test.EntryPoint",
+            "com.google.gwt.lang.Exceptions");
+    return program;
   }
 
   protected void addBuiltinClasses(MockResourceOracle sourceOracle) {
diff --git a/user/test/com/google/gwt/dev/jjs/GwtAstBuilderTest.java b/user/test/com/google/gwt/dev/jjs/GwtAstBuilderTest.java
deleted file mode 100644
index e3ab41e..0000000
--- a/user/test/com/google/gwt/dev/jjs/GwtAstBuilderTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.jjs;
-
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.dev.GwtAstBuilderUtil;
-import com.google.gwt.dev.cfg.ModuleDef;
-import com.google.gwt.dev.cfg.ModuleDefLoader;
-import com.google.gwt.dev.javac.CompilationState;
-import com.google.gwt.dev.javac.CompilationUnit;
-import com.google.gwt.dev.jjs.ast.JDeclaredType;
-import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
-
-import junit.framework.TestCase;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Massive test for {@link com.google.gwt.dev.jjs.impl.GwtAstBuilder}.
- */
-public class GwtAstBuilderTest extends TestCase {
-  /*
-   * Reuse the module and compilation state between tests, because it takes a
-   * long time to build them. This is fine as long as we don't mutate them.
-   */
-
-  private static CompilationState compilationState;
-  private static PrintWriterTreeLogger logger;
-  private static ModuleDef module;
-
-  private static synchronized CompilationState getCompilationState()
-      throws UnableToCompleteException {
-    if (compilationState == null) {
-      compilationState = GwtAstBuilderUtil.buildGwtAst(getLogger(), getTestModule());
-    }
-    return compilationState;
-  }
-
-  private static synchronized TreeLogger getLogger() {
-    if (logger == null) {
-      logger = new PrintWriterTreeLogger(new PrintWriter(System.err, true));
-      logger.setMaxDetail(TreeLogger.ERROR);
-    }
-    return logger;
-  }
-
-  private static synchronized ModuleDef getTestModule() throws UnableToCompleteException {
-    if (module == null) {
-      module =
-          ModuleDefLoader.createSyntheticModule(getLogger(),
-              "com.google.gwt.dev.jjs.CompilerSuite.GwtAstBuilderTest", new String[]{
-                  "com.google.gwt.junit.JUnit", "com.google.gwt.dev.jjs.CompilerSuite"}, false);
-    }
-    return module;
-  }
-
-  /**
-   * Tests source compatibility between
-   * {@link com.google.gwt.dev.jjs.impl.GwtAstBuilder} and
-   * {@link com.google.gwt.dev.jjs.impl.GenerateJavaAST}.
-   */
-  public void testGwtAstBuilder() throws UnableToCompleteException {
-    CompilationState compilationState = getCompilationState();
-    assertFalse(compilationState.hasErrors());
-    JProgram jprogram =
-        GwtAstBuilderUtil.buildGenerateJavaAst(getLogger(), getTestModule(), compilationState);
-
-    Map<String, JDeclaredType> compStateTypes = new HashMap<String, JDeclaredType>();
-    for (CompilationUnit unit : compilationState.getCompilationUnits()) {
-      for (JDeclaredType type : unit.getTypes()) {
-        compStateTypes.put(type.getName(), type);
-      }
-    }
-
-    for (JDeclaredType genJavaAstType : jprogram.getDeclaredTypes()) {
-      String typeName = genJavaAstType.getName();
-      if ("com.google.gwt.core.client.GWT".equals(typeName)) {
-        // Known mismatch; UnifyAst fills in the magic methods.
-        continue;
-      }
-      if ("com.google.gwt.core.client.JavaScriptObject".equals(typeName)) {
-        // Known mismatch; genJavaAst version implements all JSO interfaces.
-        continue;
-      }
-      if ("com.google.gwt.dev.jjs.test.B$1".equals(typeName)) {
-        // Known mismatch; genJavaAst is "wrong".
-        continue;
-      }
-      if (typeName.startsWith("com.google.gwt.dev.jjs.test.CoverageTest$Inner$1")) {
-        // Known mismatch; two different emulation paths do the same thing.
-        continue;
-      }
-      JDeclaredType compStateType = compStateTypes.get(typeName);
-      assertNotNull("No matching prebuilt type for '" + typeName + "'", compStateType);
-      String oldSource = genJavaAstType.toSource();
-      String newSource = compStateType.toSource();
-      assertEquals("Mismatched output for '" + typeName + "'", oldSource, newSource);
-    }
-  }
-
-  /**
-   * Test that serialization doesn't crash and produces the same source tree.
-   */
-  public void testSerialization() throws UnableToCompleteException, IOException,
-      ClassNotFoundException {
-    CompilationState compilationState = getCompilationState();
-    assertFalse(compilationState.hasErrors());
-    for (CompilationUnit unit : compilationState.getCompilationUnits()) {
-      Map<String, JDeclaredType> compStateTypes = new HashMap<String, JDeclaredType>();
-      for (JDeclaredType type : unit.getTypes()) {
-        compStateTypes.put(type.getName(), type);
-      }
-      byte[] bytes = unit.getTypesSerialized();
-      ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-      ObjectInputStream ois = new ObjectInputStream(bais);
-      List<JDeclaredType> deserializedTypes = JProgram.deserializeTypes(ois);
-      assertEquals(compStateTypes.size(), deserializedTypes.size());
-      for (JDeclaredType deserializedType : deserializedTypes) {
-        String typeName = deserializedType.getName();
-        JDeclaredType compStateType = compStateTypes.get(typeName);
-        assertNotNull("No matching prebuilt type for '" + typeName + "'", compStateType);
-        String oldSource = compStateType.toSource();
-        String newSource = deserializedType.toSource();
-        assertEquals("Mismatched output for '" + typeName + "'", oldSource, newSource);
-      }
-    }
-  }
-}