diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
index 1ceeea4..b80057c 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
@@ -328,7 +328,7 @@
    * @return <code>null</code> if the type is not found
    */
   public JClassType findType(String name) {
-    assert Name.isSourceName(name);
+    assert Name.isSourceName(name) : name + " is not a source name";
     return allTypes.get(name);
   }
 
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..a6ff29d 100644
--- a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
+++ b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
@@ -19,29 +19,21 @@
 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;
 import com.google.gwt.dev.javac.CompilationState;
 import com.google.gwt.dev.javac.CompilationUnit;
 import com.google.gwt.dev.javac.CompiledClass;
 import com.google.gwt.dev.javac.JsniMethod;
-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.OriginalJsniSignature;
+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.BinaryName;
 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 +56,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
@@ -146,23 +136,6 @@
       DispatchClassInfo dispClassInfo = getClassInfoFromClassName(className);
       if (dispClassInfo != null) {
         String memberName = parsed.memberSignature();
-
-        /*
-         * Disallow the use of JSNI references to SingleJsoImpl interface
-         * methods. This policy is due to web-mode dispatch implementation
-         * details; resolving the JSNI reference wouldn't be just be a name
-         * replacement, instead it would be necessary to significantly alter the
-         * semantics of the hand-written JS.
-         */
-        if (singleJsoImplTypes.contains(canonicalizeClassName(className))) {
-          logger.log(TreeLogger.WARN,
-              "Invalid JSNI reference to SingleJsoImpl interface (" + className
-                  + "); consider using a trampoline. "
-                  + "Expect subsequent failures.", new NoSuchFieldError(
-                  jsniMemberRef));
-          return -1;
-        }
-
         int memberId = dispClassInfo.getMemberId(memberName);
         if (memberId < 0) {
           if (!className.startsWith("java.")) {
@@ -294,11 +267,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 +323,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 +332,8 @@
    * space (thus, they bridge across the spaces).
    */
   private static final Class<?>[] BRIDGE_CLASSES = new Class<?>[] {
-      ShellJavaScriptHost.class, GWTBridge.class};
+      ShellJavaScriptHost.class, GWTBridge.class, OriginalJsniSignature.class,
+      SingleJsoImplSupport.class};
 
   private static final boolean CLASS_DUMP = Boolean.getBoolean("gwt.dev.classDump");
 
@@ -830,8 +480,6 @@
 
   private ShellJavaScriptHost shellJavaScriptHost;
 
-  private final Set<String> singleJsoImplTypes = new HashSet<String>();
-
   /**
    * Used by {@link #findClass(String)} to prevent reentrant JSNI injection.
    */
@@ -861,36 +509,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,8 +642,8 @@
      * when loading a JSO interface class; just wait until the implementation
      * class is loaded.
      */
-    if (!classRewriter.isJsoIntf(className)) {
-      CompilationUnit unit = getUnitForClassName(canonicalizeClassName(className));
+    {
+      CompilationUnit unit = getUnitForClassName(BinaryName.toInternalName(className));
       if (unit != null) {
         toInject.push(unit);
       }
@@ -1064,37 +686,27 @@
     dispClassInfoOracle.clear();
   }
 
-  /**
-   * 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;
-  }
-
   @SuppressWarnings("deprecation")
   private byte[] findClassBytes(String className) {
     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;
+    } else if (className.startsWith(HostedModeClassRewriter.DISAMBIGUATOR_TYPE_NAME)) {
+      byte[] bytes = classRewriter.writeConstructorDisambiguationType(className);
+      if (CLASS_DUMP) {
+        classDump(className, bytes);
+      }
+      return bytes;
     }
 
     // A JSO impl class needs the class bytes for the original class.
-    String lookupClassName = canonicalizeClassName(className);
+    String lookupClassName = BinaryName.toInternalName(className);
 
     CompiledClass compiledClass = compilationState.getClassFileMap().get(
         lookupClassName);
@@ -1155,8 +767,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);
@@ -1167,29 +779,6 @@
     return classBytes;
   }
 
-  private String getBinaryName(JClassType type) {
-    String name = type.getPackage().getName() + '.';
-    name += type.getName().replace('.', '$');
-    return name;
-  }
-
-  private String getBinaryOrPrimitiveName(JType type) {
-    JArrayType asArray = type.isArray();
-    JClassType asClass = type.isClassOrInterface();
-    JPrimitiveType asPrimitive = type.isPrimitive();
-    if (asClass != null) {
-      return getBinaryName(asClass);
-    } else if (asPrimitive != null) {
-      return asPrimitive.getQualifiedSourceName();
-    } else if (asArray != null) {
-      JType componentType = asArray.getComponentType();
-      return getBinaryOrPrimitiveName(componentType) + "[]";
-    } else {
-      throw new InternalCompilerException("Cannot create binary name for "
-          + type.getQualifiedSourceName());
-    }
-  }
-
   /**
    * Returns the compilationUnit corresponding to the className. For nested
    * classes, the unit corresponding to the top level type is returned.
@@ -1212,6 +801,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/DispatchClassInfo.java b/dev/core/src/com/google/gwt/dev/shell/DispatchClassInfo.java
index 27819b3..9fecfa2 100644
--- a/dev/core/src/com/google/gwt/dev/shell/DispatchClassInfo.java
+++ b/dev/core/src/com/google/gwt/dev/shell/DispatchClassInfo.java
@@ -15,8 +15,10 @@
  */
 package com.google.gwt.dev.shell;
 
+import com.google.gwt.dev.shell.rewrite.OriginalJsniSignature;
 import com.google.gwt.dev.util.JsniRef;
 
+import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Member;
@@ -153,6 +155,21 @@
     String name;
     Class<?>[] paramTypes;
 
+    if (member instanceof AccessibleObject) {
+      AccessibleObject accessibleObject = (AccessibleObject) member;
+      OriginalJsniSignature signature = accessibleObject.getAnnotation(OriginalJsniSignature.class);
+      if (signature != null) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(signature.name());
+        if (wildcardParamList) {
+          sb.append("(*)");
+        } else {
+          sb.append(signature.paramList());
+        }
+        return sb.toString();
+      }
+    }
+
     if (member instanceof Field) {
       return member.getName();
     } else if (member instanceof SyntheticClassMember) {
@@ -168,7 +185,7 @@
           + member.getClass().getName());
     }
 
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     sb.append(name);
     sb.append("(");
     if (wildcardParamList) {
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/DebugAnalyzerAdapter.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/DebugAnalyzerAdapter.java
new file mode 100644
index 0000000..44bbf8a
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/DebugAnalyzerAdapter.java
@@ -0,0 +1,130 @@
+/*
+ * 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.EXTRA_DEBUG_DATA;
+
+import com.google.gwt.dev.asm.Attribute;
+import com.google.gwt.dev.asm.ByteVector;
+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.commons.AnalyzerAdapter;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A utility base class that allows rewriting passes to record label-based
+ * messages in the emitted bytecode.
+ */
+class DebugAnalyzerAdapter extends AnalyzerAdapter {
+  /**
+   * Used to record debugging data generated by {@link #recordDebugData}.
+   * 
+   * @see #visitEnd()
+   */
+  private static class DebugAttribute extends Attribute {
+    private final LinkedHashMap<Label, String> debugData;
+
+    private DebugAttribute(String name, LinkedHashMap<Label, String> debugData) {
+      super(name);
+      this.debugData = debugData;
+    }
+
+    @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;
+    }
+  }
+
+  /**
+   * 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 final LinkedHashMap<Label, String> debugData = EXTRA_DEBUG_DATA
+      ? new LinkedHashMap<Label, String>() : null;
+
+  protected DebugAnalyzerAdapter(String owner, int access, String name,
+      String desc, MethodVisitor mv) {
+    super(owner, access, name, desc, mv);
+  }
+
+  /**
+   * Record debugging data, if any, in an extra attribute on the method.
+   */
+  @Override
+  public void visitEnd() {
+    if (EXTRA_DEBUG_DATA && !debugData.isEmpty()) {
+      super.visitAttribute(new DebugAttribute(getClass().getCanonicalName(),
+          debugData));
+    }
+    super.visitEnd();
+  }
+
+  /**
+   * 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.
+   */
+  protected void recordDebugData(String message) {
+    if (EXTRA_DEBUG_DATA) {
+      Label castLocation = new Label();
+      debugData.put(castLocation, message);
+      super.visitLabel(castLocation);
+    }
+  }
+}
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..ca1f488 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,26 @@
  */
 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.asm.Type;
 import com.google.gwt.dev.shell.JsValueGlue;
+import com.google.gwt.dev.util.Name.BinaryName;
+import com.google.gwt.dev.util.Name.InternalName;
+import com.google.gwt.dev.util.collect.Lists;
 
-import java.util.Collections;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
-import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
-import java.util.SortedSet;
 
 /**
  * This class performs any and all byte code rewriting needed to make hosted
@@ -38,25 +42,168 @@
  * <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 {
+    /**
+     * Used by {@link #getConstructorDisambiguator}.
+     */
+    private static final String[] EMPTY_STRING = new String[0];
+
+    private final Map<String, String[]> arrayDisambiguations = new HashMap<String, String[]>();
+
+    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(BinaryName.toInternalName(intf.getQualifiedBinaryName()));
+        queue.addAll(Arrays.asList(intf.getImplementedInterfaces()));
+      }
+
+      String[] array = toReturn.toArray(new String[toReturn.size()]);
+      Arrays.sort(array);
+      return array;
+    }
+
+    /**
+     * In order to be able to upcast all JSO subtype arrays to JavaScriptObject
+     * arrays, it is necessary to be able to maintain distinguishing method
+     * descriptors. If the given descriptor will be affected by the array upcast
+     * transformation, this method will return an array containing the internal
+     * names of any additional types that should be appended to the descriptor.
+     */
+    public String[] getArrayDisambiguator(String desc) {
+      String[] cached = arrayDisambiguations.get(desc);
+      if (cached != null) {
+        return cached;
+      }
+
+      List<String> toReturn = Lists.create();
+      for (Type t : Type.getArgumentTypes(desc)) {
+        if (t.getSort() == Type.ARRAY
+            && t.getElementType().getSort() == Type.OBJECT) {
+          String leafName = t.getElementType().getInternalName();
+          if (isJsoOrSubtype(leafName)) {
+            String disambiguatotr = DISAMBIGUATOR_TYPE_INTERNAL_NAME + "$"
+                + InternalName.toIdentifier(leafName);
+            toReturn = Lists.add(toReturn, disambiguatotr);
+          }
+        }
+      }
+
+      String[] array;
+      if (toReturn.isEmpty()) {
+        array = EMPTY_STRING;
+      } else {
+        array = toReturn.toArray(new String[toReturn.size()]);
+      }
+      arrayDisambiguations.put(desc, 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 +212,68 @@
    */
 
   /**
-   * 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 #writeConstructorDisambiguationType}.
    */
-  public interface InstanceMethodOracle {
-
-    /**
-     * 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);
-  }
+  public static final String DISAMBIGUATOR_TYPE_NAME = "com.google.gwt.dev.shell.rewrite.$Disambiguator";
 
   /**
-   * Contains data about how SingleJsoImpl methods are to be dispatched.
+   * Used in CompilingClassLoader to trigger a call to
+   * {@link #writeSingleJsoImplAdjunct}.
    */
-  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);
+  public static final String SINGLE_JSO_IMPL_ADJUNCT_SUFFIX = "$$singleJsoImpl";
 
-    /**
-     * 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);
+  static final String CANONICAL_FIELD = "canonicalJso";
 
-    /**
-     * Returns all of the mangled method names for SingleJsoImpl methods.
-     */
-    SortedSet<String> getMangledNames();
+  static final String DISAMBIGUATOR_TYPE_INTERNAL_NAME = BinaryName.toInternalName(DISAMBIGUATOR_TYPE_NAME);
 
-    /**
-     * 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 JAVASCRIPTOBJECT_DESC = BinaryName.toInternalName(JsValueGlue.JSO_CLASS);
 
   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) {
-    return jsoSubtype.replace('.', '/');
-  }
+  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 = Type.getInternalName(SingleJsoImplSupport.class);
+
+  static final int SYSTEM_CLASS_VERSION = Double.parseDouble(System.getProperty("java.class.version")) < Opcodes.V1_6
+      ? Opcodes.V1_5 : Opcodes.V1_6;
 
   /**
-   * 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 = BinaryName.toInternalName(className);
 
     // The ASM model is to chain a bunch of visitors together.
     ClassWriter writer = new ClassWriter(0);
@@ -227,49 +282,75 @@
     // 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 RewriteJsoArrays(v, rewriterOracle);
+
+    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 is used to disambiguate constructors that have
+   * JSO subtype array parameters that have been upcast to JavaScriptObject
+   * arrays.
+   */
+  public byte[] writeConstructorDisambiguationType(String className) {
+    // Keep the synthetic class creation code next to where its consumed
+    return RewriteJsoArrays.writeConstructorDisambiguationType(className);
+  }
 
-    // The ASM model is to chain a bunch of visitors together.
-    ClassWriter writer = new ClassWriter(0);
-    ClassVisitor v = writer;
+  /**
+   * 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);
+  }
 
-    // v = new CheckClassAdapter(v);
-    // v = new TraceClassVisitor(v, new PrintWriter(System.out));
+  /**
+   * 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;
 
-    String[] interfaces;
-    // TODO(bov): something better than linear?
-    if (superDescs.contains("java/lang/Object")) {
-      interfaces = null;
-    } else {
-      interfaces = superDescs.toArray(new String[superDescs.size()]);
+      // 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);
+        }
+      };
+
+      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/OriginalJsniSignature.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/OriginalJsniSignature.java
new file mode 100644
index 0000000..74d924a
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/OriginalJsniSignature.java
@@ -0,0 +1,39 @@
+/*
+ * 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 java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation will be applied to a method or constructor by
+ * {@link HostedModeClassRewriter} if the method signature of a rewritten method
+ * differs from the original source. This annotation is necessary because
+ * dispatch id allocation is performed reflectively, after the class rewriting
+ * may have altered the method.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = {ElementType.CONSTRUCTOR, ElementType.METHOD})
+public @interface OriginalJsniSignature {
+  String name();
+
+  /**
+   * This is the method descriptor, minus the return type.
+   */
+  String paramList();
+}
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsoArrays.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsoArrays.java
new file mode 100644
index 0000000..db716e3
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsoArrays.java
@@ -0,0 +1,388 @@
+/*
+ * 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.DISAMBIGUATOR_TYPE_INTERNAL_NAME;
+import static com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.SYSTEM_CLASS_VERSION;
+
+import com.google.gwt.dev.asm.AnnotationVisitor;
+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.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.RewriterOracle;
+import com.google.gwt.dev.util.Name.InternalName;
+
+import java.util.Arrays;
+
+/**
+ * The object of this pass is to turn all JSO subtype arrays into
+ * JavaScriptObject arrays. This allows JSO arrays to participate in arbitrary
+ * cross-casting.
+ */
+public class RewriteJsoArrays extends ClassAdapter {
+
+  private static final String ORIGINAL_JSNI_SIGNATURE_DESC = Type.getDescriptor(OriginalJsniSignature.class);
+
+  /**
+   * Performs upcasts on JSO subtype arrays.
+   */
+  private class UpcastAdapter extends DebugAnalyzerAdapter {
+
+    private final int minLocals;
+    private int minStack;
+
+    public UpcastAdapter(String owner, int access, String name, String desc,
+        MethodVisitor mv, int minLocals) {
+      super(owner, access, name, desc, mv);
+      this.minLocals = minLocals;
+    }
+
+    /**
+     * Upcast field access.
+     */
+    @Override
+    public void visitFieldInsn(int opcode, String owner, String name,
+        String desc) {
+      Type t = Type.getType(desc);
+      if (t.getSort() == Type.ARRAY) {
+        t = upcastJsoType(t);
+        if (t != null) {
+          desc = t.getDescriptor();
+        }
+      }
+      super.visitFieldInsn(opcode, owner, name, desc);
+    }
+
+    /**
+     * Fix JSO array types in framing data to keep the verifier and other
+     * AnalyzerAdapters synced up.
+     */
+    @Override
+    public void visitFrame(int type, int nLocal, Object[] local, int nStack,
+        Object[] stack) {
+      fixFrameData(local);
+      fixFrameData(stack);
+      super.visitFrame(type, nLocal, local, nStack, stack);
+    }
+
+    /**
+     * Keep the debugger from going off the rails.
+     */
+    @Override
+    public void visitLocalVariable(String name, String desc, String signature,
+        Label start, Label end, int index) {
+      Type t = Type.getType(desc);
+      if (t.getSort() == Type.ARRAY) {
+        t = upcastJsoType(t);
+        if (t != null) {
+          desc = t.getInternalName();
+        }
+      }
+      super.visitLocalVariable(name, desc, signature, start, end, index);
+    }
+
+    /**
+     * We need to override the number of locals when rewriting a constructor to
+     * account for synthetic disambiguation parameters. The null argument to the
+     * disambiguated constructor might require adjustment of the stack size.
+     */
+    @Override
+    public void visitMaxs(int maxStack, int maxLocals) {
+      super.visitMaxs(Math.max(minStack, maxStack), Math.max(minLocals,
+          maxLocals));
+    }
+
+    /**
+     * Fix the descriptors used by method invocations to account for the upcast
+     * array types. Initializers are handled specially, since we can't simply
+     * change their name to provide disambiguation. Instead, we add an
+     * additional null argument of a synthetic type.
+     */
+    @Override
+    public void visitMethodInsn(int opcode, String owner, String name,
+        String desc) {
+      switch (opcode) {
+        case Opcodes.INVOKESPECIAL: {
+          if ("<init>".equals(name)) {
+            String[] disambiguator = rewriterOracle.getArrayDisambiguator(desc);
+            // Widen any JSO arrays.
+            Method m = upcastMethod(name, desc);
+            desc = m == null ? desc : m.getDescriptor();
+            if (disambiguator.length != 0) {
+              desc = addDisambiguator(desc, disambiguator);
+              // Add bogus values to the stack
+              recordDebugData("Constructor disambiguation "
+                  + Arrays.asList(disambiguator));
+              for (int i = 0, j = disambiguator.length; i < j; i++) {
+                super.visitInsn(Opcodes.ACONST_NULL);
+              }
+              minStack = Math.max(minStack, stack.size());
+            }
+            break;
+          }
+          // Intentional fallthrough for non-init methods
+        }
+        case Opcodes.INVOKEINTERFACE:
+        case Opcodes.INVOKESTATIC:
+        case Opcodes.INVOKEVIRTUAL: {
+          Method m = upcastMethod(name, desc);
+          if (m != null) {
+            recordDebugData("Replaced method call " + name + " " + desc
+                + " with " + m.toString());
+            name = m.getName();
+            desc = m.getDescriptor();
+          }
+          break;
+        }
+        default:
+          throw new RuntimeException("Unhandled method instruction " + opcode);
+      }
+      super.visitMethodInsn(opcode, owner, name, desc);
+    }
+
+    /**
+     * Fix the types of multidimensional arrays allocations.
+     */
+    @Override
+    public void visitMultiANewArrayInsn(String desc, int dims) {
+      Type replacement = upcastJsoType(Type.getObjectType(desc));
+      if (replacement != null) {
+        recordDebugData("Widened JSO array allocation");
+        desc = replacement.getInternalName();
+      }
+      super.visitMultiANewArrayInsn(desc, dims);
+    }
+
+    /**
+     * Convert all JSO subtype array allocations into an allocation of a
+     * JavaScriptObject array.
+     */
+    @Override
+    public void visitTypeInsn(int opcode, String internalName) {
+      if (opcode == Opcodes.ANEWARRAY) {
+        Type replacement = upcastJsoType(Type.getObjectType(internalName));
+        if (replacement != null) {
+          recordDebugData("Widened JSO array allocation");
+          internalName = replacement.getInternalName();
+        }
+      }
+      super.visitTypeInsn(opcode, internalName);
+    }
+
+    /**
+     * Utility method used by {@link #visitFrame} to process the stack and local
+     * arrays.
+     */
+    private void fixFrameData(Object[] data) {
+      for (int i = 0, j = data.length; i < j; i++) {
+        if (data[i] instanceof String) {
+          Type t = Type.getObjectType((String) data[i]);
+          if (t.getSort() == Type.ARRAY) {
+            t = upcastJsoType(t);
+            if (t != null) {
+              data[i] = t.getInternalName();
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Creates an empty interface type.
+   */
+  static byte[] writeConstructorDisambiguationType(String className) {
+    String internalName = className.replace('.', '/');
+    assert internalName.startsWith(DISAMBIGUATOR_TYPE_INTERNAL_NAME) : "Bad className "
+        + className;
+
+    ClassWriter writer = new ClassWriter(0);
+
+    writer.visit(SYSTEM_CLASS_VERSION, Opcodes.ACC_PUBLIC
+        | Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE, internalName, null,
+        "java/lang/Object", null);
+
+    writer.visitEnd();
+    return writer.toByteArray();
+  }
+
+  /**
+   * Records the class currently being processed.
+   */
+  private String owner;
+  private final RewriterOracle rewriterOracle;
+
+  public RewriteJsoArrays(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) {
+    super.visit(version, access, name, signature, superName, interfaces);
+    owner = name;
+  }
+
+  /**
+   * Widen all fields of a JSO array type to JSO[].
+   */
+  @Override
+  public FieldVisitor visitField(int access, String name, String desc,
+      String signature, Object value) {
+    Type t = Type.getType(desc);
+    if (t.getSort() == Type.ARRAY) {
+      Type newType = upcastJsoType(t);
+      if (newType != null) {
+        desc = newType.getDescriptor();
+      }
+    }
+    return super.visitField(access, name, desc, signature, value);
+  }
+
+  /**
+   * Widen all JSO array paramaters to JSO[]. Constructors may have a
+   * disambiguator type added to their parameter list.
+   */
+  @Override
+  public MethodVisitor visitMethod(int access, String name, String desc,
+      String signature, String[] exceptions) {
+    int minLocals = 0;
+    String originalJsniName = name;
+    String originalJsniDesc = desc;
+    Method upcast = upcastMethod(name, desc);
+
+    if (upcast != null) {
+      if ("<init>".equals(name)) {
+        String[] disambiguator = rewriterOracle.getArrayDisambiguator(desc);
+        desc = upcast.getDescriptor();
+        if (disambiguator.length != 0) {
+          desc = addDisambiguator(desc, disambiguator);
+          // +1 for this
+          minLocals = Type.getArgumentTypes(desc).length + 1;
+        }
+        originalJsniName = "new";
+      } else {
+        name = upcast.getName();
+        desc = upcast.getDescriptor();
+      }
+    }
+
+    MethodVisitor mv = super.visitMethod(access, name, desc, signature,
+        exceptions);
+    if (mv != null) {
+      // Record the original JSNI signature if we've mangled the method
+      if (upcast != null) {
+        AnnotationVisitor av = mv.visitAnnotation(ORIGINAL_JSNI_SIGNATURE_DESC,
+            true);
+        if (av != null) {
+          av.visit("name", originalJsniName);
+          // Strip the return type
+          av.visit("paramList", originalJsniDesc.substring(0,
+              originalJsniDesc.indexOf(')') + 1));
+          av.visitEnd();
+        }
+      }
+      mv = new UpcastAdapter(owner, access, name, desc, mv, minLocals);
+    }
+    return mv;
+  }
+
+  /**
+   * Add disambiguator types as the last parameters of a method descriptor.
+   */
+  private String addDisambiguator(String desc, String[] disambiguator) {
+    int idx = desc.indexOf(')');
+    StringBuilder sb = new StringBuilder();
+    sb.append(desc.substring(0, idx));
+    for (String d : disambiguator) {
+      sb.append("L").append(d).append(";");
+    }
+    sb.append(desc.substring(idx));
+    return sb.toString();
+  }
+
+  /**
+   * Utility method for constructing a descriptor. If the given type is a JSO
+   * subtype array, the appropriate JavaScriptObject array type will be appended
+   * to the descriptor and this method will return <code>true</code>. Otherwise,
+   * this method will simply append the type to the descriptor and return
+   * <code>false</code>.
+   */
+  private boolean appendTypeMaybeUpcast(StringBuilder newDesc, Type type) {
+    if (type.getSort() == Type.ARRAY) {
+      Type newType = upcastJsoType(type);
+      if (newType != null) {
+        newDesc.append(newType.getDescriptor());
+        return true;
+      }
+    }
+    newDesc.append(type.getDescriptor());
+    return false;
+  }
+
+  /**
+   * Calls {@link RewriteJsoCasts#upcastJsoType} with the instance's
+   * {@link #rewriterOracle}.
+   */
+  private Type upcastJsoType(Type type) {
+    return RewriteJsoCasts.upcastJsoType(rewriterOracle, type);
+  }
+
+  /**
+   * Determine if a descriptor contains references to JSO subtype arrays. If so,
+   * returns an upcast descriptor and a guaranteed-unique name for the method.
+   * Otherwise, this method returns <code>null</code>.
+   */
+  private Method upcastMethod(String name, String desc) {
+    boolean didChange = false;
+    StringBuilder newName = new StringBuilder(name);
+    StringBuilder newDesc = new StringBuilder("(");
+
+    for (Type arg : Type.getArgumentTypes(desc)) {
+      // Add the arguments, one at a time, to the new descriptor
+      if (appendTypeMaybeUpcast(newDesc, arg)) {
+        didChange = true;
+        /*
+         * Add the original type to the method name. We don't need to worry
+         * about the number of parameters or their relative positions when
+         * constructing the name, because that information is still in the
+         * method descriptor.
+         */
+        newName.append("_").append(
+            InternalName.toIdentifier(arg.getElementType().getInternalName())).append(
+            "_").append(arg.getDimensions());
+      }
+    }
+    newDesc.append(")");
+
+    Type returnType = Type.getReturnType(desc);
+    if (appendTypeMaybeUpcast(newDesc, returnType)) {
+      didChange = true;
+    }
+
+    if (!didChange) {
+      return null;
+    }
+    return new Method(newName.toString(), newDesc.toString());
+  }
+}
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..267fe42
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsoCasts.java
@@ -0,0 +1,557 @@
+/*
+ * 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.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.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.Type;
+import com.google.gwt.dev.asm.commons.Method;
+import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.RewriterOracle;
+
+/**
+ * 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 DebugAnalyzerAdapter {
+    /*
+     * 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 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();
+      if (returnType.getSort() == Type.OBJECT) {
+        String internalName = returnType.getInternalName();
+        boolean maybeCanonicalize = rewriterOracle.jsoAssignmentRequiresCanonicalization(internalName);
+        boolean maybeRewrap = rewriterOracle.isJsoOrSubtype(internalName);
+        returnNeedsCanonical = maybeCanonicalize || maybeRewrap;
+      } else {
+        returnNeedsCanonical = false;
+      }
+    }
+
+    @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.
+           */
+          recordDebugData("Canonicalized object for getClass");
+          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 ("cast".equals(name)
+          && ("()L" + JAVASCRIPTOBJECT_DESC + ";").equals(desc)
+          && rewriterOracle.isJsoOrSubtype(owner)) {
+        // Remove calls to cast, since they trigger NPEs in older code
+        recordDebugData("Removed call to JSO.cast()");
+        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);
+      boolean isInstance = opcode == Opcodes.INVOKEINTERFACE
+          || opcode == Opcodes.INVOKEVIRTUAL;
+      Type[] args;
+      if (isInstance) {
+        /*
+         * Treat invocations of non-static dispatch as though they were static
+         * methods that have an extra "this" argument that is the type of the
+         * instance that's expected.
+         */
+        Type[] actualArgs = m.getArgumentTypes();
+        args = new Type[actualArgs.length + 1];
+        args[0] = Type.getObjectType(owner);
+        System.arraycopy(actualArgs, 0, args, 1, actualArgs.length);
+      } else {
+        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 or
+         * rewrapping.
+         */
+        if (arg.getSort() != Type.OBJECT) {
+          continue;
+        }
+        boolean maybeCanonicalize = rewriterOracle.jsoAssignmentRequiresCanonicalization(arg.getInternalName());
+        boolean maybeRewrap = rewriterOracle.couldContainJso(arg.getInternalName());
+        if (!maybeCanonicalize && !maybeRewrap) {
+          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) {
+        recordDebugData("Fixed arguments to method invocation");
+        // 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);
+        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());
+      }
+
+      // 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) {
+              recordDebugData("Upcast JSO array checkcast from "
+                  + parsed.getInternalName());
+              type = t.getInternalName();
+            }
+          }
+          // Intentional fall-through to super invocation below
+          break;
+
+        case Opcodes.INSTANCEOF: {
+          String internalName = parsed.getInternalName();
+          if (rewriterOracle.isInterface(internalName)
+              && rewriterOracle.couldContainJso(internalName)) {
+            recordDebugData("SingleJsoImpl instanceof check for "
+                + internalName);
+            /*
+             * 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
+          recordDebugData("Upcast instanceof from " + internalName);
+          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;
+
+      recordDebugData(topType + " ->  " + internalName);
+
+      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>.
+   */
+  static Type upcastJsoType(RewriterOracle rewriterOracle, 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());
+  }
+
+  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;
+  }
+
+  /**
+   * Convenience method.
+   */
+  private Type upcastJsoType(Type type) {
+    return upcastJsoType(rewriterOracle, type);
+  }
+}
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..36a182e
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/SingleJsoImplSupport.java
@@ -0,0 +1,270 @@
+/*
+ * 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.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);
+  }
+
+  /**
+   * Called by synthetic code when the object on the stack might be a JSO
+   * wrapper and we want the canonical object.
+   */
+  public static Object ensureCanonical(Object o) {
+    if (o == null) {
+      return null;
+    }
+
+    Class<?> jsoClass = getJsoClass(o);
+    if (jsoClass.isInstance(o)) {
+      Exception ex;
+      try {
+        return jsoClass.getField(CANONICAL_FIELD).get(o);
+      } catch (IllegalArgumentException e) {
+        ex = e;
+      } catch (SecurityException e) {
+        ex = e;
+      } catch (IllegalAccessException e) {
+        ex = e;
+      } catch (NoSuchFieldException e) {
+        ex = e;
+      }
+      throw new RuntimeException("Unable to determine canonical object", ex);
+    }
+
+    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/dev/core/src/com/google/gwt/dev/util/Name.java b/dev/core/src/com/google/gwt/dev/util/Name.java
index 279a744..647a9f9 100644
--- a/dev/core/src/com/google/gwt/dev/util/Name.java
+++ b/dev/core/src/com/google/gwt/dev/util/Name.java
@@ -165,7 +165,12 @@
         assert isInternalName(internalName);
         return internalName.replace('/', '.');
       }
-      
+
+      public static String toIdentifier(String internalName) {
+        assert isInternalName(internalName);
+        return internalName.replace("_", "_1").replace('/', '_');
+      }
+
       public static String toSourceName(String internalName) {
         assert isInternalName(internalName);
         // don't change a trailing $ or slash to a .
diff --git a/user/src/com/google/gwt/i18n/client/CurrencyData.java b/user/src/com/google/gwt/i18n/client/CurrencyData.java
index e4eda01..2b11211 100644
--- a/user/src/com/google/gwt/i18n/client/CurrencyData.java
+++ b/user/src/com/google/gwt/i18n/client/CurrencyData.java
@@ -15,9 +15,13 @@
  */
 package com.google.gwt.i18n.client;
 
+import com.google.gwt.core.client.SingleJsoImpl;
+import com.google.gwt.i18n.client.impl.CurrencyDataImpl;
+
 /**
  * Information about a currency.
  */
+@SingleJsoImpl(CurrencyDataImpl.class)
 public interface CurrencyData {
 
   /**
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..93f9e3f 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,54 @@
     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());
+
+    // Test Collection.toArray(), since the behavior depends on the array type
+    Object[] objectArray = fooList.toArray(new Object[0]);
+    assertSame(foo[0], objectArray[0]);
+    JavaScriptObject[] jsArray = fooList.toArray(new JavaScriptObject[0]);
+    assertSame(foo[0], jsArray[0]);
+    Foo[] fooArray = fooList.toArray(new Foo[0]);
+    assertSame(foo[0], fooArray[0]);
+    acceptsFooArray(fooArray, 1);
+
+    // Test System.arrayCopy to make sure cross-JSO cast appears to work
+    Bar[] bar2 = new Bar[1];
+    System.arraycopy(foo, 0, bar2, 0, 1);
+    assertSame(foo[0], bar[0]);
+
+    try {
+      String[] bad = new String[1];
+      System.arraycopy(foo, 0, bad, 0, 1);
+      fail("Should have thrown ArrayStoreException");
+    } catch (ArrayStoreException expected) {
+    }
+  }
+
+  private void acceptsFooArray(Foo[] array, int length) {
+    assertEquals(length, array.length);
+  }
+
   public void testArrayStore() {
     JavaScriptObject[] jsoArray = new JavaScriptObject[1];
     jsoArray[0] = makeJSO();
@@ -374,6 +442,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 +508,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 +535,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 +550,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 +654,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..b7d4927 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) {
@@ -557,6 +582,10 @@
       fail("b");
     }
   }
+  
+  public void testDispatchWithWidenedArrays() {
+    acceptsSimpleArrayAndInvokes(makeSimple(), makeSimple(), makeSimple());
+  }
 
   public void testDualCase() {
     // Direct dispatch
@@ -604,7 +633,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 +665,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 +1003,7 @@
   }
 
   public void testStaticCallsToSubclasses() {
+    JsoCallsStaticMethodInSubclass a = JavaScriptObject.createObject().cast();
     Object o = "String";
     assertEquals(String.class, o.getClass());
     o = JavaScriptObject.createObject();
@@ -791,9 +1084,66 @@
     }
   }
 
+  /**
+   * 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 void acceptsSimpleArrayAndInvokes(Simple... simples) {
+    assertEquals(3, simples.length);
+    for (Simple s : simples) {
+      assertEquals("a", s.a());
+    }
+  }
+
+  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;
+  }-*/;
 }
diff --git a/user/test/com/google/gwt/dev/jjs/test/jsointfs/JsoInterfaceWithUnreferencedImpl.java b/user/test/com/google/gwt/dev/jjs/test/jsointfs/JsoInterfaceWithUnreferencedImpl.java
index 42a7e26..8a281e0 100644
--- a/user/test/com/google/gwt/dev/jjs/test/jsointfs/JsoInterfaceWithUnreferencedImpl.java
+++ b/user/test/com/google/gwt/dev/jjs/test/jsointfs/JsoInterfaceWithUnreferencedImpl.java
@@ -15,10 +15,14 @@
  */
 package com.google.gwt.dev.jjs.test.jsointfs;
 
+import com.google.gwt.core.client.SingleJsoImpl;
+import com.google.gwt.dev.jjs.test.jsoimpls.UnreferencedImplOfJsoInterface;
+
 /**
  * This class exists for the purpose of testing JSO implementation types that
  * aren't specifically referenced in any Java source.
  */
+@SingleJsoImpl(UnreferencedImplOfJsoInterface.class)
 public interface JsoInterfaceWithUnreferencedImpl {
   boolean isOk();
 }
