diff --git a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
index e35484c..a789ac0 100644
--- a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
+++ b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
@@ -19,8 +19,11 @@
 import com.google.gwt.core.client.GwtScriptOnly;
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.TreeLogger.Type;
 import com.google.gwt.core.ext.typeinfo.JArrayType;
 import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JMethod;
+import com.google.gwt.core.ext.typeinfo.JParameter;
 import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
 import com.google.gwt.core.ext.typeinfo.JType;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
@@ -31,11 +34,14 @@
 import com.google.gwt.dev.jjs.InternalCompilerException;
 import com.google.gwt.dev.shell.rewrite.HasAnnotation;
 import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter;
-import com.google.gwt.dev.shell.rewrite.SingleJsoImplSupport;
+import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.InstanceMethodOracle;
+import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SingleJsoImplData;
 import com.google.gwt.dev.util.JsniRef;
+import com.google.gwt.dev.util.Name;
 import com.google.gwt.dev.util.Util;
 import com.google.gwt.dev.util.Name.InternalName;
 import com.google.gwt.dev.util.Name.SourceOrBinaryName;
+import com.google.gwt.dev.util.collect.Lists;
 import com.google.gwt.util.tools.Utility;
 
 import org.apache.commons.collections.map.AbstractReferenceMap;
@@ -58,7 +64,9 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.SortedSet;
 import java.util.Stack;
+import java.util.TreeSet;
 
 /**
  * An isolated {@link ClassLoader} for running all user code. All user files are
@@ -286,6 +294,11 @@
         return null;
       }
 
+      // Map JSO type references to the appropriate impl class.
+      if (classRewriter.isJsoIntf(cls.getName())) {
+        cls = getClassFromBinaryName(cls.getName() + "$");
+      }
+
       /*
        * we need to create a new DispatchClassInfo since we have never seen this
        * class before under any source or binary class name
@@ -342,6 +355,325 @@
   }
 
   /**
+   * Implements {@link InstanceMethodOracle} on behalf of the
+   * {@link HostedModeClassRewriter}. Implemented using {@link TypeOracle}.
+   */
+  private class MyInstanceMethodOracle implements InstanceMethodOracle {
+
+    private final Map<String, Set<JClassType>> signatureToDeclaringClasses = new HashMap<String, Set<JClassType>>();
+
+    public MyInstanceMethodOracle(Set<JClassType> jsoTypes,
+        JClassType javaLangObject, SingleJsoImplData jsoData) {
+
+      // Record that the JSO implements its own methods
+      for (JClassType type : jsoTypes) {
+        for (JMethod method : type.getMethods()) {
+          if (!method.isStatic()) {
+            assert !method.isAbstract() : "Abstract method in JSO type "
+                + method;
+            add(type, method);
+          }
+        }
+      }
+
+      /*
+       * Record the implementing types for methods defined in SingleJsoImpl
+       * interfaces. We have to make this pass because of possible variance in
+       * the return types between the abstract method declaration in the
+       * interface and the concrete method.
+       */
+      for (String intfName : jsoData.getSingleJsoIntfTypes()) {
+        // We only store the name in the data block to keep it lightweight
+        JClassType intf = typeOracle.findType(Name.InternalName.toSourceName(intfName));
+        JClassType jso = typeOracle.getSingleJsoImpl(intf);
+        for (JMethod method : intf.getMethods()) {
+          add(jso, method);
+        }
+      }
+
+      // Object clobbers everything.
+      for (JMethod method : javaLangObject.getMethods()) {
+        if (!method.isStatic()) {
+          String signature = createSignature(method);
+          Set<JClassType> declaringClasses = new HashSet<JClassType>();
+          signatureToDeclaringClasses.put(signature, declaringClasses);
+          declaringClasses.add(javaLangObject);
+        }
+      }
+    }
+
+    public String findOriginalDeclaringClass(String desc, String signature) {
+      // Lookup the method.
+      Set<JClassType> declaringClasses = signatureToDeclaringClasses.get(signature);
+      assert declaringClasses != null : "No classes for " + signature;
+      if (declaringClasses.size() == 1) {
+        // Shortcut: if there's only one answer, it must be right.
+        return createDescriptor(declaringClasses.iterator().next());
+      }
+      // Must check for assignability.
+      String sourceName = desc.replace('/', '.');
+      sourceName = sourceName.replace('$', '.');
+      JClassType declaredType = typeOracle.findType(sourceName);
+
+      // Check if I declare this directly.
+      if (declaringClasses.contains(declaredType)) {
+        return desc;
+      }
+
+      // Check to see what type I am assignable to.
+      for (JClassType possibleSupertype : declaringClasses) {
+        if (declaredType.isAssignableTo(possibleSupertype)) {
+          return createDescriptor(possibleSupertype);
+        }
+      }
+      throw new IllegalArgumentException("Could not resolve signature '"
+          + signature + "' from class '" + desc + "'");
+    }
+
+    /**
+     * Record that a given JSO type contains the concrete implementation of a
+     * (possibly abstract) method.
+     */
+    private void add(JClassType type, JMethod method) {
+      String signature = createSignature(method);
+      Set<JClassType> declaringClasses = signatureToDeclaringClasses.get(signature);
+      if (declaringClasses == null) {
+        declaringClasses = new HashSet<JClassType>();
+        signatureToDeclaringClasses.put(signature, declaringClasses);
+      }
+      declaringClasses.add(type);
+    }
+
+    private String createDescriptor(JClassType type) {
+      String jniSignature = type.getJNISignature();
+      return jniSignature.substring(1, jniSignature.length() - 1);
+    }
+
+    private String createSignature(JMethod method) {
+      StringBuffer sb = new StringBuffer(method.getName());
+      sb.append('(');
+      for (JParameter param : method.getParameters()) {
+        sb.append(param.getType().getJNISignature());
+      }
+      sb.append(')');
+      sb.append(method.getReturnType().getJNISignature());
+      String signature = sb.toString();
+      return signature;
+    }
+  }
+
+  /**
+   * Cook up the data we need to support JSO subtypes that implement interfaces
+   * with methods. This includes the set of SingleJsoImpl interfaces actually
+   * implemented by a JSO type, the mangled method names, and the names of the
+   * Methods that should actually implement the virtual functions.
+   * 
+   * Given the current implementation of JSO$ and incremental execution of
+   * rebinds, it's not possible for Generators to produce additional
+   * JavaScriptObject subtypes, so this data can remain static.
+   */
+  private class MySingleJsoImplData implements SingleJsoImplData {
+    private final SortedSet<String> mangledNames = new TreeSet<String>();
+    private final Map<String, List<com.google.gwt.dev.asm.commons.Method>> mangledNamesToDeclarations = new HashMap<String, List<com.google.gwt.dev.asm.commons.Method>>();
+    private final Map<String, List<com.google.gwt.dev.asm.commons.Method>> mangledNamesToImplementations = new HashMap<String, List<com.google.gwt.dev.asm.commons.Method>>();
+    private final SortedSet<String> unmodifiableNames = Collections.unmodifiableSortedSet(mangledNames);
+    private final Set<String> unmodifiableIntfNames = Collections.unmodifiableSet(singleJsoImplTypes);
+
+    public MySingleJsoImplData() {
+      // Loop over all interfaces with JSO implementations
+      typeLoop : for (JClassType type : typeOracle.getSingleJsoImplInterfaces()) {
+        assert type.isInterface() == type : "Expecting interfaces only";
+
+        /*
+         * By preemptively adding all possible mangled names by which a method
+         * could be called, we greatly simplify the logic necessary to rewrite
+         * the call-site.
+         * 
+         * interface A {void m();}
+         * 
+         * interface B extends A {void z();}
+         * 
+         * becomes
+         * 
+         * c_g_p_A_m() -> JsoA$.m$()
+         * 
+         * c_g_p_B_m() -> JsoA$.m$()
+         * 
+         * c_g_p_B_z() -> JsoB$.z$()
+         */
+        for (JMethod intfMethod : type.getOverridableMethods()) {
+          assert intfMethod.isAbstract() : "Expecting only abstract methods";
+
+          /*
+           * It is necessary to locate the implementing type on a per-method
+           * basis. Consider the case of
+           * 
+           * @SingleJsoImpl interface C extends A, B {}
+           * 
+           * Methods inherited from interfaces A and B must be dispatched to
+           * their respective JSO implementations.
+           */
+          JClassType implementingType = typeOracle.getSingleJsoImpl(intfMethod.getEnclosingType());
+
+          if (implementingType == null) {
+            /*
+             * This means that there is no concrete implementation of the
+             * interface by a JSO. Any implementation that might be created by a
+             * Generator won't be a JSO subtype, so we'll just ignore it as an
+             * actionable type. Were Generators ever able to create new JSO
+             * subtypes, we'd have to speculatively rewrite the callsite.
+             */
+            continue typeLoop;
+          }
+
+          /*
+           * Record the type as being actionable.
+           */
+          singleJsoImplTypes.add(canonicalizeClassName(getBinaryName(type)));
+
+          /*
+           * The mangled name adds the current interface like
+           * 
+           * com_foo_Bar_methodName
+           */
+          String mangledName = getBinaryName(type).replace('.', '_') + "_"
+              + intfMethod.getName();
+          mangledNames.add(mangledName);
+
+          /*
+           * Handle virtual overrides by finding the method that we would
+           * normally invoke and using its declaring class as the dispatch
+           * target.
+           */
+          JMethod implementingMethod;
+          while ((implementingMethod = findOverloadUsingErasure(
+              implementingType, intfMethod)) == null) {
+            implementingType = implementingType.getSuperclass();
+          }
+          // implementingmethod and implementingType cannot be null here
+
+          /*
+           * Create a pseudo-method declaration for the interface method. This
+           * should look something like
+           * 
+           * ReturnType method$ (ParamType, ParamType)
+           * 
+           * This must be kept in sync with the WriteJsoImpl class.
+           */
+          {
+            String decl = getBinaryOrPrimitiveName(intfMethod.getReturnType().getErasedType())
+                + " " + intfMethod.getName() + "(";
+            for (JParameter param : intfMethod.getParameters()) {
+              decl += ",";
+              decl += getBinaryOrPrimitiveName(param.getType().getErasedType());
+            }
+            decl += ")";
+
+            com.google.gwt.dev.asm.commons.Method declaration = com.google.gwt.dev.asm.commons.Method.getMethod(decl);
+            addToMap(mangledNamesToDeclarations, mangledName, declaration);
+          }
+
+          /*
+           * Cook up the a pseudo-method declaration for the concrete type. This
+           * should look something like
+           * 
+           * ReturnType method$ (JsoType, ParamType, ParamType)
+           * 
+           * This must be kept in sync with the WriteJsoImpl class.
+           */
+          {
+            String returnName = getBinaryOrPrimitiveName(implementingMethod.getReturnType().getErasedType());
+            String jsoName = getBinaryOrPrimitiveName(implementingType);
+
+            String decl = returnName + " " + intfMethod.getName() + "$ ("
+                + jsoName;
+            for (JParameter param : implementingMethod.getParameters()) {
+              decl += ",";
+              decl += getBinaryOrPrimitiveName(param.getType().getErasedType());
+            }
+            decl += ")";
+
+            com.google.gwt.dev.asm.commons.Method toImplement = com.google.gwt.dev.asm.commons.Method.getMethod(decl);
+            addToMap(mangledNamesToImplementations, mangledName, toImplement);
+          }
+        }
+      }
+
+      if (logger.isLoggable(Type.SPAM)) {
+        TreeLogger dumpLogger = logger.branch(Type.SPAM,
+            "SingleJsoImpl method mappings");
+        for (Map.Entry<String, List<com.google.gwt.dev.asm.commons.Method>> entry : mangledNamesToImplementations.entrySet()) {
+          dumpLogger.log(Type.SPAM, entry.getKey() + " -> " + entry.getValue());
+        }
+      }
+    }
+
+    public List<com.google.gwt.dev.asm.commons.Method> getDeclarations(
+        String mangledName) {
+      List<com.google.gwt.dev.asm.commons.Method> toReturn = mangledNamesToDeclarations.get(mangledName);
+      return toReturn == null ? null : Collections.unmodifiableList(toReturn);
+    }
+
+    public List<com.google.gwt.dev.asm.commons.Method> getImplementations(
+        String mangledName) {
+      List<com.google.gwt.dev.asm.commons.Method> toReturn = mangledNamesToImplementations.get(mangledName);
+      return toReturn == null ? toReturn
+          : Collections.unmodifiableList(toReturn);
+    }
+
+    public SortedSet<String> getMangledNames() {
+      return unmodifiableNames;
+    }
+
+    public Set<String> getSingleJsoIntfTypes() {
+      return unmodifiableIntfNames;
+    }
+
+    /**
+     * Assumes that the usual case is a 1:1 mapping.
+     */
+    private <K, V> void addToMap(Map<K, List<V>> map, K key, V value) {
+      List<V> list = map.get(key);
+      if (list == null) {
+        map.put(key, Lists.create(value));
+      } else {
+        List<V> maybeOther = Lists.add(list, value);
+        if (maybeOther != list) {
+          map.put(key, maybeOther);
+        }
+      }
+    }
+
+    /**
+     * Looks for a concrete implementation of <code>intfMethod</code> in
+     * <code>implementingType</code>.
+     */
+    private JMethod findOverloadUsingErasure(JClassType implementingType,
+        JMethod intfMethod) {
+
+      int numParams = intfMethod.getParameters().length;
+      JType[] erasedTypes = new JType[numParams];
+      for (int i = 0; i < numParams; i++) {
+        erasedTypes[i] = intfMethod.getParameters()[i].getType().getErasedType();
+      }
+
+      outer : for (JMethod method : implementingType.getOverloads(intfMethod.getName())) {
+        JParameter[] params = method.getParameters();
+        if (params.length != numParams) {
+          continue;
+        }
+        for (int i = 0; i < numParams; i++) {
+          if (params[i].getType().getErasedType() != erasedTypes[i]) {
+            continue outer;
+          }
+        }
+        return method;
+      }
+      return null;
+    }
+  }
+
+  /**
    * The names of the bridge classes.
    */
   private static final Map<String, Class<?>> BRIDGE_CLASS_NAMES = new HashMap<String, Class<?>>();
@@ -351,7 +683,7 @@
    * space (thus, they bridge across the spaces).
    */
   private static final Class<?>[] BRIDGE_CLASSES = new Class<?>[] {
-      ShellJavaScriptHost.class, GWTBridge.class, SingleJsoImplSupport.class};
+      ShellJavaScriptHost.class, GWTBridge.class};
 
   private static final boolean CLASS_DUMP = Boolean.getBoolean("gwt.dev.classDump");
 
@@ -529,10 +861,36 @@
 
     ensureJavaScriptHostBytes(logger);
 
