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 a789ac0..e35484c 100644
--- a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
+++ b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
@@ -19,11 +19,8 @@
 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;
@@ -34,14 +31,11 @@
 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.HostedModeClassRewriter.InstanceMethodOracle;
-import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SingleJsoImplData;
+import com.google.gwt.dev.shell.rewrite.SingleJsoImplSupport;
 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;
@@ -64,9 +58,7 @@
 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
@@ -294,11 +286,6 @@
         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
@@ -355,325 +342,6 @@
   }
 
   /**
-   * 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<?>>();
@@ -683,7 +351,7 @@
    * space (thus, they bridge across the spaces).
    */
   private static final Class<?>[] BRIDGE_CLASSES = new Class<?>[] {
-      ShellJavaScriptHost.class, GWTBridge.class};
+      ShellJavaScriptHost.class, GWTBridge.class, SingleJsoImplSupport.class};
 
   private static final boolean CLASS_DUMP = Boolean.getBoolean("gwt.dev.classDump");
 
@@ -861,36 +529,10 @@
 
     ensureJavaScriptHostBytes(logger);
 
-    // Create a class rewriter based on all the subtypes of the JSO class.
+    // Create a class rewriter based on availability of JSO class.
     JClassType jsoType = typeOracle.findType(JsValueGlue.JSO_CLASS);
     if (jsoType != null) {
-
-      // 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);
+      classRewriter = new HostedModeClassRewriter(typeOracle);
     } else {
       // If we couldn't find the JSO class, we don't need to do any rewrites.
       classRewriter = null;
@@ -1020,7 +662,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);
@@ -1068,13 +710,7 @@
    * Convert a binary class name into a resource-like name.
    */
   private String canonicalizeClassName(String className) {
-    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;
+    return className.replace('.', '/');
   }
 
   @SuppressWarnings("deprecation")
@@ -1082,15 +718,12 @@
     if (JavaScriptHost.class.getName().equals(className)) {
       // No need to rewrite.
       return javaScriptHostBytes;
-    }
-
-    if (classRewriter != null && classRewriter.isJsoIntf(className)) {
-      // Generate a synthetic JSO interface class.
-      byte[] newBytes = classRewriter.writeJsoIntf(className);
+    } else if (className.endsWith(HostedModeClassRewriter.SINGLE_JSO_IMPL_ADJUNCT_SUFFIX)) {
+      byte[] bytes = classRewriter.writeSingleJsoImplAdjunct(className);
       if (CLASS_DUMP) {
-        classDump(className, newBytes);
+        classDump(className, bytes);
       }
-      return newBytes;
+      return bytes;
     }
 
     // A JSO impl class needs the class bytes for the original class.
@@ -1155,8 +788,8 @@
       if (unit != null) {
         anonymousClassMap = unit.getAnonymousClassMap();
       }