-    // Create a class rewriter based on availability of JSO class.
+    // Create a class rewriter based on all the subtypes of the JSO class.
     JClassType jsoType = typeOracle.findType(JsValueGlue.JSO_CLASS);
     if (jsoType != null) {
-      classRewriter = new HostedModeClassRewriter(typeOracle);
+
+      // Create a set of binary names.
+      Set<JClassType> jsoTypes = new HashSet<JClassType>();
+      JClassType[] jsoSubtypes = jsoType.getSubtypes();
+      Collections.addAll(jsoTypes, jsoSubtypes);
+      jsoTypes.add(jsoType);
+
+      Set<String> jsoTypeNames = new HashSet<String>();
+      Map<String, List<String>> jsoSuperTypes = new HashMap<String, List<String>>();
+      for (JClassType type : jsoTypes) {
+        List<String> types = new ArrayList<String>();
+        types.add(getBinaryName(type.getSuperclass()));
+        for (JClassType impl : type.getImplementedInterfaces()) {
+          types.add(getBinaryName(impl));
+        }
+
+        String binaryName = getBinaryName(type);
+        jsoTypeNames.add(binaryName);
+        jsoSuperTypes.put(binaryName, types);
+      }
+
+      SingleJsoImplData singleJsoImplData = new MySingleJsoImplData();
+
+      MyInstanceMethodOracle mapper = new MyInstanceMethodOracle(jsoTypes,
+          typeOracle.getJavaLangObject(), singleJsoImplData);
+      classRewriter = new HostedModeClassRewriter(jsoTypeNames, jsoSuperTypes,
+          singleJsoImplData, mapper);
     } else {
       // If we couldn't find the JSO class, we don't need to do any rewrites.
       classRewriter = null;
@@ -662,7 +1020,7 @@
      * when loading a JSO interface class; just wait until the implementation
      * class is loaded.
      */
-    {
+    if (!classRewriter.isJsoIntf(className)) {
       CompilationUnit unit = getUnitForClassName(canonicalizeClassName(className));
       if (unit != null) {
         toInject.push(unit);
@@ -710,7 +1068,13 @@
    * Convert a binary class name into a resource-like name.
    */
   private String canonicalizeClassName(String className) {
-    return className.replace('.', '/');
+    String lookupClassName = className.replace('.', '/');
+    // A JSO impl class ends with $, strip it
+    if (classRewriter != null && classRewriter.isJsoImpl(className)) {
+      lookupClassName = lookupClassName.substring(0,
+          lookupClassName.length() - 1);
+    }
+    return lookupClassName;
   }
 
   @SuppressWarnings("deprecation")
@@ -718,12 +1082,15 @@
     if (JavaScriptHost.class.getName().equals(className)) {
       // No need to rewrite.
       return javaScriptHostBytes;
-    } else if (className.endsWith(HostedModeClassRewriter.SINGLE_JSO_IMPL_ADJUNCT_SUFFIX)) {
-      byte[] bytes = classRewriter.writeSingleJsoImplAdjunct(className);
+    }
+
+    if (classRewriter != null && classRewriter.isJsoIntf(className)) {
+      // Generate a synthetic JSO interface class.
+      byte[] newBytes = classRewriter.writeJsoIntf(className);
       if (CLASS_DUMP) {
-        classDump(className, bytes);
+        classDump(className, newBytes);
       }
-      return bytes;
+      return newBytes;
     }
 
     // A JSO impl class needs the class bytes for the original class.
@@ -788,8 +1155,8 @@
       if (unit != null) {
         anonymousClassMap = unit.getAnonymousClassMap();
       }
-      byte[] newBytes = classRewriter.rewrite(className, classBytes,
-          anonymousClassMap);
+      byte[] newBytes = classRewriter.rewrite(typeOracle, className,
+          classBytes, anonymousClassMap);
       if (CLASS_DUMP) {
         if (!Arrays.equals(classBytes, newBytes)) {
           classDump(className, newBytes);
@@ -845,8 +1212,6 @@
     if (unit == null || unit.getJsniMethods() == null) {
       return;
     }
-    logger.log(TreeLogger.SPAM, "Injecting JSNI methods for "
-        + unit.getTypeName());
     shellJavaScriptHost.createNativeMethods(logger, unit.getJsniMethods(), this);
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/shell/JsValueGlue.java b/dev/core/src/com/google/gwt/dev/shell/JsValueGlue.java
index fdefaed..02e2cdd 100644
--- a/dev/core/src/com/google/gwt/dev/shell/JsValueGlue.java
+++ b/dev/core/src/com/google/gwt/dev/shell/JsValueGlue.java
@@ -16,7 +16,6 @@
 package com.google.gwt.dev.shell;
 
 import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.dev.shell.rewrite.SingleJsoImplSupport;
 import com.google.gwt.dev.util.TypeInfo;
 
 import java.lang.reflect.Constructor;
@@ -30,13 +29,11 @@
 public final class JsValueGlue {
   public static final String HOSTED_MODE_REFERENCE = "hostedModeReference";
   public static final String JSO_CLASS = "com.google.gwt.core.client.JavaScriptObject";
+  public static final String JSO_IMPL_CLASS = "com.google.gwt.core.client.JavaScriptObject$";
 
   /**
-   * Create a JavaScriptObject instance referring to this JavaScript object,
-   * optionally wrapping the object in the desired JSO facade type.
+   * Create a JavaScriptObject instance referring to this JavaScript object.
    * 
-   * @param desiredType the subclass of JavaScriptObject that the calling code
-   *          wishes to see, or <code>null</code>
    * @param classLoader the classLoader to create from
    * @return the constructed JavaScriptObject
    */
@@ -44,18 +41,23 @@
       CompilingClassLoader classLoader) {
     Throwable caught;
     try {
-      Class<?> jsoType = Class.forName(JSO_CLASS, true, classLoader);
-
       // See if there's already a wrapper object (assures identity comparison).
       Object jso = classLoader.getCachedJso(value.getJavaScriptObjectPointer());
-      if (jso == null) {
-        // Instantiate the JSO instance.
-        Constructor<?> ctor = jsoType.getDeclaredConstructor(Object.class);
-        jso = ctor.newInstance(value);
-
-        classLoader.putCachedJso(value.getJavaScriptObjectPointer(), jso);
+      if (jso != null) {
+        return jso;
       }
 
+      // Instantiate the JSO class.
+      Class<?> jsoType = Class.forName(JSO_IMPL_CLASS, true, classLoader);
+      Constructor<?> ctor = jsoType.getDeclaredConstructor();
+      ctor.setAccessible(true);
+      jso = ctor.newInstance();
+
+      // Set the reference field to this JsValue using reflection.
+      Field referenceField = jsoType.getField(HOSTED_MODE_REFERENCE);
+      referenceField.set(jso, value);
+
+      classLoader.putCachedJso(value.getJavaScriptObjectPointer(), jso);
       return jso;
     } catch (InstantiationException e) {
       caught = e;
@@ -71,6 +73,8 @@
       caught = e;
     } catch (ClassNotFoundException e) {
       caught = e;
+    } catch (NoSuchFieldException e) {
+      caught = e;
     }
     throw new RuntimeException("Error creating JavaScript object", caught);
   }
@@ -84,7 +88,7 @@
    * @param msgPrefix a prefix for error/warning messages
    * @return the object reference
    * @throws com.google.gwt.dev.shell.HostedModeException if the JavaScript
-   *           object is not assignable to the supplied type.
+   *     object is not assignable to the supplied type.
    */
   @SuppressWarnings("unchecked")
   public static <T> T get(JsValue value, CompilingClassLoader cl,
@@ -162,11 +166,7 @@
       return type.cast(value.getString());
     }
     if (value.isJavaScriptObject()) {
-      Object jso = createJavaScriptObject(value, cl);
-      if (type != Object.class) {
-        jso = SingleJsoImplSupport.cast(jso, type);
-      }
-      return type.cast(jso);
+      return type.cast(createJavaScriptObject(value, cl));
     }
 
     // Just don't know what do to with this.
@@ -217,8 +217,8 @@
     } else {
       // not a boxed primitive
       try {
-        Class<?> jsoType = Class.forName(JSO_CLASS, false, cl);
-        if (jsoType.isInstance(obj)) {
+        Class<?> jsoType = Class.forName(JSO_IMPL_CLASS, false, cl);
+        if (jsoType == obj.getClass()) {
           JsValue jsObject = getUnderlyingObject(obj);
           value.setValue(jsObject);
           return;
@@ -258,10 +258,9 @@
       }
       intVal = (int) doubleVal;
       if (intVal != doubleVal) {
-        ModuleSpace.getLogger().log(
-            TreeLogger.WARN,
+        ModuleSpace.getLogger().log(TreeLogger.WARN,
             msgPrefix + ": Rounding double (" + doubleVal + ") to int for "
-                + typeName, null);
+            + typeName, null);
       }
     } else {
       throw new HostedModeException(msgPrefix + ": JS value of type "
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/HostedModeClassRewriter.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/HostedModeClassRewriter.java
index 095eda7..319aeb3 100644
--- a/dev/core/src/com/google/gwt/dev/shell/rewrite/HostedModeClassRewriter.java
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/HostedModeClassRewriter.java
@@ -15,22 +15,22 @@
  */
 package com.google.gwt.dev.shell.rewrite;
 
-import com.google.gwt.core.ext.typeinfo.JClassType;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.dev.asm.ClassAdapter;
 import com.google.gwt.dev.asm.ClassReader;
 import com.google.gwt.dev.asm.ClassVisitor;
 import com.google.gwt.dev.asm.ClassWriter;
 import com.google.gwt.dev.asm.Opcodes;
+import com.google.gwt.dev.asm.commons.Method;
 import com.google.gwt.dev.shell.JsValueGlue;
-import com.google.gwt.dev.util.Name.InternalName;
 
-import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.SortedSet;
 
 /**
  * This class performs any and all byte code rewriting needed to make hosted
@@ -38,123 +38,25 @@
  * <ol>
  * <li>Rewrites all native methods into non-native thunks to call JSNI via
  * {@link com.google.gwt.dev.shell.JavaScriptHost}.</li>
- * <li>JavaScriptObject and its subtypes gain a static {@value #REWRAP_METHOD}
- * method and new constructor methods.</li>
- * <li>All uses of <code>==</code> object comparisons gain an explicit cast to
- * Object to force canonicalization.</li>
- * <li>Casts and assignments to Object, JavaScriptObject, and interface types
- * have runtime type-fitting code added to support the not-really-a-type
- * semantic.</li>
- * <li>All interfaces that a JSO may implement have an adjunct class generated
- * that aids the SingleJsoImpl cast operations.</li>
+ * <li>Rewrites all JSO types into an interface type (which retains the original
+ * name) and an implementation type (which has a $ appended).</li>
+ * <li>All JSO interface types are empty and mirror the original type hierarchy.
+ * </li>
+ * <li>All JSO impl types contain the guts of the original type, except that all
+ * instance methods are reimplemented as statics.</li>
+ * <li>Calls sites to JSO types rewritten to dispatch to impl types. Any virtual
+ * calls are also made static. Static field references to JSO types reference
+ * static fields in the the impl class.</li>
+ * <li>JavaScriptObject$ implements all the interface types and is the only
+ * instantiable type.</li>
  * </ol>
  * 
  * @see RewriteJsniMethods
+ * @see RewriteRefsToJsoClasses
+ * @see WriteJsoInterface
  * @see WriteJsoImpl
- * @see RewriteObjectComparisons
- * @see RewriteJsoCasts
- * @see WriteSingleJsoSupportCode
  */
 public class HostedModeClassRewriter {
-
-  /**
-   * An oracle to answer queries from the rewriting passes about the
-   * type-system.
-   */
-  static class RewriterOracle {
-    private final JClassType jsoType;
-    /**
-     * The TypeOracle for the module being rewritten. We need the typeOracle to
-     * provide a live view of the module's type-system, since Generators may add
-     * new JSO types.
-     */
-    private final TypeOracle typeOracle;
-
-    public RewriterOracle(TypeOracle typeOracle) {
-      this.typeOracle = typeOracle;
-      jsoType = typeOracle.findType(JsValueGlue.JSO_CLASS);
-      assert jsoType != null : "No JavaScriptObject type";
-    }
-
-    /**
-     * Returns <code>true</code> if a given type is potentially assignable from
-     * a JSO subtype.
-     */
-    public boolean couldContainJso(String internalName) {
-      return "java/lang/Object".equals(internalName)
-          || JAVASCRIPTOBJECT_DESC.equals(internalName)
-          || isJsoOrSubtype(internalName)
-          || (!internalName.startsWith("java/") && isInterface(internalName));
-    }
-
-    public String[] getAllSuperInterfaces(String[] interfaces) {
-      Set<String> toReturn = new HashSet<String>();
-      Set<JClassType> seen = new HashSet<JClassType>();
-      List<JClassType> queue = new LinkedList<JClassType>();
-
-      for (String intf : interfaces) {
-        JClassType type = typeOracle.findType(InternalName.toSourceName(intf));
-        if (type == null) {
-          throw new RuntimeException("Unknown type " + intf);
-        }
-        queue.add(type);
-      }
-
-      while (!queue.isEmpty()) {
-        JClassType intf = queue.remove(0);
-        if (seen.contains(intf)) {
-          continue;
-        }
-        seen.add(intf);
-        toReturn.add(intf.getQualifiedBinaryName().replace('.', '/'));
-        queue.addAll(Arrays.asList(intf.getImplementedInterfaces()));
-      }
-
-      String[] array = toReturn.toArray(new String[toReturn.size()]);
-      Arrays.sort(array);
-      return array;
-    }
-
-    public boolean isInterface(String internalName) {
-      String sourceName = InternalName.toSourceName(internalName);
-      if (sourceName.contains("$")) {
-        // Anonymous type
-        return false;
-      }
-      JClassType type = typeOracle.findType(sourceName);
-      return type != null && type.isInterface() != null;
-    }
-
-    public boolean isJsoOrSubtype(String internalName) {
-      String sourceName = InternalName.toSourceName(internalName);
-      if (sourceName.contains("$")) {
-        // Anonymous type
-        return false;
-      }
-      JClassType type = typeOracle.findType(sourceName);
-      return type != null && jsoType.isAssignableFrom(type);
-    }
-
-    public boolean isTagInterface(String internalName) {
-      String sourceName = InternalName.toSourceName(internalName);
-      if (sourceName.contains("$")) {
-        // Anonymous type
-        return false;
-      }
-      JClassType type = typeOracle.findType(sourceName);
-      return type != null && type.isInterface() != null
-          && type.getOverridableMethods().length == 0;
-    }
-
-    /**
-     * Returns <code>true</code> if a JSO assigned to a slot/field of this type
-     * requires canonicalizing the JSO wrapper.
-     */
-    public boolean jsoAssignmentRequiresCanonicalization(String internalName) {
-      return "java/lang/Object".equals(internalName);
-    }
-  }
-
   /*
    * Note: this rewriter operates on a class-by-class basis and has no global
    * view on the entire system. However, its operation requires certain global
@@ -163,66 +65,160 @@
    */
 
   /**
-   * Used in CompilingClassLoader to trigger a call to
-   * {@link #writeSingleJsoImplAdjunct}.
+   * Maps instance methods to the class in which they are declared. This must be
+   * provided by the caller since it requires global program state.
    */
-  public static final String SINGLE_JSO_IMPL_ADJUNCT_SUFFIX = "$$singleJsoImpl";
+  public interface InstanceMethodOracle {
 
-  static final String CANONICAL_FIELD = "canonicalJso";
+    /**
+     * For a given instance method and declared enclosing class (which must be a
+     * JSO subtype), find the class in which that method was originally
+     * declared. Methods declared on Object will return "java/lang/Object".
+     * Static methods will always return <code>declaredClass</code>.
+     * 
+     * @param declaredClass a descriptor of the static type of the qualifier
+     * @param signature the binary signature of the method
+     * @return the descriptor of the class in which that method was declared,
+     *         which will either be <code>declaredClass</code> or some
+     *         superclass
+     * @throws IllegalArgumentException if the method could not be found
+     */
+    String findOriginalDeclaringClass(String declaredClass, String signature);
+  }
 
-  static final boolean EXTRA_DEBUG_DATA = Boolean.getBoolean("gwt.dev.classDump");
+  /**
+   * Contains data about how SingleJsoImpl methods are to be dispatched.
+   */
+  public interface SingleJsoImplData {
+    /**
+     * Returns the method declarations that should be generated for a given
+     * mangled method name. {@link #getDeclarations} and
+     * {@link #getImplementations} maintain a pairwise mapping.
+     */
+    List<Method> getDeclarations(String mangledName);
+
+    /**
+     * Returns the implementations that the method declarations above should
+     * delegate to.{@link #getDeclarations} and {@link #getImplementations}
+     * maintain a pairwise mapping.
+     */
+    List<Method> getImplementations(String mangledName);
+
+    /**
+     * Returns all of the mangled method names for SingleJsoImpl methods.
+     */
+    SortedSet<String> getMangledNames();
+
+    /**
+     * Returns the internal names of all interface types implemented by JSOs.
+     */
+    Set<String> getSingleJsoIntfTypes();
+  }
 
   static final String JAVASCRIPTOBJECT_DESC = JsValueGlue.JSO_CLASS.replace(
       '.', '/');
 
-  static final String REFERENCE_FIELD = JsValueGlue.HOSTED_MODE_REFERENCE;
-
-  static final String REWRAP_METHOD = "$rewrap";
-
-  static final String SINGLE_JSO_IMPL_FIELD = "$singleJsoImpl";
-
-  static final String SINGLE_JSO_IMPL_CAST_METHOD = "cast$";
-
-  static final String SINGLE_JSO_IMPL_CAST_TO_OBJECT_METHOD = "castToObject$";
-
-  static final String SINGLE_JSO_IMPL_INSTANCEOF_METHOD = "instanceOf$";
-
-  static final String SINGLE_JSO_IMPL_SUPPORT_CLASS = SingleJsoImplSupport.class.getName().replace(
+  static final String JAVASCRIPTOBJECT_IMPL_DESC = JsValueGlue.JSO_IMPL_CLASS.replace(
       '.', '/');
 
-  static final int SYSTEM_CLASS_VERSION = Double.parseDouble(System.getProperty("java.class.version")) < Opcodes.V1_6
-      ? Opcodes.V1_5 : Opcodes.V1_6;
+  static final String REFERENCE_FIELD = JsValueGlue.HOSTED_MODE_REFERENCE;
 
-  private static String toInternalName(String jsoSubtype) {
+  static String addSyntheticThisParam(String owner, String methodDescriptor) {
+    return "(L" + owner + ";" + methodDescriptor.substring(1);
+  }
+
+  private static String toDescriptor(String jsoSubtype) {
     return jsoSubtype.replace('.', '/');
   }
 
   /**
-   * Passed into the rewriting visitors.
+   * An unmodifiable set of descriptors containing the implementation form of
+   * <code>JavaScriptObject</code> and all subclasses.
    */
-  private final RewriterOracle rewriterOracle;
+  private final Set<String> jsoImplDescs;
 
   /**
-   * Creates a new {@link HostedModeClassRewriter}.
-   * 
-   * @param typeOracle The TypeOracle for the GWT module that is being rewritten
+   * An unmodifiable set of descriptors containing the interface form of
+   * <code>JavaScriptObject</code> and all subclasses.
    */
-  public HostedModeClassRewriter(TypeOracle typeOracle) {
-    rewriterOracle = new RewriterOracle(typeOracle);
+  private final Set<String> jsoIntfDescs;
+
+  private final SingleJsoImplData jsoData;
+
+  /**
+   * Records the superclass of every JSO for generating empty JSO interfaces.
+   */
+  private final Map<String, List<String>> jsoSuperDescs;
+
+  /**
+   * Maps methods to the class in which they are declared.
+   */
+  private InstanceMethodOracle mapper;
+
+  /**
+   * Creates a new {@link HostedModeClassRewriter} for a specified set of
+   * subclasses of JavaScriptObject.
+   * 
+   * @param jsoSubtypes a set of binary type names representing JavaScriptObject
+   *          and all of its subtypes of
+   * @param mapper maps methods to the class in which they are declared
+   */
+  public HostedModeClassRewriter(Set<String> jsoSubtypes,
+      Map<String, List<String>> jsoSuperTypes, SingleJsoImplData jsoData,
+      InstanceMethodOracle mapper) {
+    Set<String> buildJsoIntfDescs = new HashSet<String>();
+    Set<String> buildJsoImplDescs = new HashSet<String>();
+    Map<String, List<String>> buildJsoSuperDescs = new HashMap<String, List<String>>();
+    for (String jsoSubtype : jsoSubtypes) {
+      String desc = toDescriptor(jsoSubtype);
+      buildJsoIntfDescs.add(desc);
+      buildJsoImplDescs.add(desc + "$");
+
+      List<String> superTypes = jsoSuperTypes.get(jsoSubtype);
+      assert (superTypes != null);
+      assert (superTypes.size() > 0);
+      for (ListIterator<String> i = superTypes.listIterator(); i.hasNext();) {
+        i.set(toDescriptor(i.next()));
+      }
+      buildJsoSuperDescs.put(desc, Collections.unmodifiableList(superTypes));
+    }
+
+    this.jsoIntfDescs = Collections.unmodifiableSet(buildJsoIntfDescs);
+    this.jsoImplDescs = Collections.unmodifiableSet(buildJsoImplDescs);
+    this.jsoSuperDescs = Collections.unmodifiableMap(buildJsoSuperDescs);
+    this.jsoData = jsoData;
+    this.mapper = mapper;
+  }
+
+  /**
+   * Returns <code>true</code> if the class is the implementation class for a
+   * JSO subtype.
+   */
+  public boolean isJsoImpl(String className) {
+    return jsoImplDescs.contains(toDescriptor(className));
+  }
+
+  /**
+   * Returns <code>true</code> if the class is the interface class for a JSO
+   * subtype.
+   */
+  public boolean isJsoIntf(String className) {
+    return jsoIntfDescs.contains(toDescriptor(className));
   }
 
   /**
    * Performs rewriting transformations on a class.
    * 
+   * @param typeOracle a typeOracle modeling the user classes
    * @param className the name of the class
    * @param classBytes the bytes of the class
    * @param anonymousClassMap a map between the anonymous class names of java
    *          compiler used to compile code and jdt. Emma-specific.
    */
-  public byte[] rewrite(String className, byte[] classBytes,
-      Map<String, String> anonymousClassMap) {
-    classBytes = maybeUpgradeBytecode(classBytes);
-    String desc = toInternalName(className);
+  public byte[] rewrite(TypeOracle typeOracle, String className,
+      byte[] classBytes, Map<String, String> anonymousClassMap) {
+    String desc = toDescriptor(className);
+    assert (!jsoIntfDescs.contains(desc));
 
     // The ASM model is to chain a bunch of visitors together.
     ClassWriter writer = new ClassWriter(0);
@@ -231,63 +227,49 @@
     // v = new CheckClassAdapter(v);
     // v = new TraceClassVisitor(v, new PrintWriter(System.out));
 
-    v = new WriteSingleJsoSupportCode(v, rewriterOracle);
+    v = new RewriteSingleJsoImplDispatches(v, typeOracle, jsoData);
 
-    v = new RewriteJsoCasts(v, rewriterOracle);
+    v = new RewriteRefsToJsoClasses(v, jsoIntfDescs, mapper);
 
-    v = new RewriteObjectComparisons(v, rewriterOracle);
-
-    if (rewriterOracle.isJsoOrSubtype(desc)) {
-      v = WriteJsoImpl.create(v, desc);
+    if (jsoImplDescs.contains(desc)) {
+      v = WriteJsoImpl.create(v, desc, jsoIntfDescs, mapper, jsoData);
     }
 
     v = new RewriteJsniMethods(v, anonymousClassMap);
 
-    if (SYSTEM_CLASS_VERSION < Opcodes.V1_6) {
+    if (Double.parseDouble(System.getProperty("java.class.version")) < Opcodes.V1_6) {
       v = new ForceClassVersion15(v);
     }
 
-    // We need EXPAND_FRAMES here for RewriteJsoCasts
-    new ClassReader(classBytes).accept(v, ClassReader.EXPAND_FRAMES);
+    new ClassReader(classBytes).accept(v, 0);
     return writer.toByteArray();
   }
 
-  /**
-   * Synthesize a class file that implements an interface's SingleJsoImpl
-   * adjunct type.
-   */
-  public byte[] writeSingleJsoImplAdjunct(String className) {
-    // Keep the synthetic class creation code next to where its consumed
-    return WriteSingleJsoSupportCode.writeSingleJsoImplAdjunct(className);
-  }
+  public byte[] writeJsoIntf(String className) {
+    String desc = toDescriptor(className);
+    assert (jsoIntfDescs.contains(desc));
+    assert (jsoSuperDescs.containsKey(desc));
+    List<String> superDescs = jsoSuperDescs.get(desc);
+    assert (superDescs != null);
+    assert (superDescs.size() > 0);
 
-  /**
-   * AnalyzerAdapter, and thus RewriteJsoCasts, requires StackFrameMap data
-   * which is new in version 50 (Java 1.6) bytecode. This method will only do
-   * work if the input bytecode is less than version 50. This would occur when
-   * running on Java 1.5 or if Emma support is enabled (since Emma is from
-   * 2005).
-   */
-  private byte[] maybeUpgradeBytecode(byte[] classBytes) {
-    // Major version is stored at offset 7 in the class file format
-    if (classBytes[7] < Opcodes.V1_6) {
-      // Get ASM to generate the stack frame data
-      ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
-      ClassVisitor v2 = cw;
+    // The ASM model is to chain a bunch of visitors together.
+    ClassWriter writer = new ClassWriter(0);
+    ClassVisitor v = writer;
 
-      // Upgrade to version 50 class format
-      v2 = new ClassAdapter(v2) {
-        @Override
-        public void visit(int version, int access, String name,
-            String signature, String superName, String[] interfaces) {
-          super.visit(Opcodes.V1_6, access, name, signature, superName,
-              interfaces);
-        }
-      };
+    // v = new CheckClassAdapter(v);
+    // v = new TraceClassVisitor(v, new PrintWriter(System.out));
 
-      new ClassReader(classBytes).accept(v2, 0);
-      classBytes = cw.toByteArray();
+    String[] interfaces;
+    // TODO(bov): something better than linear?
+    if (superDescs.contains("java/lang/Object")) {
+      interfaces = null;
+    } else {
+      interfaces = superDescs.toArray(new String[superDescs.size()]);
     }
-    return classBytes;
+    v.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC | Opcodes.ACC_INTERFACE, desc,
+        null, "java/lang/Object", interfaces);
+    v.visitEnd();
+    return writer.toByteArray();
   }
 }
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsoCasts.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsoCasts.java
deleted file mode 100644
index a3fe1ce..0000000
--- a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsoCasts.java
+++ /dev/null
@@ -1,617 +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.shell.rewrite;
-
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.CANONICAL_FIELD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.EXTRA_DEBUG_DATA;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.JAVASCRIPTOBJECT_DESC;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.REWRAP_METHOD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_ADJUNCT_SUFFIX;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_CAST_METHOD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_CAST_TO_OBJECT_METHOD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_INSTANCEOF_METHOD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_SUPPORT_CLASS;
-
-import com.google.gwt.dev.asm.Attribute;
-import com.google.gwt.dev.asm.ByteVector;
-import com.google.gwt.dev.asm.ClassAdapter;
-import com.google.gwt.dev.asm.ClassVisitor;
-import com.google.gwt.dev.asm.ClassWriter;
-import com.google.gwt.dev.asm.Label;
-import com.google.gwt.dev.asm.MethodVisitor;
-import com.google.gwt.dev.asm.Opcodes;
-import com.google.gwt.dev.asm.Type;
-import com.google.gwt.dev.asm.commons.AnalyzerAdapter;
-import com.google.gwt.dev.asm.commons.Method;
-import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.RewriterOracle;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Ensure that an appropriate JSO wrapper type or canonical JavaScriptObject is
- * used. Assignments to fields, locals, arrays, return statements, and method
- * parameters will be updated with the following rules:
- * <ul>
- * <li>Changing from one JSO type to another results in a replacement JSO
- * Wrapper type being placed on the stack</li>
- * <li>Referring to a JSO or a JSO subype as Object results in the canonical JSO
- * instance being placed on the stack</li>
- * <li>An invocation of <code>getClass()</code> on a JSO subtype results in
- * <code>JavaScriptObject.class</code> being placed on the stack.</li>
- * </ul>
- */
-class RewriteJsoCasts extends ClassAdapter {
-
-  /**
-   * Injects necessary casting logic.
-   */
-  private class MyMethodAdapter extends AnalyzerAdapter {
-    /*
-     * NOTE TO MAINTAINERS: It's tempting to sprinkle one-off cast-handling
-     * logic around this class. That way lies madness while trying to track down
-     * exactly how a particular bit of cast logic wound up in the bytecode.
-     * Instead, all casting logic should be routed through generateCast.
-     */
-
-    private final Map<Label, String> debugData = EXTRA_DEBUG_DATA
-        ? new LinkedHashMap<Label, String>() : null;
-    private final boolean returnNeedsCanonical;
-    private final Type returnType;
-
-    public MyMethodAdapter(int access, String name, String desc,
-        MethodVisitor mv) {
-      super(currentClass, access, name, desc, mv);
-
-      Method m = new Method(name, desc);
-      returnType = m.getReturnType();
-      returnNeedsCanonical = returnType.getSort() == Type.OBJECT
-          && rewriterOracle.jsoAssignmentRequiresCanonicalization(returnType.getInternalName());
-    }
-
-    @Override
-    public void visitEnd() {
-      if (EXTRA_DEBUG_DATA && !debugData.isEmpty()) {
-        /*
-         * When things go wrong in the field, users can enable rewritten
-         * class-file dumping and send us the class files. Most of the other
-         * rewriting passes add whole classes or methods so their effects are
-         * easy to find. Since this rewriting pass is rather subtle, we'll add
-         * an extra method attribute that contains a UTF8-encoded diagnostic
-         * log.
-         */
-        Attribute attr = new Attribute("com.google.gwt.RewriteJsoCasts") {
-          @Override
-          protected Label[] getLabels() {
-            return debugData.keySet().toArray(new Label[debugData.size()]);
-          }
-
-          @Override
-          protected ByteVector write(ClassWriter cw, byte[] code, int len,
-              int maxStack, int maxLocals) {
-            StringBuilder sb = new StringBuilder();
-            for (Map.Entry<Label, String> entry : debugData.entrySet()) {
-              String line = "Offset " + entry.getKey().getOffset() + " : "
-                  + entry.getValue() + "\n";
-              sb.append(line);
-            }
-            ByteVector toReturn = new ByteVector();
-            toReturn.putUTF8(sb.toString());
-            return toReturn;
-          }
-        };
-        super.visitAttribute(attr);
-      }
-      super.visitEnd();
-    }
-
-    @Override
-    public void visitFieldInsn(int opcode, String owner, String name,
-        String desc) {
-      if (desc.charAt(0) == 'L' && !owner.equals(JAVASCRIPTOBJECT_DESC)
-          && !name.equals(CANONICAL_FIELD)) {
-        switch (opcode) {
-          case Opcodes.PUTFIELD:
-          case Opcodes.PUTSTATIC:
-            generateCast(desc.substring(1, desc.length() - 1));
-        }
-      }
-      super.visitFieldInsn(opcode, owner, name, desc);
-    }
-
-    /**
-     * Possibly canonicalize returned values.
-     */
-    @Override
-    public void visitInsn(int opcode) {
-      if (opcode == Opcodes.ARETURN && returnNeedsCanonical) {
-        // Stack is: returnValue
-        generateCast(returnType.getInternalName());
-        // Stack is: canonical
-      } else if (opcode == Opcodes.AASTORE) {
-        // Stack is: ..., arrayRef, index, value
-        Object topType = stack.get(stack.size() - 1);
-        if (topType instanceof String) {
-          String objectType = (String) topType;
-          String arrayType = (String) stack.get(stack.size() - 3);
-          Type t = Type.getObjectType(arrayType);
-          if (t.getDimensions() == 1
-              && rewriterOracle.jsoAssignmentRequiresCanonicalization(objectType)) {
-            /*
-             * If the object being assigned needs canonicalization, then we want
-             * to ensure the canonical object is being stored in the array.
-             */
-            generateCast(objectType);
-          }
-        }
-      }
-      super.visitInsn(opcode);
-    }
-
-    /**
-     * Replace references to JSO subtype class literals with references to
-     * JavaScriptObject.
-     */
-    @Override
-    public void visitLdcInsn(Object cst) {
-      if (cst instanceof Type) {
-        Type upcast = upcastJsoType((Type) cst);
-        if (upcast != null) {
-          cst = upcast;
-        }
-      }
-      super.visitLdcInsn(cst);
-    }
-
-    /**
-     * Canonicalize the arguments to methods that require Object or
-     * JavaScriptObject as parameters. Additional local variables will be
-     * allocated to save as many of the arguments as necessary in order to cast
-     * the first parameter that requires canonicalization.
-     */
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name,
-        String desc) {
-
-      // Update calls to getClass()
-      if ("getClass".equals(name) && "()Ljava/lang/Class;".equals(desc)) {
-        // Stack is: instance
-        Type t = Type.getObjectType((String) stack.get(stack.size() - 1));
-        if (t.getSort() == Type.OBJECT
-            && rewriterOracle.couldContainJso(t.getInternalName())) {
-          /*
-           * Make sure the canonical object is on the stack. This method call
-           * will pass nulls straight through, so the getClass() invocation will
-           * still trigger an NPE.
-           */
-          super.visitMethodInsn(Opcodes.INVOKESTATIC,
-              SINGLE_JSO_IMPL_SUPPORT_CLASS, "ensureCanonical",
-              "(Ljava/lang/Object;)Ljava/lang/Object;");
-          // Stack is: canonical object
-          super.visitMethodInsn(opcode, "java/lang/Object", name, desc);
-          // Stack is: classLit
-          return;
-
-        } else if (t.getSort() == Type.ARRAY
-            && t.getElementType().getSort() == Type.OBJECT
-            && rewriterOracle.isJsoOrSubtype(t.getElementType().getInternalName())) {
-          // Call the method to throw an NPE if necessary
-          super.visitMethodInsn(opcode, "java/lang/Object", name, desc);
-          // Stack is: classLit
-          super.visitInsn(Opcodes.POP);
-          // Stack is: <empty>
-          super.visitLdcInsn(upcastJsoType(t));
-          // Stack is: classLit
-          return;
-        }
-      } else if ("cast".equals(name)
-          && ("()L" + JAVASCRIPTOBJECT_DESC + ";").equals(desc)
-          && rewriterOracle.isJsoOrSubtype(owner)) {
-        // Remove calls to cast, since they trigger NPEs in older code
-        return;
-      }
-
-      /*
-       * We want to ensure that all arguments passed into the method have been
-       * canonicalized. To do this, we'll find the first argument on the stack
-       * that requires canonicalization. Each argument on above the first
-       * argument on the stack will be stored in a temporary local variable and
-       * eventually restored.
-       * 
-       * Assume the stack looks like this:
-       * 
-       * instance, Ok, NeedsCanonicalization, Ok, Ok, NeedsCanonicalization
-       * 
-       * (1) We'll store the top three arguments in locals until we have this:
-       * 
-       * instance, Ok, NeedsCanonicalization
-       * 
-       * (2) Then, we'll apply whatever canonicalization is necessary to the
-       * top-most element:
-       * 
-       * instance, Ok, Canonicalized
-       * 
-       * (3) The arguments stored in the temporary local variables will be
-       * pushed back onto the stack, possibly canonicalizing them in the
-       * process:
-       * 
-       * instance, Ok, Canonicalized, Ok, Ok, Canonicalized
-       * 
-       * This could be accomplished without the use of local variables if we
-       * were to track the last opcode that pushes an argument value onto the
-       * stack and buffer intervening opcodes or use a two-pass approach. Once
-       * the relevant opcode has been identified, the canonicalization logic
-       * could be immediately inserted.
-       */
-      Method m = new Method(name, desc);
-      Type[] args = m.getArgumentTypes();
-      int firstCast = -1;
-      boolean[] needsCanonicalization = new boolean[args.length];
-
-      // (1) Works backwards, since the last argument is on top of the stack
-      for (int i = args.length - 1, s = stack.size(); i >= 0; i--) {
-        Type arg = args[i];
-        s -= arg.getSize();
-
-        // Ignore arguments that never require a canonicalizing cast
-        if (arg.getSort() != Type.OBJECT
-            || !rewriterOracle.jsoAssignmentRequiresCanonicalization(arg.getInternalName())) {
-          continue;
-        }
-
-        Object onStack = stack.get(s);
-        assert !onStack.equals(Opcodes.TOP) : "Bad offset computation";
-
-        if (onStack instanceof String) {
-          String stackType = (String) onStack;
-          if (rewriterOracle.couldContainJso(stackType)) {
-            needsCanonicalization[i] = true;
-            firstCast = i;
-          }
-        }
-      }
-
-      // Short-circuit if none of the arguments need canonicalization
-      if (firstCast >= 0) {
-        // These labels are used to provide information to the debugger
-        Label castStackStart = new Label();
-        Label castStackEnd = new Label();
-
-        // (1) Pop N - 1 arguments off of the stack, storing them in locals
-        super.visitLabel(castStackStart);
-        @SuppressWarnings("unchecked")
-        List<Object> originalLocals = new ArrayList<Object>(locals);
-        int[] slots = new int[args.length];
-        for (int i = args.length - 1; i >= firstCast + 1; i--) {
-          Type arg = args[i];
-          int slot = locals.size();
-          slots[i] = slot;
-          super.visitVarInsn(arg.getOpcode(Opcodes.ISTORE), slot);
-        }
-
-        // (2) Convert the first argument
-        generateCast(args[firstCast].getInternalName());
-
-        // (3) Load arguments, converting those that need them
-        for (int i = firstCast + 1; i < args.length; i++) {
-          Type arg = args[i];
-          int slot = slots[i];
-          super.visitVarInsn(arg.getOpcode(Opcodes.ILOAD), slot);
-          if (needsCanonicalization[i]) {
-            generateCast(arg.getInternalName());
-          }
-        }
-
-        super.visitLabel(castStackEnd);
-
-        // Record locals to aid debbuging and manual inspection of bytecode.
-        for (int i = firstCast + 1; i < args.length; i++) {
-          super.visitLocalVariable("$cast_" + i, args[i].getDescriptor(), null,
-              castStackStart, castStackEnd, slots[i]);
-        }
-
-        // Record new stack / locals size
-        super.visitMaxs(stack.size(), locals.size());
-
-        /*
-         * Reset the local variables as though they were declared inside of a
-         * scoped block in the middle of a method.
-         */
-        @SuppressWarnings("unchecked")
-        Object[] stackArray = stack.toArray(new Object[stack.size()]);
-        super.visitFrame(Opcodes.F_NEW, originalLocals.size(),
-            originalLocals.toArray(new Object[originalLocals.size()]),
-            stack.size(), stackArray);
-      }
-
-      // Call the method
-      super.visitMethodInsn(opcode, owner, name, desc);
-    }
-
-    /**
-     * Rewrite casts and instanceof tests.
-     */
-    @Override
-    public void visitTypeInsn(int opcode, String type) {
-      Type parsed = Type.getObjectType(type);
-      switch (opcode) {
-        case Opcodes.CHECKCAST:
-          if (rewriterOracle.couldContainJso(type)) {
-            // Maybe generate casting code for JSO types
-            if (generateCast(type)) {
-              return;
-            }
-          } else if (parsed.getSort() == Type.ARRAY) {
-            // Always upcast JSO array types
-            Type t = upcastJsoType(parsed);
-            if (t != null) {
-              type = t.getInternalName();
-            }
-          }
-          // Intentional fall-through to super invocation below
-          break;
-
-        case Opcodes.INSTANCEOF: {
-          if (rewriterOracle.isInterface(parsed.getInternalName())
-              && rewriterOracle.couldContainJso(parsed.getInternalName())) {
-            /*
-             * We need to use the interface's adjunct type if the interface
-             * could contain a JSO type.
-             */
-            super.visitMethodInsn(Opcodes.INVOKESTATIC, type
-                + SINGLE_JSO_IMPL_ADJUNCT_SUFFIX,
-                SINGLE_JSO_IMPL_INSTANCEOF_METHOD, "(Ljava/lang/Object;)Z");
-            return;
-          }
-          // Always try to upcast instanceof JSO tests
-          Type t = upcastJsoType(parsed);
-          if (t != null) {
-            type = t.getInternalName();
-          }
-          break;
-        }
-      }
-      super.visitTypeInsn(opcode, type);
-    }
-
-    /**
-     * The do-everything method for determining how to make whatever is on top
-     * of the stack fit correctly in a slot of the given type. Casts to Object
-     * should result in the canonical object winding up on the stack. Otherwise,
-     * we may need a new wrapper instance.
-     * <p>
-     * This method should generate code that is stack-neutral. Any non-trivial
-     * cast logic should be moved to a support class, either
-     * {@link SingleJsoImplSupport} or the synthetic interface adjunct classes.
-     * 
-     * @param internalName the type to which the object on top of the stack
-     *          should be assigned
-     * @return <code>true</code> if cast code was generated
-     */
-    private boolean generateCast(String internalName) {
-      assert internalName.charAt(0) != 'L'
-          && internalName.charAt(internalName.length() - 1) != ';' : "Passed "
-          + "a descriptor instead of an internal name: " + internalName;
-      Object topStack = stack.get(stack.size() - 1);
-      if (!(topStack instanceof String)) {
-        return false;
-      }
-
-      final String topType = (String) topStack;
-
-      if (EXTRA_DEBUG_DATA) {
-        Label castLocation = new Label();
-        debugData.put(castLocation, topType + "  ->  " + internalName);
-        super.visitLabel(castLocation);
-      }
-
-      if (internalName.equals("java/lang/Object")) {
-        /*
-         * We're looking at code (probably created by one of our other visitors)
-         * that is casting a value to java.lang.Object.
-         */
-        // Stack is: something
-
-        if (rewriterOracle.isJsoOrSubtype(topType)) {
-          /*
-           * We know that the top of the stack is a wrapper type, so we need to
-           * canonicalize it by calling JavaScriptObject's synthetic rewrap
-           * method.
-           */
-          // Stack is: jsoSubtype
-          super.visitMethodInsn(Opcodes.INVOKESTATIC, JAVASCRIPTOBJECT_DESC,
-              REWRAP_METHOD, "(L" + JAVASCRIPTOBJECT_DESC + ";)L"
-                  + JAVASCRIPTOBJECT_DESC + ";");
-          // Stack is: canonicalObject
-          return true;
-
-        } else if (rewriterOracle.isInterface(topType)
-            && rewriterOracle.couldContainJso(topType)) {
-          /*
-           * We're looking at an interface that may contain a JSO. If the object
-           * is a JSO, replace it with the canonical instance by calling into
-           * the interface's SingleJsoImpl adjunct class's castToObject()
-           * method.
-           */
-          String supportType = topType + SINGLE_JSO_IMPL_ADJUNCT_SUFFIX;
-
-          // Stack is: interfaceType
-          super.visitMethodInsn(Opcodes.INVOKESTATIC, supportType,
-              SINGLE_JSO_IMPL_CAST_TO_OBJECT_METHOD, "(L" + topType
-                  + ";)Ljava/lang/Object;");
-          // Stack is: object (possible canonical JSO)
-          return true;
-
-        } else if ("java/lang/Object".equals(topType)) {
-          /*
-           * This is a situation that we'll run into when dealing with JRE code.
-           * See JsoTest.testArrayJreInteractions for the canonical example of
-           * loss of type information.
-           */
-          super.visitMethodInsn(Opcodes.INVOKESTATIC,
-              SINGLE_JSO_IMPL_SUPPORT_CLASS, "ensureCanonical",
-              "(Ljava/lang/Object;)Ljava/lang/Object;");
-          // Stack is: canonical object
-          return true;
-
-        } else {
-          // Casting some non-JSO type to Object
-          return false;
-        }
-
-      } else if (internalName.equals(topType)) {
-        // Casting an object to its own type
-        return false;
-
-      } else if (!rewriterOracle.couldContainJso(internalName)) {
-        // It's a cast to something that could never contain a JSO
-        return false;
-
-      } else if (rewriterOracle.isInterface(internalName)
-          && rewriterOracle.couldContainJso(internalName)) {
-        /*
-         * Casting to a SingleJsoImpl interface. Need to use the SingleJsoImpl
-         * adjunct to possibly create a new wrapper type.
-         */
-
-        // Stack is: something
-        super.visitMethodInsn(Opcodes.INVOKESTATIC, internalName
-            + SINGLE_JSO_IMPL_ADJUNCT_SUFFIX, SINGLE_JSO_IMPL_CAST_METHOD,
-            "(Ljava/lang/Object;)Ljava/lang/Object;");
-        // Stack is: something (maybe JSO wrapper type)
-        super.visitTypeInsn(Opcodes.CHECKCAST, internalName);
-        // Stack is: desiredType (maybe JSO wrapper type)
-
-        return true;
-
-      } else if (rewriterOracle.isJsoOrSubtype(internalName)) {
-        /*
-         * Casting to a JavaScriptObject subtype.
-         */
-
-        /*
-         * Change the cast to JavaScriptObject to ensure we get a
-         * ClassCastException for something like (JsoSubclass) "foo".
-         */
-        // Stack is: something
-        super.visitTypeInsn(Opcodes.CHECKCAST, JAVASCRIPTOBJECT_DESC);
-        // Stack is: jso
-
-        /*
-         * Put the canonical object onto the stack by calling
-         * JsoSubclass.$rewrap().
-         */
-        super.visitMethodInsn(Opcodes.INVOKESTATIC, internalName,
-            REWRAP_METHOD, "(L" + JAVASCRIPTOBJECT_DESC + ";)L" + internalName
-                + ";");
-        // Stack is: wrapperObject
-        return true;
-      }
-
-      /*
-       * Fail definitively, since getting this wrong is going to break the user
-       * in all kinds of unpredictable ways.
-       */
-      throw new RuntimeException(
-          "generateCast was called with an unhandled configuration. topType: "
-              + topType + " internalName: " + internalName);
-    }
-
-    /**
-     * If <code>type</code> is a JSO subtype or JSO subtype array, return the
-     * JSO type or JSO array type to which <code>type</code> can be assigned, or
-     * <code>null</code>.
-     */
-    private Type upcastJsoType(Type type) {
-      StringBuilder sb = new StringBuilder();
-      if (type.getSort() == Type.ARRAY) {
-        Type elementType = type.getElementType();
-        if (elementType.getSort() != Type.OBJECT
-            || !rewriterOracle.isJsoOrSubtype(elementType.getInternalName())) {
-          return null;
-        }
-        for (int i = 0, j = type.getDimensions(); i < j; i++) {
-          sb.append("[");
-        }
-      } else if (type.getSort() == Type.OBJECT) {
-        if (type.getInternalName().equals(JAVASCRIPTOBJECT_DESC)
-            || !rewriterOracle.isJsoOrSubtype(type.getInternalName())) {
-          return null;
-        }
-      } else {
-        return null;
-      }
-      sb.append("L" + JAVASCRIPTOBJECT_DESC + ";");
-      return Type.getType(sb.toString());
-    }
-  }
-
-  /**
-   * Decodes the UTF8-as-octets output from javap.
-   */
-  public static void main(String args[]) throws IOException {
-    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
-    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-    Pattern p = Pattern.compile("[0-9A-F]{2}");
-    String line;
-    while ((line = reader.readLine()) != null) {
-      if (line.length() > 0) {
-        Matcher m = p.matcher(line);
-        while (m.find()) {
-          bytes.write(Byte.parseByte(m.group(), 16));
-        }
-      } else {
-        String message = new String(bytes.toByteArray());
-        System.out.println(message);
-        bytes = new ByteArrayOutputStream();
-      }
-    }
-  }
-
-  private String currentClass;
-  private final RewriterOracle rewriterOracle;
-
-  public RewriteJsoCasts(ClassVisitor v, RewriterOracle rewriterOracle) {
-    super(v);
-    this.rewriterOracle = rewriterOracle;
-  }
-
-  @Override
-  public void visit(int version, int access, String name, String signature,
-      String superName, String[] interfaces) {
-    currentClass = name;
-    super.visit(version, access, name, signature, superName, interfaces);
-  }
-
-  @Override
-  public MethodVisitor visitMethod(int access, String name, String desc,
-      String signature, String[] exceptions) {
-    MethodVisitor mv = super.visitMethod(access, name, desc, signature,
-        exceptions);
-    if (mv != null && !REWRAP_METHOD.equals(name)) {
-      mv = new MyMethodAdapter(access, name, desc, mv);
-    }
-    return mv;
-  }
-}
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteObjectComparisons.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteObjectComparisons.java
deleted file mode 100644
index f7d2377..0000000
--- a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteObjectComparisons.java
+++ /dev/null
@@ -1,108 +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.shell.rewrite;
-
-import com.google.gwt.dev.asm.ClassAdapter;
-import com.google.gwt.dev.asm.ClassVisitor;
-import com.google.gwt.dev.asm.Label;
-import com.google.gwt.dev.asm.MethodVisitor;
-import com.google.gwt.dev.asm.Opcodes;
-import com.google.gwt.dev.asm.commons.AnalyzerAdapter;
-import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.RewriterOracle;
-
-/**
- * This injects artificial casts to Object which will be replaced by
- * {@link RewriteJsoCasts}.
- */
-class RewriteObjectComparisons extends ClassAdapter {
-
-  private class MyMethodAdapter extends AnalyzerAdapter {
-    public MyMethodAdapter(String owner, int access, String name, String desc,
-        MethodVisitor mv) {
-      super(owner, access, name, desc, mv);
-    }
-
-    /**
-     * All object equality comparisons in the JVM are performed via a jump
-     * opcode. Even something as simple as <code>boolean x = a == b;</code> is
-     * implemented as
-     * 
-     * <pre>
-     * ALOAD 1;
-     * ALOAD 2;
-     * IF_ACMPEQ label;
-     * PUSH false;
-     * GOTO: done;
-     * label: PUSH true;
-     * done: ASTORE 3;
-     * </pre>
-     */
-    @Override
-    public void visitJumpInsn(int opcode, Label label) {
-      switch (opcode) {
-        case Opcodes.IF_ACMPEQ:
-        case Opcodes.IF_ACMPNE:
-          Object type1 = stack.get(stack.size() - 2);
-          boolean jso1 = type1 instanceof String
-              && rewriterOracle.couldContainJso((String) type1);
-          Object type2 = stack.get(stack.size() - 1);
-          boolean jso2 = type2 instanceof String
-              && rewriterOracle.couldContainJso((String) type2);
-
-          if (jso1 || jso2) {
-            if (jso2) {
-              // Stack: something, something
-              super.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Object");
-            }
-            if (jso1) {
-              // Stack: something, object2
-              super.visitInsn(Opcodes.SWAP);
-              // Stack: object2, something
-              super.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Object");
-              // Stack: object2, object1
-            }
-          }
-      }
-      super.visitJumpInsn(opcode, label);
-    }
-  }
-
-  private final RewriterOracle rewriterOracle;
-  private String currentClass;
-
-  public RewriteObjectComparisons(ClassVisitor v, RewriterOracle rewriterOracle) {
-    super(v);
-    this.rewriterOracle = rewriterOracle;
-  }
-
-  @Override
-  public void visit(int version, int access, String name, String signature,
-      String superName, String[] interfaces) {
-    currentClass = name;
-    super.visit(version, access, name, signature, superName, interfaces);
-  }
-
-  @Override
-  public MethodVisitor visitMethod(int access, String name, String desc,
-      String signature, String[] exceptions) {
-    MethodVisitor mv = super.visitMethod(access, name, desc, signature,
-        exceptions);
-    if (mv != null) {
-      mv = new MyMethodAdapter(currentClass, access, name, desc, mv);
-    }
-    return mv;
-  }
-}
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteRefsToJsoClasses.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteRefsToJsoClasses.java
new file mode 100644
index 0000000..3a45363
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteRefsToJsoClasses.java
@@ -0,0 +1,150 @@
+/*
+ * 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.shell.rewrite;
+
+import com.google.gwt.dev.asm.ClassAdapter;
+import com.google.gwt.dev.asm.ClassVisitor;
+import com.google.gwt.dev.asm.MethodAdapter;
+import com.google.gwt.dev.asm.MethodVisitor;
+import com.google.gwt.dev.asm.Opcodes;
+import com.google.gwt.dev.asm.commons.Remapper;
+import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.InstanceMethodOracle;
+
+import java.util.Set;
+
+/**
+ * Rewrites references to modified JSO subtypes.
+ * 
+ * <ol>
+ * <li>Changes the owner type for instructions that reference items in a JSO
+ * class to the implementation class.</li>
+ * <li>Rewrites instance calls to JSO classes into static calls.</li>
+ * <li>Updates the descriptor for such call sites to includes a synthetic
+ * <code>this</code> parameter. This modified method has same stack behavior
+ * as the original instance method.</li>
+ * </ol>
+ */
+class RewriteRefsToJsoClasses extends ClassAdapter {
+
+  /**
+   * A method body rewriter to actually rewrite call sites.
+   */
+  private class MyMethodAdapter extends MethodAdapter {
+
+    private Remapper remapper = new Remapper() {
+      @Override
+      public String map(String typeName) {
+        if (jsoDescriptors.contains(typeName)) {
+          return HostedModeClassRewriter.JAVASCRIPTOBJECT_IMPL_DESC;
+        }
+        return typeName;
+      }
+    };
+
+    public MyMethodAdapter(MethodVisitor mv) {
+      super(mv);
+    }
+
+    @Override
+    public void visitFieldInsn(int opcode, String owner, String name,
+        String desc) {
+      if (jsoDescriptors.contains(owner)) {
+        // Change the owner to the rewritten class.
+        owner += "$";
+      }
+      super.visitFieldInsn(opcode, owner, name, desc);
+    }
+
+    @Override
+    public void visitLdcInsn(Object cst) {
+      cst = remapper.mapValue(cst);
+      super.visitLdcInsn(cst);
+    }
+
+    @Override
+    public void visitMethodInsn(int opcode, String owner, String name,
+        String desc) {
+      if (jsoDescriptors.contains(owner)) {
+        // Find the class that actually declared the method.
+        if (opcode == Opcodes.INVOKEVIRTUAL) {
+          owner = mapper.findOriginalDeclaringClass(owner, name + desc);
+        }
+        if (!owner.equals("java/lang/Object")) {
+          if (opcode == Opcodes.INVOKEVIRTUAL
+              || opcode == Opcodes.INVOKESPECIAL) {
+            // Instance/super call to JSO; rewrite as static.
+            opcode = Opcodes.INVOKESTATIC;
+            desc = HostedModeClassRewriter.addSyntheticThisParam(owner, desc);
+            name += "$";
+          }
+          // Change the owner to implementation class.
+          owner += "$";
+        }
+      }
+      super.visitMethodInsn(opcode, owner, name, desc);
+    }
+
+    @Override
+    public void visitMultiANewArrayInsn(String desc, int dims) {
+      desc = remapper.mapType(desc);
+      super.visitMultiANewArrayInsn(desc, dims);
+    }
+
+    @Override
+    public void visitTypeInsn(int opcode, String type) {
+      if (opcode == Opcodes.ANEWARRAY) {
+        type = remapper.mapType(type);
+      }
+      super.visitTypeInsn(opcode, type);
+    }
+  }
+
+  /**
+   * An unmodifiable set of descriptors containing <code>JavaScriptObject</code>
+   * and all subclasses.
+   */
+  protected final Set<String> jsoDescriptors;
+
+  /**
+   * Maps methods to the class in which they are declared.
+   */
+  private InstanceMethodOracle mapper;
+
+  /**
+   * Construct a new rewriter instance.
+   * 
+   * @param cv the visitor to chain to
+   * @param jsoDescriptors an unmodifiable set of descriptors containing
+   *          <code>JavaScriptObject</code> and all subclasses
+   * @param mapper maps methods to the class in which they are declared
+   */
+  public RewriteRefsToJsoClasses(ClassVisitor cv, Set<String> jsoDescriptors,
+      InstanceMethodOracle mapper) {
+    super(cv);
+    this.jsoDescriptors = jsoDescriptors;
+    this.mapper = mapper;
+  }
+
+  @Override
+  public MethodVisitor visitMethod(int access, String name, String desc,
+      String signature, String[] exceptions) {
+    // Wrap the returned method visitor in my own.
+    MethodVisitor mv = super.visitMethod(access, name, desc, signature,
+        exceptions);
+    return new MyMethodAdapter(mv);
+  }
+
+}
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteSingleJsoImplDispatches.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteSingleJsoImplDispatches.java
new file mode 100644
index 0000000..b6c7c1e
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteSingleJsoImplDispatches.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2009 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.shell.rewrite;
+
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.dev.asm.ClassAdapter;
+import com.google.gwt.dev.asm.ClassVisitor;
+import com.google.gwt.dev.asm.MethodAdapter;
+import com.google.gwt.dev.asm.MethodVisitor;
+import com.google.gwt.dev.asm.Opcodes;
+import com.google.gwt.dev.asm.Type;
+import com.google.gwt.dev.asm.commons.Method;
+import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SingleJsoImplData;
+import com.google.gwt.dev.util.collect.Maps;
+import com.google.gwt.dev.util.collect.Sets;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * Effects the renaming of {@code @SingleJsoImpl} methods from their original
+ * name to their mangled name. Let us call the original method an "unmangled
+ * method" and the new method a "mangled method". There are three steps in this
+ * process:
+ * <ol>
+ * <li>Within {@code @SingleJsoImpl} interfaces rename all unmangled methods to
+ * become mangled methods.</li>
+ * <li>Within non-JSO classes containing a concrete implementation of an
+ * unmangled method, add a mangled method which is implemented as a simple
+ * trampoline to the unmangled method. (We don't do this in JSO classes here
+ * because the one-and-only trampoline lives in JavaScriptObject$ and is emitted
+ * in {@link WriteJsoImpl}).
+ * <li>Update all call sites targeting unmangled methods to target mangled
+ * methods instead, provided the caller is binding to the interface rather than
+ * a concrete type.</li>
+ * </ol>
+ */
+public class RewriteSingleJsoImplDispatches extends ClassAdapter {
+  private class MyMethodVisitor extends MethodAdapter {
+    public MyMethodVisitor(MethodVisitor mv) {
+      super(mv);
+    }
+
+    /*
+     * Implements objective #3: updates call sites to unmangled methods.
+     */
+    @Override
+    public void visitMethodInsn(int opcode, String owner, String name,
+        String desc) {
+      if (opcode == Opcodes.INVOKEINTERFACE) {
+        if (jsoData.getSingleJsoIntfTypes().contains(owner)) {
+          // Simple case; referring directly to a SingleJso interface.
+          name = owner.replace('/', '_') + "_" + name;
+          assert jsoData.getMangledNames().contains(name) : "Missing " + name;
+
+        } else {
+          /*
+           * Might be referring to a subtype of a SingleJso interface:
+           * 
+           * interface IA { void foo() }
+           * 
+           * interface JA extends JSO implements IA;
+           * 
+           * interface IB extends IA {}
+           * 
+           * void bar() { ((IB) object).foo(); }
+           */
+          outer : for (String intf : computeAllInterfaces(owner)) {
+            if (jsoData.getSingleJsoIntfTypes().contains(intf)) {
+              /*
+               * Check that it really should be mangled and is not a reference
+               * to a method defined in a non-singleJso super-interface. If
+               * there are two super-interfaces that define methods with
+               * identical names and descriptors, the choice of implementation
+               * is undefined.
+               */
+              String maybeMangled = intf.replace('/', '_') + "_" + name;
+              List<Method> methods = jsoData.getImplementations(maybeMangled);
+              if (methods != null) {
+                for (Method method : methods) {
+                  /*
+                   * Found a method with the right name, but we need to check
+                   * the parameters and the return type. In order to do this,
+                   * we'll look at the arguments and return type of the target
+                   * method, removing the first argument, which is the instance.
+                   */
+                  assert method.getArgumentTypes().length >= 1;
+                  Type[] argumentTypes = new Type[method.getArgumentTypes().length - 1];
+                  System.arraycopy(method.getArgumentTypes(), 1, argumentTypes,
+                      0, argumentTypes.length);
+                  String maybeDescriptor = Type.getMethodDescriptor(
+                      method.getReturnType(), argumentTypes);
+                  if (maybeDescriptor.equals(desc)) {
+                    name = maybeMangled;
+                    break outer;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      super.visitMethodInsn(opcode, owner, name, desc);
+    }
+  }
+
+  private String currentTypeName;
+  private final Set<String> implementedMethods = new HashSet<String>();
+  private boolean inSingleJsoImplInterfaceType;
+  private Map<String, Set<String>> intfNamesToAllInterfaces = Maps.create();
+  private final SingleJsoImplData jsoData;
+  private final TypeOracle typeOracle;
+
+  public RewriteSingleJsoImplDispatches(ClassVisitor v, TypeOracle typeOracle,
+      SingleJsoImplData jsoData) {
+    super(v);
+    this.typeOracle = typeOracle;
+    this.jsoData = jsoData;
+  }
+
+  @Override
+  public void visit(int version, int access, String name, String signature,
+      String superName, String[] interfaces) {
+    assert currentTypeName == null;
+    super.visit(version, access, name, signature, superName, interfaces);
+
+    /*
+     * This visitor would mangle JSO$ since it acts as a roll-up of all
+     * SingleJso types and the result would be repeated method definitions due
+     * to the trampoline methods this visitor would create.
+     */
+    if (name.equals(HostedModeClassRewriter.JAVASCRIPTOBJECT_IMPL_DESC)) {
+      return;
+    }
+
+    currentTypeName = name;
+    inSingleJsoImplInterfaceType = jsoData.getSingleJsoIntfTypes().contains(
+        name);
+
+    /*
+     * Implements objective #2: non-JSO types that implement a SingleJsoImpl
+     * interface don't have their original instance methods altered. Instead, we
+     * add trampoline methods with mangled names that simply call over to the
+     * original methods.
+     */
+    if (interfaces != null && (access & Opcodes.ACC_INTERFACE) == 0) {
+      Set<String> toStub = computeAllInterfaces(interfaces);
+      toStub.retainAll(jsoData.getSingleJsoIntfTypes());
+
+      for (String stubIntr : toStub) {
+        writeTrampoline(stubIntr);
+      }
+    }
+  }
+
+  @Override
+  public void visitEnd() {
+    /*
+     * Add any missing methods that are defined by a super-interface, but that
+     * may be referenced via a more specific interface.
+     */
+    if (inSingleJsoImplInterfaceType) {
+      for (Map.Entry<String, List<Method>> entry : toImplement(currentTypeName).entrySet()) {
+        for (Method method : entry.getValue()) {
+          writeEmptyMethod(entry.getKey(), method);
+        }
+      }
+    }
+    super.visitEnd();
+  }
+
+  @Override
+  public MethodVisitor visitMethod(int access, String name, String desc,
+      String signature, String[] exceptions) {
+
+    /*
+     * Implements objective #2: Rename unmangled methods in a @SingleJsoImpl
+     * into mangled methods (except for clinit, LOL).
+     */
+    if (inSingleJsoImplInterfaceType && !"<clinit>".equals(name)) {
+      name = currentTypeName.replace('/', '_') + "_" + name;
+      implementedMethods.add(name);
+    }
+
+    MethodVisitor mv = super.visitMethod(access, name, desc, signature,
+        exceptions);
+    if (mv == null) {
+      return null;
+    }
+
+    return new MyMethodVisitor(mv);
+  }
+
+  private Set<String> computeAllInterfaces(String intfName) {
+    Set<String> toReturn = intfNamesToAllInterfaces.get(intfName);
+    if (toReturn != null) {
+      return toReturn;
+    }
+
+    toReturn = Sets.create();
+    List<JClassType> q = new LinkedList<JClassType>();
+    JClassType intf = typeOracle.findType(intfName.replace('/', '.').replace(
+        '$', '.'));
+    assert intf != null : "Could not find interface " + intfName;
+    q.add(intf);
+
+    while (!q.isEmpty()) {
+      intf = q.remove(0);
+      String resourceName = getResourceName(intf);
+      if (!toReturn.contains(resourceName)) {
+        toReturn = Sets.add(toReturn, resourceName);
+        Collections.addAll(q, intf.getImplementedInterfaces());
+      }
+    }
+
+    intfNamesToAllInterfaces = Maps.put(intfNamesToAllInterfaces, intfName,
+        toReturn);
+    return toReturn;
+  }
+
+  private Set<String> computeAllInterfaces(String[] interfaces) {
+    Set<String> toReturn = new HashSet<String>();
+    for (String intfName : interfaces) {
+      toReturn.addAll(computeAllInterfaces(intfName));
+    }
+    return toReturn;
+  }
+
+  private String getResourceName(JClassType type) {
+    if (type.getEnclosingType() != null) {
+      return getResourceName(type.getEnclosingType()) + "$"
+          + type.getSimpleSourceName();
+    }
+    return type.getQualifiedSourceName().replace('.', '/');
+  }
+
+  /**
+   * Given a resource name of a class, find all mangled method names that must
+   * be implemented.
+   */
+  private SortedMap<String, List<Method>> toImplement(String typeName) {
+    String name = typeName.replace('/', '_');
+    String prefix = name + "_";
+    String suffix = name + "`";
+    SortedMap<String, List<Method>> toReturn = new TreeMap<String, List<Method>>();
+
+    for (String mangledName : jsoData.getMangledNames().subSet(prefix, suffix)) {
+      toReturn.put(mangledName, jsoData.getImplementations(mangledName));
+    }
+    toReturn.keySet().removeAll(implementedMethods);
+    return toReturn;
+  }
+
+  private void writeEmptyMethod(String mangledMethodName, Method method) {
+    assert method.getArgumentTypes().length > 0;
+    // Remove the first argument, which would be the implementing JSO type
+    String descriptor = "("
+        + method.getDescriptor().substring(
+            1 + method.getArgumentTypes()[0].getDescriptor().length());
+
+    // Create the stub method entry in the interface
+    MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC
+        | Opcodes.ACC_ABSTRACT, mangledMethodName, descriptor, null, null);
+    mv.visitEnd();
+  }
+
+  /**
+   * For regular Java objects that implement a SingleJsoImpl interface, write
+   * instance trampoline dispatchers for mangled method names to the
+   * implementing method.
+   */
+  private void writeTrampoline(String stubIntr) {
+    /*
+     * This is almost the same kind of trampoline as the ones generated in
+     * WriteJsoImpl, however there are enough small differences between the
+     * semantics of the dispatches that would make a common implementation far
+     * more awkward than the duplication of code.
+     */
+    for (Map.Entry<String, List<Method>> entry : toImplement(stubIntr).entrySet()) {
+      for (Method method : entry.getValue()) {
+        String mangledName = entry.getKey();
+
+        String descriptor = "("
+            + method.getDescriptor().substring(
+                1 + method.getArgumentTypes()[0].getDescriptor().length());
+        String localName = method.getName().substring(0,
+            method.getName().length() - 1);
+        Method toCall = new Method(localName, descriptor);
+
+        // Must not be final
+        MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC
+            | Opcodes.ACC_SYNTHETIC, mangledName, descriptor, null, null);
+        if (mv != null) {
+          mv.visitCode();
+
+          /*
+           * It just so happens that the stack and local variable sizes are the
+           * same, but they're kept distinct to aid in clarity should the
+           * dispatch logic change.
+           * 
+           * These start at 1 because we need to load "this" onto the stack
+           */
+          int var = 1;
+          int size = 1;
+
+          // load this
+          mv.visitVarInsn(Opcodes.ALOAD, 0);
+
+          // then the rest of the arguments
+          for (Type t : toCall.getArgumentTypes()) {
+            size += t.getSize();
+            mv.visitVarInsn(t.getOpcode(Opcodes.ILOAD), var);
+            var += t.getSize();
+          }
+
+          // Make sure there's enough room for the return value
+          size = Math.max(size, toCall.getReturnType().getSize());
+
+          mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, currentTypeName,
+              toCall.getName(), toCall.getDescriptor());
+          mv.visitInsn(toCall.getReturnType().getOpcode(Opcodes.IRETURN));
+          mv.visitMaxs(size, var);
+          mv.visitEnd();
+        }
+      }
+    }
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/SingleJsoImplSupport.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/SingleJsoImplSupport.java
deleted file mode 100644
index 9c0b794..0000000
--- a/dev/core/src/com/google/gwt/dev/shell/rewrite/SingleJsoImplSupport.java
+++ /dev/null
@@ -1,252 +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.shell.rewrite;
-
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.REWRAP_METHOD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_ADJUNCT_SUFFIX;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_FIELD;
-
-import com.google.gwt.dev.shell.JsValueGlue;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Utility methods that are called by code generated by
- * {@link WriteSingleJsoSupportCode}.
- */
-public class SingleJsoImplSupport {
-
-  /**
-   * Stash a reference to the JavaScriptObject Class object.
-   */
-  private static final ThreadLocal<Class<?>> JSO_CLASS_OBJECT = new ThreadLocal<Class<?>>();
-
-  /**
-   * Called from JsValueGlue to ensure that a JSO instance can be cast to the
-   * desired type. If the desired type is a regular JSO subclass, this is a
-   * simple rewrap call. Otherwise, assume that it's a SingleJsoImpl interface
-   * type and use {@link #cast(Object, Class, Class)}.
-   */
-  public static Object cast(Object o, Class<?> jsoOrIntfType) {
-    assert o != null : "o is null";
-    assert jsoOrIntfType != Object.class : "Not expecting Object";
-
-    if (jsoOrIntfType.isInterface()) {
-      // Casting to an interface type
-      Class<?> targetJsoType = getTargetJsoType(jsoOrIntfType);
-
-      checkTarget(jsoOrIntfType, targetJsoType);
-
-      // Let the no-implementing-type code in cast(3) handle the error
-      return rewrap(targetJsoType, o);
-    }
-
-    if (getJsoClass(o).isAssignableFrom(jsoOrIntfType)) {
-      // A JSO type
-      return rewrap(jsoOrIntfType, o);
-    }
-
-    // Something else, let the call-site hit CCE
-    return o;
-  }
-
-  /**
-   * Called by synthetic code to cast an object <code>o</code> to some concrete
-   * type that implements the interface <code>intfType</code>. If a
-   * JavaScriptObject subtype has been loaded that implements the interface,
-   * that type will be provided in <code>targetJsoType</code>.
-   * 
-   * @return an object that implements <code>intfType</code>
-   * @throws ClassCastException if <code>o</code> is a JSO subtype and there is
-   *           no SingleJsoImpl type for <code>intfType</code>
-   */
-  public static Object cast(Object o, Class<?> intfType, Class<?> targetJsoType) {
-    if (o == null || intfType.isInstance(o) || !getJsoClass(o).isInstance(o)) {
-      // Let class cast exception happen at callsite
-      return o;
-    }
-
-    checkTarget(intfType, targetJsoType);
-
-    return rewrap(targetJsoType, o);
-  }
-
-  public static Object ensureCanonical(Object o) {
-    if (o == null) {
-      return null;
-    }
-
-    if (getJsoClass(o).isInstance(o)) {
-      return rewrap(getJsoClass(o), o);
-    }
-
-    return o;
-  }
-
-  /**
-   * Returns the JSO implementation type declared on the interface via a
-   * SingleJsoImpl annotation.
-   */
-  @SuppressWarnings("unchecked")
-  public static Class<?> getDeclaredSingleJsoImplType(Class<?> intfType) {
-    Exception ex;
-    try {
-      Class singleJsoImplType = intfType.getClassLoader().loadClass(
-          "com.google.gwt.core.client.SingleJsoImpl");
-      Object annotation = intfType.getAnnotation(singleJsoImplType);
-      if (annotation != null) {
-        Method m = singleJsoImplType.getMethod("value");
-        Class<?> value = (Class<?>) m.invoke(annotation);
-        return value;
-      }
-
-      // Try the by-name annotation
-      singleJsoImplType = intfType.getClassLoader().loadClass(
-          "com.google.gwt.core.client.SingleJsoImplName");
-      annotation = intfType.getAnnotation(singleJsoImplType);
-      if (annotation != null) {
-        Method m = singleJsoImplType.getMethod("value");
-        String name = (String) m.invoke(annotation);
-
-        return Class.forName(name, true, intfType.getClassLoader());
-      }
-
-      return null;
-    } catch (ClassNotFoundException e) {
-      ex = e;
-    } catch (IllegalArgumentException e) {
-      ex = e;
-    } catch (IllegalAccessException e) {
-      ex = e;
-    } catch (InvocationTargetException e) {
-      ex = e;
-    } catch (SecurityException e) {
-      ex = e;
-    } catch (NoSuchMethodException e) {
-      ex = e;
-    }
-    throw new RuntimeException("Unable to determine SingleJsoImpl type", ex);
-  }
-
-  /**
-   * Called by synthetic code to implement instanceof tests.
-   * 
-   * @param o the object to test
-   * @param intf the interface type that <code>o</code> is being tested against
-   * @param implJsoType the JavaScriptObject subtype that implements
-   *          <code>intf</code> if it has been loaded
-   * @return <code>true</code> if <code>o</code> implements <code>intf</code> or
-   *         if <code>o</code> is a JSO and some JSO type that implements
-   *         <code>intf</code> has been loaded
-   */
-  public static boolean instanceOf(Object o, Class<?> intf, Class<?> implJsoType) {
-    return intf.isInstance(o)
-        || (implJsoType != null && getJsoClass(o).isInstance(o));
-  }
-
-  /**
-   * Throw a specialized ClassCastException if <code>targetJsoType</code> is
-   * null.
-   */
-  private static void checkTarget(Class<?> intfType, Class<?> targetJsoType) {
-    if (targetJsoType == null) {
-      throw new ClassCastException(
-          "There is no known JavaScriptObject subtype that implements "
-              + intfType.getCanonicalName()
-              + ". Fix by adding an @SingleJsoImpl annotation to "
-              + intfType.getSimpleName()
-              + " or by referencing the concrete JSO type.");
-    }
-  }
-
-  /**
-   * Load the JavaScriptObject Class object from a client object's isolated
-   * ClassLoader.
-   */
-  private static Class<?> getJsoClass(Object jso) {
-    Class<?> toReturn = JSO_CLASS_OBJECT.get();
-    if (toReturn != null) {
-      return toReturn;
-    }
-    try {
-      toReturn = jso.getClass().getClassLoader().loadClass(
-          JsValueGlue.JSO_CLASS);
-    } catch (ClassNotFoundException e) {
-      throw new RuntimeException("No JavaScriptObject class", e);
-    }
-    JSO_CLASS_OBJECT.set(toReturn);
-    return toReturn;
-  }
-
-  private static Class<?> getTargetJsoType(Class<?> intfType) {
-    Field f;
-    Exception ex;
-    try {
-      intfType = intfType.getClassLoader().loadClass(
-          intfType.getName() + SINGLE_JSO_IMPL_ADJUNCT_SUFFIX);
-      f = intfType.getField(SINGLE_JSO_IMPL_FIELD);
-      return (Class<?>) f.get(null);
-    } catch (SecurityException e) {
-      ex = e;
-    } catch (NoSuchFieldException e) {
-      ex = e;
-    } catch (IllegalArgumentException e) {
-      ex = e;
-    } catch (IllegalAccessException e) {
-      ex = e;
-    } catch (ClassNotFoundException e) {
-      ex = e;
-    }
-    throw new RuntimeException("Unable to query singleJsoImpl type", ex);
-  }
-
-  /**
-   * Reflectively invoke a JSO subtype's rewrap method to create a new wrapper
-   * instance for a JavaScriptObject.
-   * 
-   * @param jsoClass the desired wrapper type
-   * @param jso a JavaScriptObject
-   * @return a JavaScriptObject wrapper that encloses <code>jso</code>'s
-   *         canonical JSO identity
-   */
-  private static Object rewrap(Class<?> jsoClass, Object jso) {
-    Method m;
-    Exception ex;
-    try {
-      m = jsoClass.getMethod(REWRAP_METHOD, getJsoClass(jsoClass));
-      return m.invoke(null, jso);
-    } catch (NoSuchMethodException e) {
-      throw new RuntimeException("Missing expected synthetic method", e);
-    } catch (SecurityException e) {
-      ex = e;
-    } catch (IllegalArgumentException e) {
-      ex = e;
-    } catch (IllegalAccessException e) {
-      ex = e;
-    } catch (InvocationTargetException e) {
-      ex = e;
-    }
-    throw new RuntimeException(ex);
-  }
-
-  /**
-   * Utility class.
-   */
-  private SingleJsoImplSupport() {
-  }
-}
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/WriteJsoImpl.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/WriteJsoImpl.java
index 92acc1b..4eafd89 100644
--- a/dev/core/src/com/google/gwt/dev/shell/rewrite/WriteJsoImpl.java
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/WriteJsoImpl.java
@@ -15,79 +15,94 @@
  */
 package com.google.gwt.dev.shell.rewrite;
 
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.CANONICAL_FIELD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.JAVASCRIPTOBJECT_DESC;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.REFERENCE_FIELD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.REWRAP_METHOD;
-
 import com.google.gwt.dev.asm.ClassAdapter;
 import com.google.gwt.dev.asm.ClassVisitor;
 import com.google.gwt.dev.asm.FieldVisitor;
-import com.google.gwt.dev.asm.Label;
 import com.google.gwt.dev.asm.MethodVisitor;
 import com.google.gwt.dev.asm.Opcodes;
+import com.google.gwt.dev.asm.Type;
+import com.google.gwt.dev.asm.commons.Method;
+import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.InstanceMethodOracle;
+import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SingleJsoImplData;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
 
 /**
  * Writes the implementation classes for JSO and its subtypes.
+ * 
+ * Changes made by the base class:
+ * <ol>
+ * <li>The new type has the same name as the old type with a '$' appended.</li>
+ * <li>All instance methods in the original type become static methods taking an
+ * explicit <code>this</code> parameter. Such methods have the same stack
+ * behavior as the original.</li>
+ * </ol>
  */
-class WriteJsoImpl {
+abstract class WriteJsoImpl extends ClassAdapter {
 
   /**
    * This type implements JavaScriptObject.
    * 
-   * <ul>
+   * <ol>
    * <li>JavaScriptObject itself gets a new synthetic field to store the
    * underlying hosted mode reference.</li>
-   * <li>It also receives a field to retain the canonical JavaScriptObject when
-   * creating wrapper subclasses.</li>
-   * <li>A rewrap method is added that simply returns the input object's
-   * canonical object.</li>
-   * <li>The zero-arg constructor is made public and makes the JavaScriptObject
-   * its own canonical object.</li>
-   * <li>A one-arg constructor is added for use by subclasses that copies the
-   * hosted mode reference and canonical identity object.</li>
-   * </ul>
+   * <li>Instance methods are added so that JavaScriptObject implements all
+   * SingleJsoImpl interfaces.</li>
+   * </ol>
    * 
    */
-  private static class ForJso extends ClassAdapter {
-    public ForJso(ClassVisitor cv) {
-      super(cv);
+  private static class ForJsoDollar extends WriteJsoImpl {
+    /**
+     * An unmodifiable set of descriptors containing
+     * <code>JavaScriptObject</code> and all subclasses.
+     */
+    private final Set<String> jsoDescriptors;
+    private final SingleJsoImplData jsoData;
+
+    public ForJsoDollar(ClassVisitor cv, Set<String> jsoDescriptors,
+        InstanceMethodOracle mapper, SingleJsoImplData jsoData) {
+      super(cv, mapper);
+      this.jsoDescriptors = jsoDescriptors;
+      this.jsoData = jsoData;
     }
 
     @Override
     public void visit(int version, int access, String name, String signature,
         String superName, String[] interfaces) {
 
-      super.visit(version, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
-          | Opcodes.ACC_SYNTHETIC, name, signature, superName, interfaces);
+      ArrayList<String> jsoDescList = new ArrayList<String>();
+      jsoDescList.addAll(jsoDescriptors);
+      interfaces = jsoDescList.toArray(new String[jsoDescList.size()]);
 
-      // Generate JavaScriptObject.rewrap$()
-      MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC
-          | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, REWRAP_METHOD, "(L"
-          + JAVASCRIPTOBJECT_DESC + ";)L" + name + ";", null, null);
-      if (mv != null) {
-        writeRewrapMethod(mv);
-      }
+      super.visit(version, access, name, signature, superName, interfaces);
 
       /*
        * Generate the synthetic "hostedModeReferece" field to contain the
        * underlying real reference to the JavaScript object.
        */
-      FieldVisitor fv = visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC
-          | Opcodes.ACC_FINAL, REFERENCE_FIELD, "Ljava/lang/Object;", null,
+      FieldVisitor fv = visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC,
+          HostedModeClassRewriter.REFERENCE_FIELD, "Ljava/lang/Object;", null,
           null);
       if (fv != null) {
         fv.visitEnd();
       }
 
-      /*
-       * Generate a synthetic "canonical" field.
-       */
-      fv = visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC
-          | Opcodes.ACC_FINAL, CANONICAL_FIELD, "L" + JAVASCRIPTOBJECT_DESC
-          + ";", null, null);
-      if (fv != null) {
-        fv.visitEnd();
+      // Implement the trampoline methods
+      for (String mangledName : jsoData.getMangledNames()) {
+        List<Method> declarations = jsoData.getDeclarations(mangledName);
+        List<Method> implementations = jsoData.getImplementations(mangledName);
+        assert declarations.size() == implementations.size() : "Declaration / implementation size mismatch";
+
+        Iterator<Method> declIterator = declarations.iterator();
+        Iterator<Method> implIterator = implementations.iterator();
+
+        while (declIterator.hasNext()) {
+          assert implIterator.hasNext();
+          writeTrampoline(mangledName, declIterator.next(), implIterator.next());
+        }
       }
     }
 
@@ -95,364 +110,123 @@
     public MethodVisitor visitMethod(int access, String name, String desc,
         String signature, String[] exceptions) {
       if (isCtor(name)) {
-        writeConstructors(name);
-        return null;
-      } else if ("equals".equals(name) && "(Ljava/lang/Object;)Z".equals(desc)) {
-        writeEquals(access, name, desc, signature, exceptions);
-        return null;
+        // make the JavaScriptObject$ constructor public
+        access &= ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED);
+        access |= Opcodes.ACC_PUBLIC;
       }
       return super.visitMethod(access, name, desc, signature, exceptions);
     }
 
     /**
-     * Generates a method to return the canonical object.
+     * JSO methods are implemented as flyweight style, with the instance being
+     * passed as the first parameter. This loop create instance methods on JSO$
+     * for all of the mangled SingleJsoImpl interface method names. These
+     * instance methods simply turn around and call the static-dispatch methods.
+     * In Java, it might look like:
      * 
      * <pre>
-     * public JavaScriptObject rewrap$(JavaScriptObject o) {
-     *   if (o == null) {
-     *     return null;
+     * interface Interface {
+     *   String someMethod(int a, double b);
+     * }
+     * 
+     * class J extends JSO implements I {
+     *   public String com_google_Interface_someMethod(int a, double b) {
+     *     return com.google.MyJso$.someMethod$(this, a, b);
      *   }
-     *   return o.canonical;
      * }
      * </pre>
-     */
-    protected void writeRewrapMethod(MethodVisitor mv) {
-      Label start = new Label();
-      Label end = new Label();
-
-      mv.visitCode();
-      mv.visitLabel(start);
-
-      mv.visitVarInsn(Opcodes.ALOAD, 0);
-      // Stack is: jso
-      mv.visitInsn(Opcodes.DUP);
-      // Stack is: jso, jso
-
-      Label ret = new Label();
-      mv.visitJumpInsn(Opcodes.IFNULL, ret);
-      // Stack is: jso
-
-      mv.visitFieldInsn(Opcodes.GETFIELD, JAVASCRIPTOBJECT_DESC,
-          CANONICAL_FIELD, "L" + JAVASCRIPTOBJECT_DESC + ";");
-      // Stack is: canonical
-
-      mv.visitLabel(ret);
-      mv.visitFrame(Opcodes.F_NEW, 1, new Object[] {JAVASCRIPTOBJECT_DESC}, 1,
-          new Object[] {JAVASCRIPTOBJECT_DESC});
-      mv.visitInsn(Opcodes.ARETURN);
-
-      mv.visitMaxs(2, 1);
-      mv.visitLabel(end);
-      mv.visitLocalVariable("jso", "L" + JAVASCRIPTOBJECT_DESC + ";", null,
-          start, end, 0);
-      mv.visitEnd();
-    }
-
-    /**
-     * Write JavaScriptObject's constructors.
      * 
-     * <pre>
-     * public JavaScriptObject(Object hostedModeReference) {
-     *   this.canonical = this;
-     *   this.hostedModeReference = hostedModeReference;
-     * }
-     * protected JavaScriptObject(JavaScriptObject jso) {
-     *   this.canonical = jso.canonical;
-     *   this.hostedModeReference = jso.hostedModeReference;
-     * }
-     * </pre>
+     * @param mangledName {@code com_google_gwt_sample_hello_client_Interface_a}
+     * @param interfaceMethod {@code java.lang.String a(int, double)}
+     * @param implementingMethod {@code static final java.lang.String
+     *          a$(com.google.gwt.sample.hello.client.Jso, ...);}
      */
-    private void writeConstructors(String name) {
-      // Write the zero-arg constructor
-      MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC
-          | Opcodes.ACC_SYNTHETIC, name, "(Ljava/lang/Object;)V", null, null);
+    private void writeTrampoline(String mangledName, Method interfaceMethod,
+        Method implementingMethod) {
+      assert implementingMethod.getArgumentTypes().length > 0;
+
+      /*
+       * The local descriptor is the same as the descriptor from the abstract
+       * method in the interface.
+       */
+      String localDescriptor = interfaceMethod.getDescriptor();
+      Method localMethod = new Method(mangledName, localDescriptor);
+
+      /*
+       * We also use the first argument to know which type to statically
+       * dispatch to.
+       */
+      Type implementingType = Type.getType("L"
+          + implementingMethod.getArgumentTypes()[0].getInternalName() + "$;");
+
+      // Maybe create the method. This is marked final as a sanity check
+      MethodVisitor mv = visitMethodNoRewrite(Opcodes.ACC_PUBLIC
+          | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC, localMethod.getName(),
+          localMethod.getDescriptor(), null, null);
+
       if (mv != null) {
         mv.visitCode();
-        // Call Object's constructor
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitInsn(Opcodes.DUP);
-        // Stack: this, this
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
-            "()V");
-        // Stack: this
 
-        // this.canonical = this;
-        mv.visitInsn(Opcodes.DUP);
-        mv.visitInsn(Opcodes.DUP);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        // Stack: this, this, this, hostedModeReference
-        mv.visitFieldInsn(Opcodes.PUTFIELD, JAVASCRIPTOBJECT_DESC,
-            REFERENCE_FIELD, "Ljava/lang/Object;");
-        // Stack: this, this
-        mv.visitFieldInsn(Opcodes.PUTFIELD, JAVASCRIPTOBJECT_DESC,
-            CANONICAL_FIELD, "L" + JAVASCRIPTOBJECT_DESC + ";");
-        // Stack: <empty>
+        /*
+         * It just so happens that the stack and local variable sizes are the
+         * same, but they're kept distinct to aid in clarity should the dispatch
+         * logic change.
+         */
+        int var = 0;
+        int size = 0;
 
-        mv.visitInsn(Opcodes.RETURN);
-        mv.visitMaxs(4, 2);
+        for (Type t : implementingMethod.getArgumentTypes()) {
+          size += t.getSize();
+          mv.visitVarInsn(t.getOpcode(Opcodes.ILOAD), var);
+          var += t.getSize();
+        }
+
+        // Make sure there's enough room for the return value
+        size = Math.max(size, implementingMethod.getReturnType().getSize());
+
+        mv.visitMethodInsn(Opcodes.INVOKESTATIC,
+            implementingType.getInternalName(), implementingMethod.getName(),
+            implementingMethod.getDescriptor());
+        mv.visitInsn(localMethod.getReturnType().getOpcode(Opcodes.IRETURN));
+        mv.visitMaxs(size, var);
         mv.visitEnd();
       }
-
-      // Write the protected one-arg constructor
-      mv = super.visitMethod(Opcodes.ACC_PROTECTED | Opcodes.ACC_SYNTHETIC,
-          name, "(L" + JAVASCRIPTOBJECT_DESC + ";)V", null, null);
-      if (mv != null) {
-        Label start = new Label();
-        Label end = new Label();
-
-        // Call Object's constructor
-        mv.visitCode();
-        mv.visitLabel(start);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        // Stack: this
-        mv.visitInsn(Opcodes.DUP);
-        // Stack: this, this
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
-            "()V");
-        // Stack: this
-
-        // this.canonical = otherJso;
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        // Stack: this, otherJso
-        mv.visitInsn(Opcodes.DUP2);
-        // Stack: this, otherJso, this, otherJso
-        mv.visitFieldInsn(Opcodes.GETFIELD, JAVASCRIPTOBJECT_DESC,
-            CANONICAL_FIELD, "L" + JAVASCRIPTOBJECT_DESC + ";");
-        // Stack: this, otherJso, this, canonical
-        mv.visitFieldInsn(Opcodes.PUTFIELD, JAVASCRIPTOBJECT_DESC,
-            CANONICAL_FIELD, "L" + JAVASCRIPTOBJECT_DESC + ";");
-        // Stack: this, otherJso
-
-        // this.hostedModeReference = otherJso.hostedModeReference
-        mv.visitFieldInsn(Opcodes.GETFIELD, JAVASCRIPTOBJECT_DESC,
-            REFERENCE_FIELD, "Ljava/lang/Object;");
-        // Stack: this, hostedModeReference
-        mv.visitFieldInsn(Opcodes.PUTFIELD, JAVASCRIPTOBJECT_DESC,
-            REFERENCE_FIELD, "Ljava/lang/Object;");
-        // Stack: <empty>
-
-        mv.visitInsn(Opcodes.RETURN);
-        mv.visitMaxs(4, 2);
-        mv.visitLabel(end);
-        mv.visitLocalVariable("this", "L" + JAVASCRIPTOBJECT_DESC + ";", null,
-            start, end, 0);
-        mv.visitLocalVariable("jso", "L" + JAVASCRIPTOBJECT_DESC + ";", null,
-            start, end, 1);
-        mv.visitEnd();
-      }
-    }
-
-    /**
-     * Write the implementation of JSO.equals() to use a regular object-identity
-     * comparison that can be rewritten further.
-     * 
-     * <pre>
-     * public boolean equals(Object other) {
-     *   return this == other;
-     * }
-     * </pre>
-     */
-    private void writeEquals(int access, String name, String desc,
-        String signature, String[] exceptions) {
-      MethodVisitor mv = super.visitMethod(access, name, desc, signature,
-          exceptions);
-      if (mv == null) {
-        return;
-      }
-      mv.visitCode();
-
-      Label returnTrue = new Label();
-      mv.visitVarInsn(Opcodes.ALOAD, 0);
-      mv.visitVarInsn(Opcodes.ALOAD, 1);
-      // Stack: this, other
-
-      mv.visitJumpInsn(Opcodes.IF_ACMPEQ, returnTrue);
-      mv.visitInsn(Opcodes.ICONST_0);
-      // Stack: 0
-      mv.visitInsn(Opcodes.IRETURN);
-
-      mv.visitLabel(returnTrue);
-      mv.visitFrame(Opcodes.F_NEW, 2, new Object[] {
-          JAVASCRIPTOBJECT_DESC, "java/lang/Object"}, 0, new Object[0]);
-      mv.visitInsn(Opcodes.ICONST_1);
-      // Stack: 1
-      mv.visitInsn(Opcodes.IRETURN);
-
-      mv.visitMaxs(2, 2);
-      mv.visitEnd();
     }
   }
 
   /**
    * This type is used to implement subtypes of JSO.
    * 
-   * <ul>
-   * <li>The type's zero-arg constructor is replaced with a one-arg copy
-   * constructor that delegates to the one-arg super-constructor.</li>
-   * <li>A static rewrap method is added</li>
-   * </ul>
+   * <ol>
+   * <li>The new type's superclass is mangled by adding $.</li>
+   * <li>Constructors are deleted.</li>
+   * </ol>
    */
-  private static class ForJsoSubclass extends ClassAdapter {
-    private String superName;
-    private String typeName;
-
-    public ForJsoSubclass(ClassVisitor cv) {
-      super(cv);
+  private static class ForJsoInterface extends WriteJsoImpl {
+    public ForJsoInterface(ClassVisitor cv, InstanceMethodOracle mapper) {
+      super(cv, mapper);
     }
 
     @Override
     public void visit(int version, int access, String name, String signature,
         String superName, String[] interfaces) {
-      this.superName = superName;
-      this.typeName = name;
-      super.visit(version, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
-          | Opcodes.ACC_SYNTHETIC, name, signature, superName, interfaces);
+      // Reference the old superclass's implementation class.
+      superName += '$';
+      interfaces = null;
 
-      // Generate JsoSubtype.rewrap$()
-      MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC
-          | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, REWRAP_METHOD, "(L"
-          + JAVASCRIPTOBJECT_DESC + ";)L" + name + ";", null, null);
-      if (mv != null) {
-        writeRewrapMethod(mv);
-      }
+      super.visit(version, access, name, signature, superName, interfaces);
     }
 
-    /**
-     * Rewrite the JSO's constructor.
-     * 
-     * <pre>
-     * protected SomeJso(JavaScriptObject other) {
-     *   super(other);
-     * }
-     * </pre>
-     */
     @Override
     public MethodVisitor visitMethod(int access, String name, String desc,
         String signature, String[] exceptions) {
       boolean isCtor = isCtor(name);
       if (isCtor) {
-        MethodVisitor mv = super.visitMethod(Opcodes.ACC_PROTECTED
-            | Opcodes.ACC_SYNTHETIC, name,
-            "(L" + JAVASCRIPTOBJECT_DESC + ";)V", null, null);
-        if (mv == null) {
-          return null;
-        }
-
-        Label start = new Label();
-        Label end = new Label();
-        mv.visitCode();
-        mv.visitLabel(start);
-        // super(otherJso)
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        // Stack: this
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        // Stack: this, other
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", "(L"
-            + JAVASCRIPTOBJECT_DESC + ";)V");
-        // Stack: <empty>
-        mv.visitInsn(Opcodes.RETURN);
-
-        mv.visitMaxs(2, 2);
-        mv.visitLabel(end);
-
-        // For debugging
-        mv.visitLocalVariable("this", "L" + typeName + ";", null, start, end, 0);
-        mv.visitLocalVariable("jso", "L" + JAVASCRIPTOBJECT_DESC + ";", null,
-            start, end, 1);
-        mv.visitEnd();
-
+        // Don't copy over constructors except for JavaScriptObject itself.
         return null;
       }
       return super.visitMethod(access, name, desc, signature, exceptions);
     }
-
-    /**
-     * Constructs a type-specific rewrap method.
-     * 
-     * <pre>
-     * public static JsoSubclass rewrap$(JavaScriptObject jso) {
-     *   start:
-     *   if (jso == null) {
-     *     topOfStack = null;
-     *     goto doReturn;
-     *   }
-     *   
-     *   notNull: if (jso instanceof JsoSubclass) {
-     *     topOfStack = (JsoSubclass) jso;
-     *     goto doReturn;
-     *   }
-     *   
-     *   notMySubclass: topOfStack = new JsoSubclass(jso);
-     *   
-     *   doReturn: return topOfStack;
-     *   end:
-     * }
-     * </pre>
-     */
-    protected void writeRewrapMethod(MethodVisitor mv) {
-      Label start = new Label();
-      Label notNull = new Label();
-      Label notMySubclass = new Label();
-      Label doReturn = new Label();
-      Label end = new Label();
-
-      mv.visitCode();
-      mv.visitLabel(start);
-      mv.visitVarInsn(Opcodes.ALOAD, 0);
-      mv.visitInsn(Opcodes.DUP);
-      // Stack is: jso, jso
-
-      mv.visitJumpInsn(Opcodes.IFNONNULL, notNull);
-      // Stack is: jso
-      // Push a null instead of using dup so that we don't need a useless cast
-      mv.visitInsn(Opcodes.POP);
-      mv.visitInsn(Opcodes.ACONST_NULL);
-      // Stack is: null
-      mv.visitJumpInsn(Opcodes.GOTO, doReturn);
-
-      mv.visitLabel(notNull);
-      mv.visitFrame(Opcodes.F_NEW, 1, new Object[] {JAVASCRIPTOBJECT_DESC}, 1,
-          new Object[] {JAVASCRIPTOBJECT_DESC});
-      mv.visitInsn(Opcodes.DUP);
-      // Stack is: jso, jso
-      mv.visitTypeInsn(Opcodes.INSTANCEOF, typeName);
-      // Stack is: jso, boolean
-      mv.visitJumpInsn(Opcodes.IFEQ, notMySubclass);
-      // Stack is: jso
-      mv.visitTypeInsn(Opcodes.CHECKCAST, typeName);
-      mv.visitJumpInsn(Opcodes.GOTO, doReturn);
-
-      mv.visitLabel(notMySubclass);
-      mv.visitFrame(Opcodes.F_NEW, 1, new Object[] {JAVASCRIPTOBJECT_DESC}, 1,
-          new Object[] {JAVASCRIPTOBJECT_DESC});
-      // Stack is: jso
-
-      // Allocate the new wrapper instance.
-      mv.visitTypeInsn(Opcodes.NEW, typeName);
-      // Stack is: jso, wrapper
-
-      mv.visitInsn(Opcodes.DUP_X1);
-      // Stack is: wrapper, jso, wrapper
-      mv.visitInsn(Opcodes.SWAP);
-      // Stack is: wrapper, wrapper, jso
-
-      // Invoke the constructor, which will access the canonical object
-      mv.visitMethodInsn(Opcodes.INVOKESPECIAL, typeName, "<init>", "(L"
-          + JAVASCRIPTOBJECT_DESC + ";)V");
-      // Stack is: wrapper
-
-      mv.visitLabel(doReturn);
-      mv.visitFrame(Opcodes.F_NEW, 1, new Object[] {JAVASCRIPTOBJECT_DESC}, 1,
-          new Object[] {JAVASCRIPTOBJECT_DESC});
-      // Stack is: toReturn
-      mv.visitInsn(Opcodes.ARETURN);
-
-      mv.visitLabel(end);
-      mv.visitMaxs(3, 1);
-      mv.visitLocalVariable("jso", "L" + JAVASCRIPTOBJECT_DESC + ";", null,
-          start, end, 0);
-      mv.visitEnd();
-    }
   }
 
   /**
@@ -460,21 +234,89 @@
    * select between a simple implementation for user-defined JSO subtypes and
    * the complex implementation for implementing JavaScriptObject$.
    */
-  public static ClassVisitor create(ClassVisitor cv, String classDescriptor) {
-    if (classDescriptor.equals(JAVASCRIPTOBJECT_DESC)) {
-      return new ForJso(cv);
+  public static ClassVisitor create(ClassVisitor cv, String classDescriptor,
+      Set<String> jsoDescriptors, InstanceMethodOracle mapper,
+      SingleJsoImplData singleJsoImplData) {
+
+    if (classDescriptor.equals(HostedModeClassRewriter.JAVASCRIPTOBJECT_IMPL_DESC)) {
+      return new ForJsoDollar(cv, jsoDescriptors, mapper, singleJsoImplData);
     } else {
-      return new ForJsoSubclass(cv);
+      return new ForJsoInterface(cv, mapper);
     }
   }
 
-  private static boolean isCtor(String name) {
-    return "<init>".equals(name);
+  /**
+   * Maps methods to the class in which they are declared.
+   */
+  private final InstanceMethodOracle mapper;
+
+  /**
+   * The original name of the class being visited.
+   */
+  private String originalName;
+
+  /**
+   * Construct a new rewriter instance.
+   * 
+   * @param cv the visitor to chain to
+   * @param jsoDescriptors an unmodifiable set of descriptors containing
+   *          <code>JavaScriptObject</code> and all subclasses
+   * @param mapper maps methods to the class in which they are declared
+   */
+  private WriteJsoImpl(ClassVisitor cv, InstanceMethodOracle mapper) {
+    super(cv);
+    this.mapper = mapper;
   }
 
   /**
-   * Utility class.
+   * Records the original name and resets access opcodes.
    */
-  private WriteJsoImpl() {
+  @Override
+  public void visit(int version, int access, String name, String signature,
+      String superName, String[] interfaces) {
+    originalName = name;
+    super.visit(version, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
+        | Opcodes.ACC_SYNTHETIC, name + '$', signature, superName, interfaces);
+  }
+
+  /**
+   * Mangle all instance methods declared in JavaScriptObject types.
+   */
+  @Override
+  public MethodVisitor visitMethod(int access, String name, String desc,
+      String signature, String[] exceptions) {
+    boolean isCtor = isCtor(name);
+    if (!isCtor && !isStatic(access) && !isObjectMethod(name + desc)) {
+      access |= Opcodes.ACC_STATIC;
+      desc = HostedModeClassRewriter.addSyntheticThisParam(getOriginalName(),
+          desc);
+      name = name + "$";
+    }
+    return super.visitMethod(access, name, desc, signature, exceptions);
+  }
+
+  protected String getOriginalName() {
+    return originalName;
+  }
+
+  protected boolean isCtor(String name) {
+    return "<init>".equals(name);
+  }
+
+  protected boolean isObjectMethod(String signature) {
+    return "java/lang/Object".equals(mapper.findOriginalDeclaringClass(
+        originalName, signature));
+  }
+
+  protected boolean isStatic(int access) {
+    return (access & Opcodes.ACC_STATIC) != 0;
+  }
+
+  /**
+   * Allows access to an unmodified visitMethod call.
+   */
+  protected MethodVisitor visitMethodNoRewrite(int access, String name,
+      String desc, String signature, String[] exceptions) {
+    return super.visitMethod(access, name, desc, signature, exceptions);
   }
 }
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/WriteSingleJsoSupportCode.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/WriteSingleJsoSupportCode.java
deleted file mode 100644
index 05532a3..0000000
--- a/dev/core/src/com/google/gwt/dev/shell/rewrite/WriteSingleJsoSupportCode.java
+++ /dev/null
@@ -1,424 +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.shell.rewrite;
-
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.JAVASCRIPTOBJECT_DESC;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.REWRAP_METHOD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_ADJUNCT_SUFFIX;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_CAST_METHOD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_CAST_TO_OBJECT_METHOD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_FIELD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_INSTANCEOF_METHOD;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SINGLE_JSO_IMPL_SUPPORT_CLASS;
-import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SYSTEM_CLASS_VERSION;
-
-import com.google.gwt.dev.asm.ClassAdapter;
-import com.google.gwt.dev.asm.ClassVisitor;
-import com.google.gwt.dev.asm.ClassWriter;
-import com.google.gwt.dev.asm.FieldVisitor;
-import com.google.gwt.dev.asm.Label;
-import com.google.gwt.dev.asm.MethodAdapter;
-import com.google.gwt.dev.asm.MethodVisitor;
-import com.google.gwt.dev.asm.Opcodes;
-import com.google.gwt.dev.asm.Type;
-import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.RewriterOracle;
-
-/**
- * Adds code to JavaScriptObject subtypes to register themselves as the
- * implementation type for a given interface. This class also contains a utility
- * method for generating an interface's adjunct type to support SingleJsoImpl
- * dispatch.
- */
-class WriteSingleJsoSupportCode extends ClassAdapter {
-  public static String SINGLE_JSO_IMPL_ASSIGNMENT_METHOD = "assignSingleJso$";
-
-  private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
-
-  /**
-   * Create an adjunct class for every interface type that a JavaScriptObject
-   * might implement. It will contain methods for assisting with casts and
-   * instanceof checks. Given the interface <code>IFoo</code> the following type
-   * will be generated:
-   * 
-   * <pre>
-   * class IFoo$singleJsoImpl {
-   * //Initialized by the JSO subtype
-   * public static Class jsoImplType;
-   * 
-   * static {
-   *   jsoImplType = SingleJsoImplSupport.getDeclaredSingleJsoImplType(IFoo.class)
-   * }
-   * 
-   * public static Object cast(Object o) {
-   *   return SingleJsoImplSupport.cast(o, IFoo.class, jsoImplType);
-   * }
-   *
-   * public static Object castToObject$(InterfaceType o) {
-   *   if (o instanceof JavaScriptObject) {
-   *     o = JavaScriptObject.rewrap$((JavaScriptObject o));
-   *   }
-   *   return o;
-   * }
-   * public static boolean instanceOf(Object o) {
-   *   return SingleJsoImplSupport.instanceOf(o, IFoo.class, jsoImplType);
-   * }
-   * }
-   * </pre>
-   */
-  static byte[] writeSingleJsoImplAdjunct(String className) {
-    assert className.endsWith(SINGLE_JSO_IMPL_ADJUNCT_SUFFIX) : "Bad className "
-        + className;
-    String internalName = toInternalName(className);
-    String intfName = internalName.substring(0, internalName.length()
-        - SINGLE_JSO_IMPL_ADJUNCT_SUFFIX.length());
-
-    ClassWriter writer = new ClassWriter(0);
-
-    writer.visit(SYSTEM_CLASS_VERSION, Opcodes.ACC_PUBLIC
-        | Opcodes.ACC_SYNTHETIC, internalName, null, "java/lang/Object", null);
-
-    // Create jsoImplType field
-    FieldVisitor fv = writer.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
-        | Opcodes.ACC_SYNTHETIC, SINGLE_JSO_IMPL_FIELD, "Ljava/lang/Class;",
-        null, null);
-    if (fv != null) {
-      fv.visitEnd();
-    }
-
-    // Write static initializer
-    MethodVisitor mv = writer.visitMethod(Opcodes.ACC_STATIC, "<clinit>",
-        "()V", null, null);
-    if (mv != null) {
-      mv.visitCode();
-      mv.visitLdcInsn(Type.getObjectType(intfName));
-      mv.visitMethodInsn(Opcodes.INVOKESTATIC, SINGLE_JSO_IMPL_SUPPORT_CLASS,
-          "getDeclaredSingleJsoImplType",
-          "(Ljava/lang/Class;)Ljava/lang/Class;");
-      mv.visitFieldInsn(Opcodes.PUTSTATIC, internalName, SINGLE_JSO_IMPL_FIELD,
-          "Ljava/lang/Class;");
-      mv.visitInsn(Opcodes.RETURN);
-      mv.visitMaxs(1, 0);
-      mv.visitEnd();
-    }
-
-    // Write cast method
-    mv = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
-        | Opcodes.ACC_SYNTHETIC, SINGLE_JSO_IMPL_CAST_METHOD,
-        "(Ljava/lang/Object;)Ljava/lang/Object;", null, null);
-    if (mv != null) {
-      Label start = new Label();
-      Label end = new Label();
-
-      mv.visitCode();
-      mv.visitLabel(start);
-      // Stack is: empty
-      mv.visitVarInsn(Opcodes.ALOAD, 0);
-      // Stack is: object
-      mv.visitLdcInsn(Type.getType("L" + intfName + ";"));
-      // Stack is: object, interfaceType
-      mv.visitFieldInsn(Opcodes.GETSTATIC, internalName, SINGLE_JSO_IMPL_FIELD,
-          "Ljava/lang/Class;");
-      // Stack is: object, interfaceType, jsoType (may be null)
-
-      mv.visitMethodInsn(Opcodes.INVOKESTATIC, SINGLE_JSO_IMPL_SUPPORT_CLASS,
-          "cast",
-          "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Object;");
-      // Stack is: object (maybe JSO wrapper)
-
-      mv.visitInsn(Opcodes.ARETURN);
-      mv.visitLabel(end);
-      mv.visitMaxs(3, 1);
-      mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, start, end, 0);
-      mv.visitEnd();
-    }
-
-    // Write castToObject method
-    mv = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
-        | Opcodes.ACC_SYNTHETIC, SINGLE_JSO_IMPL_CAST_TO_OBJECT_METHOD, "(L"
-        + intfName + ";)Ljava/lang/Object;", null, null);
-    if (mv != null) {
-      Label start = new Label();
-      Label beforeReturn = new Label();
-      Label end = new Label();
-
-      mv.visitCode();
-      mv.visitLabel(start);
-      // Stack is: empty
-      mv.visitVarInsn(Opcodes.ALOAD, 0);
-      // Stack is: object
-      mv.visitTypeInsn(Opcodes.INSTANCEOF, JAVASCRIPTOBJECT_DESC);
-      // Stack is: int
-      mv.visitJumpInsn(Opcodes.IFEQ, beforeReturn);
-      // Stack is: empty
-
-      mv.visitVarInsn(Opcodes.ALOAD, 0);
-      // Stack is: object
-      mv.visitTypeInsn(Opcodes.CHECKCAST, JAVASCRIPTOBJECT_DESC);
-      // Stack is: JSO
-      mv.visitMethodInsn(Opcodes.INVOKESTATIC, JAVASCRIPTOBJECT_DESC,
-          REWRAP_METHOD, "(L" + JAVASCRIPTOBJECT_DESC + ";)L"
-              + JAVASCRIPTOBJECT_DESC + ";");
-      // Stack is: canonical JSO
-      mv.visitVarInsn(Opcodes.ASTORE, 0);
-      // Stack is: empty (local 0 contains canonical object)
-
-      mv.visitLabel(beforeReturn);
-      mv.visitFrame(Opcodes.F_NEW, 1, new Object[] {"java/lang/Object"}, 0,
-          EMPTY_OBJECT_ARRAY);
-      mv.visitVarInsn(Opcodes.ALOAD, 0);
-      mv.visitInsn(Opcodes.ARETURN);
-      mv.visitLabel(end);
-      mv.visitMaxs(1, 1);
-      mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, start, end, 0);
-      mv.visitEnd();
-    }
-
-    // Write instanceOf method
-    mv = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
-        | Opcodes.ACC_SYNTHETIC, SINGLE_JSO_IMPL_INSTANCEOF_METHOD,
-        "(Ljava/lang/Object;)Z", null, null);
-    if (mv != null) {
-      Label start = new Label();
-      Label end = new Label();
-
-      mv.visitCode();
-      mv.visitLabel(start);
-      // Stack is: empty
-      mv.visitVarInsn(Opcodes.ALOAD, 0);
-      // Stack is: object
-      mv.visitLdcInsn(Type.getType("L" + intfName + ";"));
-      // Stack is: object, interfaceType
-      mv.visitFieldInsn(Opcodes.GETSTATIC, internalName, SINGLE_JSO_IMPL_FIELD,
-          "Ljava/lang/Class;");
-      // Stack is: object, interfaceType, jsoType (may be null)
-
-      mv.visitMethodInsn(Opcodes.INVOKESTATIC, SINGLE_JSO_IMPL_SUPPORT_CLASS,
-          "instanceOf",
-          "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;)Z");
-      // Stack is: boolean
-
-      mv.visitInsn(Opcodes.IRETURN);
-      mv.visitLabel(end);
-      mv.visitMaxs(3, 1);
-      mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, start, end, 0);
-      mv.visitEnd();
-    }
-
-    writer.visitEnd();
-    return writer.toByteArray();
-  }
-
-  private static String toInternalName(String jsoSubtype) {
-    return jsoSubtype.replace('.', '/');
-  }
-
-  private String className;
-  private boolean hasClinit;
-  private String[] interfaces;
-  private final RewriterOracle oracle;
-
-  public WriteSingleJsoSupportCode(ClassVisitor cv, RewriterOracle oracle) {
-    super(cv);
-    this.oracle = oracle;
-  }
-
-  @Override
-  public void visit(int version, int access, String name, String signature,
-      String superName, String[] interfaces) {
-    className = name;
-    if (oracle.isJsoOrSubtype(name)) {
-      this.interfaces = oracle.getAllSuperInterfaces(interfaces);
-    } else {
-      this.interfaces = null;
-    }
-    super.visit(version, access, name, signature, superName, interfaces);
-  }
-
-  /**
-   * Write the interface assignment code and possibly introduce a static
-   * initializer.
-   */
-  @Override
-  public void visitEnd() {
-    if (interfaces != null) {
-      writeSingleJsoImplAssignments();
-
-      if (!hasClinit) {
-        MethodVisitor mv = super.visitMethod(Opcodes.ACC_STATIC, "<clinit>",
-            "()V", null, null);
-        if (mv != null) {
-          mv.visitCode();
-          mv.visitFrame(Opcodes.F_NEW, 0, EMPTY_OBJECT_ARRAY, 0,
-              EMPTY_OBJECT_ARRAY);
-          mv.visitMethodInsn(Opcodes.INVOKESTATIC, className,
-              SINGLE_JSO_IMPL_ASSIGNMENT_METHOD, "()V");
-          mv.visitInsn(Opcodes.RETURN);
-          mv.visitEnd();
-        }
-      }
-    }
-
-    super.visitEnd();
-  }
-
-  /**
-   * Possibly update the existing static initializer to call the assignment
-   * code.
-   */
-  @Override
-  public MethodVisitor visitMethod(int access, String name, String desc,
-      String signature, String[] exceptions) {
-    if (interfaces != null && "<clinit>".equals(name)) {
-      // Disable code in visitEnd()
-      hasClinit = true;
-      MethodVisitor mv = super.visitMethod(access, name, desc, signature,
-          exceptions);
-
-      if (mv == null) {
-        return null;
-      }
-
-      return new MethodAdapter(mv) {
-        /**
-         * Write the call to the assignment method as the first code in the
-         * static initializer.
-         */
-        @Override
-        public void visitCode() {
-          super.visitCode();
-          mv.visitMethodInsn(Opcodes.INVOKESTATIC, className,
-              SINGLE_JSO_IMPL_ASSIGNMENT_METHOD, "()V");
-        }
-      };
-    }
-    return super.visitMethod(access, name, desc, signature, exceptions);
-  }
-
-  /**
-   * Generate code to register the JSO subtype as the implementation type for
-   * its interfaces. For every interface (and super-interface) implemented by
-   * the JSO type, we'll register the JSO type in the interfaces' adjunct types.
-   * <p>
-   * For tag interfaces:
-   * 
-   * <pre>
-   * if (IFoo$singleJsoImpl.singleJsoImpl$ == null) {
-   *   IFoo$singleJsoImpl.singleJsoImpl$ = JsoFoo.class;
-   * }
-   * </pre>
-   * </p>
-   * <p>
-   * For non-trivial interfaces, we check to see if any existing type is a
-   * supertype of this JSO:
-   * 
-   * <pre>
-   * if (IFoo$singleJsoImpl.singleJsoImpl$ == null) {
-   *   IFoo$singleJsoImpl.singleJsoImpl$ = JsoFoo.class;
-   * } else if (!IFoo$singleJsoImpl.singleJsoImpl$.isAssignableFrom(JsoFoo.class) {
-   *   throw new RuntimeException();
-   * }
-   * </pre>
-   * </p>
-   */
-  private void writeSingleJsoImplAssignments() {
-    MethodVisitor mv = super.visitMethod(Opcodes.ACC_PRIVATE
-        | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC,
-        SINGLE_JSO_IMPL_ASSIGNMENT_METHOD, "()V", null, null);
-    if (mv == null) {
-      return;
-    }
-
-    int stack = 0;
-    mv.visitCode();
-    mv.visitFrame(Opcodes.F_NEW, 0, EMPTY_OBJECT_ARRAY, 0, EMPTY_OBJECT_ARRAY);
-    for (String intf : interfaces) {
-
-      mv.visitFieldInsn(Opcodes.GETSTATIC, intf
-          + SINGLE_JSO_IMPL_ADJUNCT_SUFFIX, SINGLE_JSO_IMPL_FIELD,
-          "Ljava/lang/Class;");
-      // Stack is: classLit (may be null)
-
-      if (oracle.isTagInterface(intf)) {
-        Label noActionNeeded = new Label();
-        /*
-         * Multiple JSO types may implement tag interfaces, so we'll ignore any
-         * existing type.
-         */
-        mv.visitJumpInsn(Opcodes.IFNONNULL, noActionNeeded);
-        mv.visitLdcInsn(Type.getObjectType(className));
-        mv.visitFieldInsn(Opcodes.PUTSTATIC, intf
-            + SINGLE_JSO_IMPL_ADJUNCT_SUFFIX, SINGLE_JSO_IMPL_FIELD,
-            "Ljava/lang/Class;");
-        mv.visitLabel(noActionNeeded);
-        mv.visitFrame(Opcodes.F_NEW, 0, EMPTY_OBJECT_ARRAY, 0,
-            EMPTY_OBJECT_ARRAY);
-        stack = Math.max(stack, 1);
-      } else {
-        /*
-         * Otherwise, throw an exception if the existing JSO implementation is
-         * not a supertype of the current class.
-         */
-        Label noPreviousClass = new Label();
-        Label noActionNeeded = new Label();
-        mv.visitJumpInsn(Opcodes.IFNULL, noPreviousClass);
-        // Stack is: empty
-
-        // Ensure the existing type is one of my supertypes
-        mv.visitFieldInsn(Opcodes.GETSTATIC, intf
-            + SINGLE_JSO_IMPL_ADJUNCT_SUFFIX, SINGLE_JSO_IMPL_FIELD,
-            "Ljava/lang/Class;");
-        mv.visitLdcInsn(Type.getObjectType(className));
-        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class",
-            "isAssignableFrom", "(Ljava/lang/Class;)Z");
-        mv.visitJumpInsn(Opcodes.IFNE, noActionNeeded);
-        // Stack is: empty
-
-        mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException");
-        // Stack is: uninitialized
-        mv.visitInsn(Opcodes.DUP);
-        // Stack is: uninitialized, uninitialized
-        mv.visitLdcInsn("Multiple JavaScriptObject subclasses implement an "
-            + "interface declared on this type");
-        // Stack is: uninitialized, uninitialized, string
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException",
-            "<init>", "(Ljava/lang/String;)V");
-        // Stack is: RuntimeException
-        mv.visitInsn(Opcodes.ATHROW);
-
-        mv.visitLabel(noPreviousClass);
-        // Stack is: empty
-        mv.visitFrame(Opcodes.F_NEW, 0, EMPTY_OBJECT_ARRAY, 0,
-            EMPTY_OBJECT_ARRAY);
-        mv.visitLdcInsn(Type.getObjectType(className));
-        // Stack is: class literal
-        mv.visitFieldInsn(Opcodes.PUTSTATIC, intf
-            + SINGLE_JSO_IMPL_ADJUNCT_SUFFIX, SINGLE_JSO_IMPL_FIELD,
-            "Ljava/lang/Class;");
-        // Stack is: empty
-
-        mv.visitLabel(noActionNeeded);
-        // Stack is: empty
-        mv.visitFrame(Opcodes.F_NEW, 0, EMPTY_OBJECT_ARRAY, 0,
-            EMPTY_OBJECT_ARRAY);
-
-        stack = Math.max(stack, 3);
-      }
-    }
-    mv.visitInsn(Opcodes.RETURN);
-    mv.visitMaxs(stack, 0);
-    mv.visitEnd();
-  }
-}
diff --git a/user/test/com/google/gwt/dev/jjs/test/JsoTest.java b/user/test/com/google/gwt/dev/jjs/test/JsoTest.java
index 50c49cc..5bf60b0 100644
--- a/user/test/com/google/gwt/dev/jjs/test/JsoTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/JsoTest.java
@@ -15,13 +15,9 @@
  */
 package com.google.gwt.dev.jjs.test;
 
-import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.junit.client.GWTTestCase;
 
-import java.util.Arrays;
-import java.util.List;
-
 /**
  * Tests {@link JavaScriptObject} and subclasses.
  */
@@ -56,7 +52,7 @@
     public static native String staticNative() /*-{
       return "nativeFoo";
     }-*/;
-
+    
     /**
      * Ensure that a supertype can refer to members of a subtype.
      */
@@ -84,7 +80,7 @@
     static String staticValueSub() {
       return "FooSub";
     }
-
+    
     protected FooSub() {
     }
 
@@ -211,20 +207,6 @@
     }
   }
 
-  public static void assertSame(Object o1, Object o2) {
-    assertTrue("Failed double-equals", o1 == o2);
-    assertTrue("Failed o1.equals(o2)", o1.equals(o2));
-    assertTrue("Failed o2.equals(o1)", o2.equals(o1));
-    assertEquals("Hashcode mismatch", o1.hashCode(), o2.hashCode());
-  }
-
-  public static void assertSame(JavaScriptObject o1, JavaScriptObject o2) {
-    assertTrue("Failed double-equals", o1 == o2);
-    assertTrue("Failed o1.equals(o2)", o1.equals(o2));
-    assertTrue("Failed o2.equals(o1)", o2.equals(o1));
-    assertEquals("Hashcode mismatch", o1.hashCode(), o2.hashCode());
-  }
-
   private static native Bar makeBar() /*-{
     return {
       toString:function() {
@@ -275,8 +257,6 @@
     return jso;
   }-*/;
 
-  private Object aField;
-
   @Override
   public String getModuleName() {
     return "com.google.gwt.dev.jjs.CompilerSuite";
@@ -289,29 +269,6 @@
     assertFalse(array[2] instanceof JavaScriptObject);
   }
 
-  public void testArrayJreInteractions() {
-    JavaScriptObject obj = makeJSO();
-    Foo[] foo = new Foo[1];
-    foo[0] = (Foo) obj;
-
-    Bar[] bar = new Bar[1];
-    bar[0] = (Bar) obj;
-
-    assertSame(foo[0], bar[0]);
-
-    List<Foo> fooList = Arrays.asList(foo);
-    List<Bar> barList = Arrays.asList(bar);
-    assertSame(fooList.get(0), barList.get(0));
-    assertSame(fooList.iterator().next(), barList.iterator().next());
-
-    @SuppressWarnings("unchecked")
-    List fooRawList = Arrays.asList(foo);
-    @SuppressWarnings("unchecked")
-    List barRawList = Arrays.asList(bar);
-    assertSame(fooRawList.get(0), barRawList.get(0));
-    assertSame(fooRawList.iterator().next(), barRawList.iterator().next());
-  }
-
   public void testArrayStore() {
     JavaScriptObject[] jsoArray = new JavaScriptObject[1];
     jsoArray[0] = makeJSO();
@@ -417,16 +374,6 @@
       fail("Expected ClassCastException");
     } catch (ClassCastException expected) {
     }
-    
-    bar = null;
-    assertFalse(bar instanceof JavaScriptObject);
-    try {
-      assertNull(bar);
-      foo = bar.cast();
-      assertNull(foo);
-    } catch (RuntimeException e) {
-      fail("Should not have thrown exception " + e.getMessage());
-    }
   }
 
   @SuppressWarnings("cast")
@@ -483,10 +430,7 @@
     assertEquals(JavaScriptObject.class, Bar.class);
     assertEquals(Foo.class, Bar.class);
 
-    if (!GWT.isScript()) {
-      assertEquals("com.google.gwt.core.client.JavaScriptObject",
-          JavaScriptObject.class.getName());
-    } else if (!JavaScriptObject.class.getName().startsWith("Class$")) {
+    if (!JavaScriptObject.class.getName().startsWith("Class$")) {
       // Class metadata could be disabled
       assertEquals("com.google.gwt.core.client.JavaScriptObject$",
           JavaScriptObject.class.getName());
@@ -510,10 +454,7 @@
     assertEquals(JavaScriptObject[][].class, Bar[][].class);
     assertEquals(Foo[][].class, Bar[][].class);
 
-    if (!GWT.isScript()) {
-      assertEquals("[[Lcom.google.gwt.core.client.JavaScriptObject;",
-          JavaScriptObject[][].class.getName());
-    } else if (!JavaScriptObject.class.getName().startsWith("Class$")) {
+    if (!JavaScriptObject.class.getName().startsWith("Class$")) {
       // Class metadata could be disabled
       assertEquals("[[Lcom.google.gwt.core.client.JavaScriptObject$;",
           JavaScriptObject[][].class.getName());
@@ -525,19 +466,11 @@
     assertEquals(jso, jso);
 
     JavaScriptObject jso2 = makeJSO();
-    assertNotSame(jso, jso2);
     assertFalse(jso.equals(jso2));
     assertFalse(jso2.equals(jso));
 
     jso2 = returnMe(jso);
-    assertSame(jso, jso2);
-
-    Object aLocal = (Bar) jso;
-    Object aLocal2 = (Foo) jso2;
-    aField = aLocal;
-    assertSame(aLocal, aField);
-    assertSame(jso, aField);
-    assertSame(aLocal, aLocal2);
+    assertEquals(jso, jso2);
   }
 
   public void testGenericsJsos() {
@@ -629,30 +562,6 @@
 
     jso2 = returnMe(jso);
     assertSame(jso, jso2);
-
-    {
-      JavaScriptObject[] arr = new JavaScriptObject[] {jso, jso2};
-      assertSame(arr[0], arr[1]);
-    }
-
-    {
-      JavaScriptObject[] arr = new JavaScriptObject[2];
-      arr[0] = jso;
-      arr[1] = jso2;
-      assertSame(arr[0], arr[1]);
-    }
-
-    {
-      JavaScriptObject[] arr = new JavaScriptObject[] {(Foo) jso, (Bar) jso2};
-      assertSame(arr[0], arr[1]);
-    }
-
-    {
-      JavaScriptObject[] arr = new JavaScriptObject[2];
-      arr[0] = (Foo) jso;
-      arr[1] = (Bar) jso2;
-      assertSame(arr[0], arr[1]);
-    }
   }
 
   public void testInheritance() {
diff --git a/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java b/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java
index ebc7195..ae07751 100644
--- a/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java
@@ -16,20 +16,12 @@
 package com.google.gwt.dev.jjs.test;
 
 import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.SingleJsoImpl;
 import com.google.gwt.dev.jjs.test.SingleJsoImplTest.JsoHasInnerJsoType.InnerType;
 import com.google.gwt.dev.jjs.test.jsointfs.JsoInterfaceWithUnreferencedImpl;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 
 import java.io.IOException;
-import java.util.AbstractMap;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * Ensures that JavaScriptObjects may implement interfaces with methods.
@@ -75,12 +67,10 @@
     String call(int a, int b);
   }
 
-  @SingleJsoImpl(JsoCreatedWithCast.class)
   interface CreatedWithCast {
     String foo();
   }
 
-  @SingleJsoImpl(JsoCreatedWithCastToTag.class)
   interface CreatedWithCastToTag {
   }
 
@@ -519,19 +509,12 @@
     return {};
   }-*/;
 
-  private Object asObject;
-
-  private Simple asSimple;
-
-  private Adder asAdder;
-
   @Override
   public String getModuleName() {
     return "com.google.gwt.dev.jjs.CompilerSuite";
   }
 
   public void testCallsToInnerTypes() {
-    JsoHasInnerJsoType o = JavaScriptObject.createObject().cast();
     CallsMethodInInnerType a = (CallsMethodInInnerType) JavaScriptObject.createObject();
     InnerType i = (InnerType) JavaScriptObject.createObject();
     assertEquals(5, a.call(i, 5).get());
@@ -539,7 +522,6 @@
   }
 
   public void testCallsWithArrays() {
-    JsoUsesArrays toss = JavaScriptObject.createObject().cast();
     UsesArrays a = JavaScriptObject.createObject().<JsoUsesArrays> cast();
     a.acceptIntArray(a.returnIntArray());
     a.acceptInt3Array(a.returnInt3Array());
@@ -557,12 +539,6 @@
     a.acceptObject3Array(a.returnString3Array());
   }
 
-  public void testClassLiterals() {
-    JavaScriptObject jso = makeSimple();
-    assertEquals(JavaScriptObject.class, jso.getClass());
-    assertEquals(JavaScriptObject.class, asSimple((JsoSimple) jso).getClass());
-  }
-
   /**
    * Ensure that SingleJSO types that are referred to only via a cast to the
    * interface type are retained. If the JsoCreatedWithCast type isn't rescued
@@ -570,7 +546,6 @@
    * compiler would assume there are types that implement the interface.
    */
   public void testCreatedWithCast() {
-    // This can't work in hosted mode, we need something to load the JSO
     try {
       Object a = (CreatedWithCast) JavaScriptObject.createObject();
     } catch (ClassCastException e) {
@@ -629,7 +604,7 @@
       assertTrue(a instanceof JsoAdder);
       assertFalse(a instanceof JavaAdder);
       // NB: This is unexpected until you consider JSO$ as a roll-up type
-      // assertTrue(a instanceof Tag);
+      assertTrue(a instanceof Tag);
       try {
         ((JavaAdder) a).add(1, 1);
         fail("Should have thrown CCE");
@@ -661,269 +636,6 @@
     }, "Hello");
   }
 
-  /**
-   * Test identity with arrays.
-   */
-  public void testIdentityArrays() {
-    // XXX Really need @SingleJsoImpl annotation here
-    makeDivider(1);
-    makeAdder(1);
-    JavaScriptObject obj = makeSimple();
-    Adder[] adders = {(Adder) obj};
-    Divider[] dividers = {(Divider) obj};
-    assertSame(adders[0], dividers[0]);
-
-    Object[] arr = {adders[0], dividers[0]};
-    assertSame(arr[0], arr[1]);
-
-    List<Adder> adderList = Arrays.asList(adders);
-    List<Divider> dividerList = Arrays.asList(dividers);
-    assertSame(adderList.get(0), dividerList.get(0));
-
-    @SuppressWarnings("unchecked")
-    List adderListRaw = Arrays.asList(adders);
-    @SuppressWarnings("unchecked")
-    List dividerListRaw = Arrays.asList(dividers);
-    assertSame(adderListRaw.get(0), dividerListRaw.get(0));
-  }
-
-  /**
-   * Pass some SingleJsoImpl types into JRE collections.
-   */
-  public void testIdentityJRE() {
-    IdentityHashMap<JavaScriptObject, Boolean> jMap = new IdentityHashMap<JavaScriptObject, Boolean>();
-    IdentityHashMap<Simple, Boolean> sMap = new IdentityHashMap<Simple, Boolean>();
-
-    JsoSimple jso = makeSimple();
-    jMap.put(jso, true);
-    sMap.put(jso, true);
-
-    assertTrue(jMap.get(jso));
-    assertTrue(sMap.get(jso));
-
-    assertTrue(jMap.get(asSimple(jso)));
-    assertTrue(sMap.get(asSimple(jso)));
-    assertTrue(jMap.get(asSimple));
-    assertTrue(sMap.get(asSimple));
-
-    assertTrue(jMap.get(asObject(jso)));
-    assertTrue(sMap.get(asObject(jso)));
-    assertTrue(jMap.get(asObject));
-    assertTrue(sMap.get(asObject));
-
-    assertNull(jMap.get(JavaScriptObject.createObject()));
-    assertNull(sMap.get(JavaScriptObject.createObject()));
-  }
-
-  /**
-   * Pass some SingleJsoImpl types into an IdentityHashMap.
-   */
-  public void testIdentityJRE2() {
-    final JavaScriptObject jso = JavaScriptObject.createObject();
-    IdentityHashMap<Object, Boolean> map = new IdentityHashMap<Object, Boolean>();
-
-    // First with a proper JSO subtype
-    map.putAll(new AbstractMap<JsoAdder, Boolean>() {
-      @Override
-      public Set<Entry<JsoAdder, Boolean>> entrySet() {
-        Entry<JsoAdder, Boolean> entry = new Entry<JsoAdder, Boolean>() {
-          public JsoAdder getKey() {
-            return (JsoAdder) jso;
-          }
-
-          public Boolean getValue() {
-            return true;
-          }
-
-          public Boolean setValue(Boolean value) {
-            throw new RuntimeException("unimplemented");
-          }
-        };
-        return Collections.singleton(entry);
-      }
-    });
-
-    assertEquals(1, map.size());
-    assertNotNull(map.get(jso));
-    assertTrue(map.get(jso));
-    assertTrue(map.get((Adder) jso));
-    assertTrue(map.get(asAdder((Adder) jso)));
-    assertTrue(map.get((JsoAdder) jso));
-    assertTrue(map.get((JsoSimple) jso));
-
-    // Now with an interface type
-    map.putAll(new AbstractMap<Adder, Boolean>() {
-      @Override
-      public Set<Entry<Adder, Boolean>> entrySet() {
-        Entry<Adder, Boolean> entry = new Entry<Adder, Boolean>() {
-          public Adder getKey() {
-            return (Adder) jso;
-          }
-
-          public Boolean getValue() {
-            return false;
-          }
-
-          public Boolean setValue(Boolean value) {
-            throw new RuntimeException("unimplemented");
-          }
-        };
-        return Collections.singleton(entry);
-      }
-    });
-
-    assertEquals(1, map.size());
-    assertNotNull(map.get(jso));
-    assertFalse(map.get(jso));
-
-    assertNull(map.get(JavaScriptObject.createObject()));
-
-    map.put(JavaScriptObject.createObject(), true);
-    assertFalse(map.remove(jso));
-    assertEquals(1, map.size());
-    assertTrue(map.values().iterator().next());
-  }
-
-  public void testIdentityMethodsAndFields() {
-    JsoSimple jso = makeSimple();
-    JsoSimple jso2 = makeSimple();
-    assertNotSame(jso, jso2);
-    assertTrue(jso != jso2);
-    assertFalse(jso == jso2);
-
-    Object o = asObject(jso);
-    Object o2 = asObject(jso2);
-    assertNotSame(o, o2);
-    assertTrue(o != o2);
-    assertFalse(o == o2);
-
-    assertSame(jso, o);
-    assertTrue(jso == o);
-    assertFalse(jso != o);
-
-    assertSame(jso2, o2);
-    assertTrue(jso2 == o2);
-    assertFalse(jso2 != o2);
-
-    assertSame(asObject, jso2);
-    assertTrue(asObject == jso2);
-    assertFalse(asObject != jso2);
-
-    assertSame(asObject, o2);
-    assertTrue(asObject == o2);
-    assertFalse(asObject != o2);
-
-    Simple s = asSimple(jso);
-    Simple s2 = asSimple(jso2);
-    assertNotSame(s, s2);
-    assertTrue(s != s2);
-    assertFalse(s == s2);
-
-    assertSame(jso, s);
-    assertTrue(jso == s);
-    assertFalse(jso != s);
-
-    assertSame(s, o);
-    assertTrue(s == o);
-    assertFalse(s != o);
-
-    assertSame(jso2, s2);
-    assertTrue(jso2 == s2);
-    assertFalse(jso2 != s2);
-
-    assertSame(o2, s2);
-    assertTrue(o2 == s2);
-    assertFalse(o2 != s2);
-
-    assertSame(asSimple, jso2);
-    assertTrue(asSimple == jso2);
-    assertFalse(asSimple != jso2);
-
-    assertSame(asSimple, o2);
-    assertTrue(asSimple == o2);
-    assertFalse(asSimple != o2);
-
-    assertSame(asSimple, s2);
-    assertTrue(asSimple == s2);
-    assertFalse(asSimple != s2);
-
-    JsoRandom r = (JsoRandom) o2;
-    assertSame(r, jso2);
-    // Can't legally compare r == jso2
-
-    assertSame(r, o2);
-    assertTrue(r == o2);
-    assertFalse(r != o2);
-
-    assertSame(r, asObject);
-    assertTrue(r == asObject);
-    assertFalse(r != asObject);
-
-    assertSame(r, s2);
-    // Can't legally compare r == s2
-
-    assertSame(r, asSimple);
-    // Can't legally compare r == asSimple
-  }
-
-  public void testIdentityWithDualTypes() {
-    JsoAdder jso = makeAdder(0);
-    JavaAdder java = new JavaAdder();
-
-    assertNotSame(jso, java);
-
-    IdentityHashMap<Adder, Integer> map = new IdentityHashMap<Adder, Integer>();
-    map.put(jso, 0);
-    map.put(java, 1);
-    assertEquals(2, map.size());
-
-    assertEquals(new Integer(0), map.get(jso));
-    assertEquals(new Integer(1), map.get(java));
-
-    // Use unambiguous dispatch
-    assertEquals(new Integer(0), map.get(asAdder(jso)));
-    assertEquals(new Integer(0), map.get(asAdder));
-    assertEquals(new Integer(1), map.get(asAdder(java)));
-    assertEquals(new Integer(1), map.get(asAdder));
-
-    // Use ambiguous dispatch
-    assertEquals(new Integer(0), map.get(asAdder((Adder) jso)));
-    assertEquals(new Integer(0), map.get(asAdder));
-    assertEquals(new Integer(1), map.get(asAdder((Adder) java)));
-    assertEquals(new Integer(1), map.get(asAdder));
-
-    // Test with plain Object
-    assertEquals(new Integer(0), map.get(asObject(jso)));
-    assertEquals(new Integer(0), map.get(asObject));
-    assertEquals(new Integer(1), map.get(asObject(java)));
-    assertEquals(new Integer(1), map.get(asObject));
-
-    // Behavior of keys
-    for (Map.Entry<Adder, Integer> entry : map.entrySet()) {
-      if (entry.getKey() == jso) {
-        assertEquals(new Integer(0), entry.getValue());
-      }
-      if (entry.getKey() == java) {
-        assertEquals(new Integer(1), entry.getValue());
-      }
-    }
-  }
-
-  public void testIdentityWithNativeMethods() {
-    JsoSimple s = makeSimple();
-    Simple s2 = asSimpleNative(s);
-    assertSame(s, s2);
-    assertSame(s, asSimple);
-    assertSame(s2, asSimple);
-  }
-
-  /**
-   * Called from asSimpleNative to continue the above test.
-   */
-  public void testIdentityWithNativeMethods(JsoSimple o) {
-    assertSame(o, asSimple);
-  }
-
   @SuppressWarnings("cast")
   public void testSimpleCase() {
     {
@@ -999,7 +711,6 @@
   }
 
   public void testStaticCallsToSubclasses() {
-    JsoCallsStaticMethodInSubclass a = JavaScriptObject.createObject().cast();
     Object o = "String";
     assertEquals(String.class, o.getClass());
     o = JavaScriptObject.createObject();
@@ -1080,59 +791,9 @@
     }
   }
 
-  /**
-   * This test relies on the SingleJsoimpl annotation in dev mode.
-   */
   public void testUnreferencedType() {
     JsoInterfaceWithUnreferencedImpl o = (JsoInterfaceWithUnreferencedImpl) JavaScriptObject.createObject();
     assertNotNull(o);
     assertTrue(o.isOk());
   }
-
-  protected Adder asAdder(Adder o) {
-    asAdder = o;
-    return o;
-  }
-
-  /*
-   * These asXYZ methods are to test cast-via-return and cast-via-assignment
-   * rewriting.
-   */
-
-  protected Adder asAdder(JavaAdder o) {
-    asAdder = o;
-    return o;
-  }
-
-  protected Adder asAdder(JsoAdder o) {
-    asAdder = o;
-    return o;
-  }
-
-  protected Object asObject(JavaAdder jso) {
-    asObject = jso;
-    return jso;
-  }
-
-  protected Object asObject(JsoAdder jso) {
-    asObject = jso;
-    return jso;
-  }
-
-  protected Object asObject(JsoSimple jso) {
-    asObject = jso;
-    return jso;
-  }
-
-  protected Simple asSimple(JsoSimple jso) {
-    asSimple = jso;
-    return jso;
-  }
-
-  private native Simple asSimpleNative(Object o) /*-{
-    // Make sure glue code does the interface cast
-    this.@com.google.gwt.dev.jjs.test.SingleJsoImplTest::asSimple = o;
-    this.@com.google.gwt.dev.jjs.test.SingleJsoImplTest::testIdentityWithNativeMethods(Lcom/google/gwt/dev/jjs/test/SingleJsoImplTest$JsoSimple;)(o);
-    return o;
-  }-*/;
 }