-      byte[] newBytes = classRewriter.rewrite(typeOracle, className,
-          classBytes, anonymousClassMap);
+      byte[] newBytes = classRewriter.rewrite(className, classBytes,
+          anonymousClassMap);
       if (CLASS_DUMP) {
         if (!Arrays.equals(classBytes, newBytes)) {
           classDump(className, newBytes);
@@ -1212,6 +845,8 @@
     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 02e2cdd..fdefaed 100644
--- a/dev/core/src/com/google/gwt/dev/shell/JsValueGlue.java
+++ b/dev/core/src/com/google/gwt/dev/shell/JsValueGlue.java
@@ -16,6 +16,7 @@
 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;
@@ -29,11 +30,13 @@
 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.
+   * Create a JavaScriptObject instance referring to this JavaScript object,
+   * optionally wrapping the object in the desired JSO facade type.
    * 
+   * @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
    */
@@ -41,23 +44,18 @@
       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) {
-        return jso;
+      if (jso == null) {
+        // Instantiate the JSO instance.
+        Constructor<?> ctor = jsoType.getDeclaredConstructor(Object.class);
+        jso = ctor.newInstance(value);
+
+        classLoader.putCachedJso(value.getJavaScriptObjectPointer(), 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;
@@ -73,8 +71,6 @@
       caught = e;
     } catch (ClassNotFoundException e) {
       caught = e;
-    } catch (NoSuchFieldException e) {
-      caught = e;
     }
     throw new RuntimeException("Error creating JavaScript object", caught);
   }
@@ -88,7 +84,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,
@@ -166,7 +162,11 @@
       return type.cast(value.getString());
     }
     if (value.isJavaScriptObject()) {
-      return type.cast(createJavaScriptObject(value, cl));
+      Object jso = createJavaScriptObject(value, cl);
+      if (type != Object.class) {
+        jso = SingleJsoImplSupport.cast(jso, type);
+      }
+      return type.cast(jso);
     }
 
     // Just don't know what do to with this.
@@ -217,8 +217,8 @@
     } else {
       // not a boxed primitive
       try {
-        Class<?> jsoType = Class.forName(JSO_IMPL_CLASS, false, cl);
-        if (jsoType == obj.getClass()) {
+        Class<?> jsoType = Class.forName(JSO_CLASS, false, cl);
+        if (jsoType.isInstance(obj)) {
           JsValue jsObject = getUnderlyingObject(obj);
           value.setValue(jsObject);
           return;
@@ -258,9 +258,10 @@
       }
       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 319aeb3..095eda7 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.Collections;
-import java.util.HashMap;
+import java.util.Arrays;
 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,25 +38,123 @@
  * <ol>
  * <li>Rewrites all native methods into non-native thunks to call JSNI via
  * {@link com.google.gwt.dev.shell.JavaScriptHost}.</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>
+ * <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>
  * </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
@@ -65,160 +163,66 @@
    */
 
   /**
-   * Maps instance methods to the class in which they are declared. This must be
-   * provided by the caller since it requires global program state.
+   * Used in CompilingClassLoader to trigger a call to
+   * {@link #writeSingleJsoImplAdjunct}.
    */
-  public interface InstanceMethodOracle {
+  public static final String SINGLE_JSO_IMPL_ADJUNCT_SUFFIX = "$$singleJsoImpl";
 
-    /**
-     * 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 String CANONICAL_FIELD = "canonicalJso";
 
-  /**
-   * 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 boolean EXTRA_DEBUG_DATA = Boolean.getBoolean("gwt.dev.classDump");
 
   static final String JAVASCRIPTOBJECT_DESC = JsValueGlue.JSO_CLASS.replace(
       '.', '/');
 
-  static final String JAVASCRIPTOBJECT_IMPL_DESC = JsValueGlue.JSO_IMPL_CLASS.replace(
-      '.', '/');
-
   static final String REFERENCE_FIELD = JsValueGlue.HOSTED_MODE_REFERENCE;
 
-  static String addSyntheticThisParam(String owner, String methodDescriptor) {
-    return "(L" + owner + ";" + methodDescriptor.substring(1);
-  }
+  static final String REWRAP_METHOD = "$rewrap";
 
-  private static String toDescriptor(String jsoSubtype) {
+  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 int SYSTEM_CLASS_VERSION = Double.parseDouble(System.getProperty("java.class.version")) < Opcodes.V1_6
+      ? Opcodes.V1_5 : Opcodes.V1_6;
+
+  private static String toInternalName(String jsoSubtype) {
     return jsoSubtype.replace('.', '/');
   }
 
   /**
-   * An unmodifiable set of descriptors containing the implementation form of
-   * <code>JavaScriptObject</code> and all subclasses.
+   * Passed into the rewriting visitors.
    */
-  private final Set<String> jsoImplDescs;
+  private final RewriterOracle rewriterOracle;
 
   /**
-   * An unmodifiable set of descriptors containing the interface form of
-   * <code>JavaScriptObject</code> and all subclasses.
-   */
-  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.
+   * Creates a new {@link HostedModeClassRewriter}.
    * 
-   * @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
+   * @param typeOracle The TypeOracle for the GWT module that is being rewritten
    */
-  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));
+  public HostedModeClassRewriter(TypeOracle typeOracle) {
+    rewriterOracle = new RewriterOracle(typeOracle);
   }
 
   /**
    * 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(TypeOracle typeOracle, String className,
-      byte[] classBytes, Map<String, String> anonymousClassMap) {
-    String desc = toDescriptor(className);
-    assert (!jsoIntfDescs.contains(desc));
+  public byte[] rewrite(String className, byte[] classBytes,
+      Map<String, String> anonymousClassMap) {
+    classBytes = maybeUpgradeBytecode(classBytes);
+    String desc = toInternalName(className);
 
     // The ASM model is to chain a bunch of visitors together.
     ClassWriter writer = new ClassWriter(0);
@@ -227,49 +231,63 @@
     // v = new CheckClassAdapter(v);
     // v = new TraceClassVisitor(v, new PrintWriter(System.out));
 
-    v = new RewriteSingleJsoImplDispatches(v, typeOracle, jsoData);
+    v = new WriteSingleJsoSupportCode(v, rewriterOracle);
 
-    v = new RewriteRefsToJsoClasses(v, jsoIntfDescs, mapper);
+    v = new RewriteJsoCasts(v, rewriterOracle);
 
-    if (jsoImplDescs.contains(desc)) {
-      v = WriteJsoImpl.create(v, desc, jsoIntfDescs, mapper, jsoData);
+    v = new RewriteObjectComparisons(v, rewriterOracle);
+
+    if (rewriterOracle.isJsoOrSubtype(desc)) {
+      v = WriteJsoImpl.create(v, desc);
     }
 
     v = new RewriteJsniMethods(v, anonymousClassMap);
 
-    if (Double.parseDouble(System.getProperty("java.class.version")) < Opcodes.V1_6) {
+    if (SYSTEM_CLASS_VERSION < Opcodes.V1_6) {
       v = new ForceClassVersion15(v);
     }
 
-    new ClassReader(classBytes).accept(v, 0);
+    // We need EXPAND_FRAMES here for RewriteJsoCasts
+    new ClassReader(classBytes).accept(v, ClassReader.EXPAND_FRAMES);
     return writer.toByteArray();
   }
 
-  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);
+  /**
+   * 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);
+  }
 
-    // The ASM model is to chain a bunch of visitors together.
-    ClassWriter writer = new ClassWriter(0);
-    ClassVisitor v = writer;
+  /**
+   * 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;
 
-    // v = new CheckClassAdapter(v);
-    // v = new TraceClassVisitor(v, new PrintWriter(System.out));
+      // 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);
+        }
+      };
 
-    String[] interfaces;
-    // TODO(bov): something better than linear?
-    if (superDescs.contains("java/lang/Object")) {
-      interfaces = null;
-    } else {
-      interfaces = superDescs.toArray(new String[superDescs.size()]);
+      new ClassReader(classBytes).accept(v2, 0);
+      classBytes = cw.toByteArray();
     }
-    v.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC | Opcodes.ACC_INTERFACE, desc,
-        null, "java/lang/Object", interfaces);
-    v.visitEnd();
-    return writer.toByteArray();
+    return classBytes;
   }
 }
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
new file mode 100644
index 0000000..a3fe1ce
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsoCasts.java
@@ -0,0 +1,617 @@
+/*
+ * 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
new file mode 100644
index 0000000..f7d2377
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteObjectComparisons.java
@@ -0,0 +1,108 @@
+/*
+ * 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
deleted file mode 100644
index 3a45363..0000000
--- a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteRefsToJsoClasses.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.dev.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
deleted file mode 100644
index b6c7c1e..0000000
--- a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteSingleJsoImplDispatches.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * 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
new file mode 100644
index 0000000..9c0b794
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/SingleJsoImplSupport.java
@@ -0,0 +1,252 @@
+/*
+ * 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 4eafd89..92acc1b 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,94 +15,79 @@
  */
 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>
  */
-abstract class WriteJsoImpl extends ClassAdapter {
+class WriteJsoImpl {
 
   /**
    * This type implements JavaScriptObject.
    * 
-   * <ol>
+   * <ul>
    * <li>JavaScriptObject itself gets a new synthetic field to store the
    * underlying hosted mode reference.</li>
-   * <li>Instance methods are added so that JavaScriptObject implements all
-   * SingleJsoImpl interfaces.</li>
-   * </ol>
+   * <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>
    * 
    */
-  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;
+  private static class ForJso extends ClassAdapter {
+    public ForJso(ClassVisitor cv) {
+      super(cv);
     }
 
     @Override
     public void visit(int version, int access, String name, String signature,
         String superName, String[] interfaces) {
 
-      ArrayList<String> jsoDescList = new ArrayList<String>();
-      jsoDescList.addAll(jsoDescriptors);
-      interfaces = jsoDescList.toArray(new String[jsoDescList.size()]);
+      super.visit(version, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
+          | Opcodes.ACC_SYNTHETIC, name, signature, superName, interfaces);
 
-      super.visit(version, access, name, signature, superName, interfaces);
+      // 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);
+      }
 
       /*
        * Generate the synthetic "hostedModeReferece" field to contain the
        * underlying real reference to the JavaScript object.
        */
-      FieldVisitor fv = visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC,
-          HostedModeClassRewriter.REFERENCE_FIELD, "Ljava/lang/Object;", null,
+      FieldVisitor fv = visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC
+          | Opcodes.ACC_FINAL, REFERENCE_FIELD, "Ljava/lang/Object;", 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());
-        }
+      /*
+       * 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();
       }
     }
 
@@ -110,123 +95,364 @@
     public MethodVisitor visitMethod(int access, String name, String desc,
         String signature, String[] exceptions) {
       if (isCtor(name)) {
-        // make the JavaScriptObject$ constructor public
-        access &= ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED);
-        access |= Opcodes.ACC_PUBLIC;
+        writeConstructors(name);
+        return null;
+      } else if ("equals".equals(name) && "(Ljava/lang/Object;)Z".equals(desc)) {
+        writeEquals(access, name, desc, signature, exceptions);
+        return null;
       }
       return super.visitMethod(access, name, desc, signature, exceptions);
     }
 
     /**
-     * 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:
+     * Generates a method to return the canonical object.
      * 
      * <pre>
-     * 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);
+     * public JavaScriptObject rewrap$(JavaScriptObject o) {
+     *   if (o == null) {
+     *     return null;
      *   }
+     *   return o.canonical;
      * }
      * </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 writeTrampoline(String mangledName, Method interfaceMethod,
-        Method implementingMethod) {
-      assert implementingMethod.getArgumentTypes().length > 0;
+    protected void writeRewrapMethod(MethodVisitor mv) {
+      Label start = new Label();
+      Label end = new Label();
 
-      /*
-       * 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);
+      mv.visitCode();
+      mv.visitLabel(start);
 
-      /*
-       * We also use the first argument to know which type to statically
-       * dispatch to.
-       */
-      Type implementingType = Type.getType("L"
-          + implementingMethod.getArgumentTypes()[0].getInternalName() + "$;");
+      mv.visitVarInsn(Opcodes.ALOAD, 0);
+      // Stack is: jso
+      mv.visitInsn(Opcodes.DUP);
+      // Stack is: jso, jso
 
-      // 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);
+      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>
+     */
+    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);
       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
 
-        /*
-         * 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;
+        // 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>
 
-        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.visitInsn(Opcodes.RETURN);
+        mv.visitMaxs(4, 2);
         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.
    * 
-   * <ol>
-   * <li>The new type's superclass is mangled by adding $.</li>
-   * <li>Constructors are deleted.</li>
-   * </ol>
+   * <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>
    */
-  private static class ForJsoInterface extends WriteJsoImpl {
-    public ForJsoInterface(ClassVisitor cv, InstanceMethodOracle mapper) {
-      super(cv, mapper);
+  private static class ForJsoSubclass extends ClassAdapter {
+    private String superName;
+    private String typeName;
+
+    public ForJsoSubclass(ClassVisitor cv) {
+      super(cv);
     }
 
     @Override
     public void visit(int version, int access, String name, String signature,
         String superName, String[] interfaces) {
-      // Reference the old superclass's implementation class.
-      superName += '$';
-      interfaces = null;
+      this.superName = superName;
+      this.typeName = name;
+      super.visit(version, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
+          | Opcodes.ACC_SYNTHETIC, name, signature, superName, interfaces);
 
-      super.visit(version, access, name, signature, superName, interfaces);
+      // 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);
+      }
     }
 
+    /**
+     * 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) {
-        // Don't copy over constructors except for JavaScriptObject itself.
+        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();
+
         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();
+    }
   }
 
   /**
@@ -234,89 +460,21 @@
    * 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,
-      Set<String> jsoDescriptors, InstanceMethodOracle mapper,
-      SingleJsoImplData singleJsoImplData) {
-
-    if (classDescriptor.equals(HostedModeClassRewriter.JAVASCRIPTOBJECT_IMPL_DESC)) {
-      return new ForJsoDollar(cv, jsoDescriptors, mapper, singleJsoImplData);
+  public static ClassVisitor create(ClassVisitor cv, String classDescriptor) {
+    if (classDescriptor.equals(JAVASCRIPTOBJECT_DESC)) {
+      return new ForJso(cv);
     } else {
-      return new ForJsoInterface(cv, mapper);
+      return new ForJsoSubclass(cv);
     }
   }
 
-  /**
-   * 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;
-  }
-
-  /**
-   * Records the original name and resets access opcodes.
-   */
-  @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) {
+  private static 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.
+   * Utility class.
    */
-  protected MethodVisitor visitMethodNoRewrite(int access, String name,
-      String desc, String signature, String[] exceptions) {
-    return super.visitMethod(access, name, desc, signature, exceptions);
+  private WriteJsoImpl() {
   }
 }
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
new file mode 100644
index 0000000..05532a3
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/WriteSingleJsoSupportCode.java
@@ -0,0 +1,424 @@
+/*
+ * 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 5bf60b0..50c49cc 100644
--- a/user/test/com/google/gwt/dev/jjs/test/JsoTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/JsoTest.java
@@ -15,9 +15,13 @@
  */
 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.
  */
@@ -52,7 +56,7 @@
     public static native String staticNative() /*-{
       return "nativeFoo";
     }-*/;
-    
+
     /**
      * Ensure that a supertype can refer to members of a subtype.
      */
@@ -80,7 +84,7 @@
     static String staticValueSub() {
       return "FooSub";
     }
-    
+
     protected FooSub() {
     }
 
@@ -207,6 +211,20 @@
     }
   }
 
+  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() {
@@ -257,6 +275,8 @@
     return jso;
   }-*/;
 
+  private Object aField;
+
   @Override
   public String getModuleName() {
     return "com.google.gwt.dev.jjs.CompilerSuite";
@@ -269,6 +289,29 @@
     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();
@@ -374,6 +417,16 @@
       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")
@@ -430,7 +483,10 @@
     assertEquals(JavaScriptObject.class, Bar.class);
     assertEquals(Foo.class, Bar.class);
 
-    if (!JavaScriptObject.class.getName().startsWith("Class$")) {
+    if (!GWT.isScript()) {
+      assertEquals("com.google.gwt.core.client.JavaScriptObject",
+          JavaScriptObject.class.getName());
+    } else if (!JavaScriptObject.class.getName().startsWith("Class$")) {
       // Class metadata could be disabled
       assertEquals("com.google.gwt.core.client.JavaScriptObject$",
           JavaScriptObject.class.getName());
@@ -454,7 +510,10 @@
     assertEquals(JavaScriptObject[][].class, Bar[][].class);
     assertEquals(Foo[][].class, Bar[][].class);
 
-    if (!JavaScriptObject.class.getName().startsWith("Class$")) {
+    if (!GWT.isScript()) {
+      assertEquals("[[Lcom.google.gwt.core.client.JavaScriptObject;",
+          JavaScriptObject[][].class.getName());
+    } else if (!JavaScriptObject.class.getName().startsWith("Class$")) {
       // Class metadata could be disabled
       assertEquals("[[Lcom.google.gwt.core.client.JavaScriptObject$;",
           JavaScriptObject[][].class.getName());
@@ -466,11 +525,19 @@
     assertEquals(jso, jso);
 
     JavaScriptObject jso2 = makeJSO();
+    assertNotSame(jso, jso2);
     assertFalse(jso.equals(jso2));
     assertFalse(jso2.equals(jso));
 
     jso2 = returnMe(jso);
-    assertEquals(jso, jso2);
+    assertSame(jso, jso2);
+
+    Object aLocal = (Bar) jso;
+    Object aLocal2 = (Foo) jso2;
+    aField = aLocal;
+    assertSame(aLocal, aField);
+    assertSame(jso, aField);
+    assertSame(aLocal, aLocal2);
   }
 
   public void testGenericsJsos() {
@@ -562,6 +629,30 @@
 
     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 ae07751..ebc7195 100644
--- a/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java
@@ -16,12 +16,20 @@
 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.
@@ -67,10 +75,12 @@
     String call(int a, int b);
   }
 
+  @SingleJsoImpl(JsoCreatedWithCast.class)
   interface CreatedWithCast {
     String foo();
   }
 
+  @SingleJsoImpl(JsoCreatedWithCastToTag.class)
   interface CreatedWithCastToTag {
   }
 
@@ -509,12 +519,19 @@
     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());
@@ -522,6 +539,7 @@
   }
 
   public void testCallsWithArrays() {
+    JsoUsesArrays toss = JavaScriptObject.createObject().cast();
     UsesArrays a = JavaScriptObject.createObject().<JsoUsesArrays> cast();
     a.acceptIntArray(a.returnIntArray());
     a.acceptInt3Array(a.returnInt3Array());
@@ -539,6 +557,12 @@
     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
@@ -546,6 +570,7 @@
    * 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) {
@@ -604,7 +629,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");
@@ -636,6 +661,269 @@
     }, "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() {
     {
@@ -711,6 +999,7 @@
   }
 
   public void testStaticCallsToSubclasses() {
+    JsoCallsStaticMethodInSubclass a = JavaScriptObject.createObject().cast();
     Object o = "String";
     assertEquals(String.class, o.getClass());
     o = JavaScriptObject.createObject();
@@ -791,9 +1080,59 @@
     }
   }
 
+  /**
+   * 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;
+  }-*/;
 }
