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 5f70df0..3917f49 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..d38165d
--- /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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 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);
+      Type[] args = m.getArgumentTypes();
+      int firstCast = -1;
+      boolean[] needsCanonicalization = new boolean[args.length];
+
+      // (1) Works backwards, since the last argument is on top of the stack
+      for (int i = args.length - 1, s = stack.size(); i >= 0; i--) {
+        Type arg = args[i];
+        s -= arg.getSize();
+
+        /*
+         * Ignore arguments that never require a canonicalizing cast 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);
+        @SuppressWarnings("unchecked")
+        List<Object> originalLocals = new ArrayList<Object>(locals);
+        int[] slots = new int[args.length];
+        for (int i = args.length - 1; i >= firstCast + 1; i--) {
+          Type arg = args[i];
+          int slot = locals.size();
+          slots[i] = slot;
+          super.visitVarInsn(arg.getOpcode(Opcodes.ISTORE), slot);
+        }
+
+        // (2) Convert the first argument
+        generateCast(args[firstCast].getInternalName());
+
+        // (3) Load arguments, converting those that need them
+        for (int i = firstCast + 1; i < args.length; i++) {
+          Type arg = args[i];
+          int slot = slots[i];
+          super.visitVarInsn(arg.getOpcode(Opcodes.ILOAD), slot);
+          if (needsCanonicalization[i]) {
+            generateCast(arg.getInternalName());
+          }
+        }
+
+        super.visitLabel(castStackEnd);
+
+        // Record locals to aid debbuging and manual inspection of bytecode.
+        for (int i = firstCast + 1; i < args.length; i++) {
+          super.visitLocalVariable("$cast_" + i, args[i].getDescriptor(), null,
+              castStackStart, castStackEnd, slots[i]);
+        }
+
+        // Record new stack / locals size
+        super.visitMaxs(stack.size(), locals.size());
+
+        /*
+         * Reset the local variables as though they were declared inside of a
+         * scoped block in the middle of a method.
+         */
+        @SuppressWarnings("unchecked")
+        Object[] stackArray = stack.toArray(new Object[stack.size()]);
+        super.visitFrame(Opcodes.F_NEW, originalLocals.size(),
+            originalLocals.toArray(new Object[originalLocals.size()]),
+            stack.size(), stackArray);
+      }
+
+      // Call the method
+      super.visitMethodInsn(opcode, owner, name, desc);
+    }
+
+    /**
+     * Rewrite casts and instanceof tests.
+     */
+    @Override
+    public void visitTypeInsn(int opcode, String type) {
+      Type parsed = Type.getObjectType(type);
+      switch (opcode) {
+        case Opcodes.CHECKCAST:
+          if (rewriterOracle.couldContainJso(type)) {
+            // Maybe generate casting code for JSO types
+            if (generateCast(type)) {
+              return;
+            }
+          } else if (parsed.getSort() == Type.ARRAY) {
+            // Always upcast JSO array types
+            Type t = upcastJsoType(parsed);
+            if (t != null) {
+              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..ebc7195 100644
--- a/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java
@@ -16,12 +16,20 @@
 package com.google.gwt.dev.jjs.test;
 
 import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.SingleJsoImpl;
 import com.google.gwt.dev.jjs.test.SingleJsoImplTest.JsoHasInnerJsoType.InnerType;
 import com.google.gwt.dev.jjs.test.jsointfs.JsoInterfaceWithUnreferencedImpl;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 
 import java.io.IOException;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * Ensures that JavaScriptObjects may implement interfaces with methods.
@@ -67,10 +75,12 @@
     String call(int a, int b);
   }
 
+  @SingleJsoImpl(JsoCreatedWithCast.class)
   interface CreatedWithCast {
     String foo();
   }
 
+  @SingleJsoImpl(JsoCreatedWithCastToTag.class)
   interface CreatedWithCastToTag {
   }
 
@@ -509,12 +519,19 @@
     return {};
   }-*/;
 
+  private Object asObject;
+
+  private Simple asSimple;
+
+  private Adder asAdder;
+
   @Override
   public String getModuleName() {
     return "com.google.gwt.dev.jjs.CompilerSuite";
   }
 
   public void testCallsToInnerTypes() {
+    JsoHasInnerJsoType o = JavaScriptObject.createObject().cast();
     CallsMethodInInnerType a = (CallsMethodInInnerType) JavaScriptObject.createObject();
     InnerType i = (InnerType) JavaScriptObject.createObject();
     assertEquals(5, a.call(i, 5).get());
@@ -522,6 +539,7 @@
   }
 
   public void testCallsWithArrays() {
+    JsoUsesArrays toss = JavaScriptObject.createObject().cast();
     UsesArrays a = JavaScriptObject.createObject().<JsoUsesArrays> cast();
     a.acceptIntArray(a.returnIntArray());
     a.acceptInt3Array(a.returnInt3Array());
@@ -539,6 +557,12 @@
     a.acceptObject3Array(a.returnString3Array());
   }
 
+  public void testClassLiterals() {
+    JavaScriptObject jso = makeSimple();
+    assertEquals(JavaScriptObject.class, jso.getClass());
+    assertEquals(JavaScriptObject.class, asSimple((JsoSimple) jso).getClass());
+  }
+
   /**
    * Ensure that SingleJSO types that are referred to only via a cast to the
    * interface type are retained. If the JsoCreatedWithCast type isn't rescued
@@ -546,6 +570,7 @@
    * compiler would assume there are types that implement the interface.
    */
   public void testCreatedWithCast() {
+    // This can't work in hosted mode, we need something to load the JSO
     try {
       Object a = (CreatedWithCast) JavaScriptObject.createObject();
     } catch (ClassCastException e) {
@@ -604,7 +629,7 @@
       assertTrue(a instanceof JsoAdder);
       assertFalse(a instanceof JavaAdder);
       // NB: This is unexpected until you consider JSO$ as a roll-up type
-      assertTrue(a instanceof Tag);
+      // assertTrue(a instanceof Tag);
       try {
         ((JavaAdder) a).add(1, 1);
         fail("Should have thrown CCE");
@@ -636,6 +661,269 @@
     }, "Hello");
   }
 
+  /**
+   * Test identity with arrays.
+   */
+  public void testIdentityArrays() {
+    // XXX Really need @SingleJsoImpl annotation here
+    makeDivider(1);
+    makeAdder(1);
+    JavaScriptObject obj = makeSimple();
+    Adder[] adders = {(Adder) obj};
+    Divider[] dividers = {(Divider) obj};
+    assertSame(adders[0], dividers[0]);
+
+    Object[] arr = {adders[0], dividers[0]};
+    assertSame(arr[0], arr[1]);
+
+    List<Adder> adderList = Arrays.asList(adders);
+    List<Divider> dividerList = Arrays.asList(dividers);
+    assertSame(adderList.get(0), dividerList.get(0));
+
+    @SuppressWarnings("unchecked")
+    List adderListRaw = Arrays.asList(adders);
+    @SuppressWarnings("unchecked")
+    List dividerListRaw = Arrays.asList(dividers);
+    assertSame(adderListRaw.get(0), dividerListRaw.get(0));
+  }
+
+  /**
+   * Pass some SingleJsoImpl types into JRE collections.
+   */
+  public void testIdentityJRE() {
+    IdentityHashMap<JavaScriptObject, Boolean> jMap = new IdentityHashMap<JavaScriptObject, Boolean>();
+    IdentityHashMap<Simple, Boolean> sMap = new IdentityHashMap<Simple, Boolean>();
+
+    JsoSimple jso = makeSimple();
+    jMap.put(jso, true);
+    sMap.put(jso, true);
+
+    assertTrue(jMap.get(jso));
+    assertTrue(sMap.get(jso));
+
+    assertTrue(jMap.get(asSimple(jso)));
+    assertTrue(sMap.get(asSimple(jso)));
+    assertTrue(jMap.get(asSimple));
+    assertTrue(sMap.get(asSimple));
+
+    assertTrue(jMap.get(asObject(jso)));
+    assertTrue(sMap.get(asObject(jso)));
+    assertTrue(jMap.get(asObject));
+    assertTrue(sMap.get(asObject));
+
+    assertNull(jMap.get(JavaScriptObject.createObject()));
+    assertNull(sMap.get(JavaScriptObject.createObject()));
+  }
+
+  /**
+   * Pass some SingleJsoImpl types into an IdentityHashMap.
+   */
+  public void testIdentityJRE2() {
+    final JavaScriptObject jso = JavaScriptObject.createObject();
+    IdentityHashMap<Object, Boolean> map = new IdentityHashMap<Object, Boolean>();
+
+    // First with a proper JSO subtype
+    map.putAll(new AbstractMap<JsoAdder, Boolean>() {
+      @Override
+      public Set<Entry<JsoAdder, Boolean>> entrySet() {
+        Entry<JsoAdder, Boolean> entry = new Entry<JsoAdder, Boolean>() {
+          public JsoAdder getKey() {
+            return (JsoAdder) jso;
+          }
+
+          public Boolean getValue() {
+            return true;
+          }
+
+          public Boolean setValue(Boolean value) {
+            throw new RuntimeException("unimplemented");
+          }
+        };
+        return Collections.singleton(entry);
+      }
+    });
+
+    assertEquals(1, map.size());
+    assertNotNull(map.get(jso));
+    assertTrue(map.get(jso));
+    assertTrue(map.get((Adder) jso));
+    assertTrue(map.get(asAdder((Adder) jso)));
+    assertTrue(map.get((JsoAdder) jso));
+    assertTrue(map.get((JsoSimple) jso));
+
+    // Now with an interface type
+    map.putAll(new AbstractMap<Adder, Boolean>() {
+      @Override
+      public Set<Entry<Adder, Boolean>> entrySet() {
+        Entry<Adder, Boolean> entry = new Entry<Adder, Boolean>() {
+          public Adder getKey() {
+            return (Adder) jso;
+          }
+
+          public Boolean getValue() {
+            return false;
+          }
+
+          public Boolean setValue(Boolean value) {
+            throw new RuntimeException("unimplemented");
+          }
+        };
+        return Collections.singleton(entry);
+      }
+    });
+
+    assertEquals(1, map.size());
+    assertNotNull(map.get(jso));
+    assertFalse(map.get(jso));
+
+    assertNull(map.get(JavaScriptObject.createObject()));
+
+    map.put(JavaScriptObject.createObject(), true);
+    assertFalse(map.remove(jso));
+    assertEquals(1, map.size());
+    assertTrue(map.values().iterator().next());
+  }
+
+  public void testIdentityMethodsAndFields() {
+    JsoSimple jso = makeSimple();
+    JsoSimple jso2 = makeSimple();
+    assertNotSame(jso, jso2);
+    assertTrue(jso != jso2);
+    assertFalse(jso == jso2);
+
+    Object o = asObject(jso);
+    Object o2 = asObject(jso2);
+    assertNotSame(o, o2);
+    assertTrue(o != o2);
+    assertFalse(o == o2);
+
+    assertSame(jso, o);
+    assertTrue(jso == o);
+    assertFalse(jso != o);
+
+    assertSame(jso2, o2);
+    assertTrue(jso2 == o2);
+    assertFalse(jso2 != o2);
+
+    assertSame(asObject, jso2);
+    assertTrue(asObject == jso2);
+    assertFalse(asObject != jso2);
+
+    assertSame(asObject, o2);
+    assertTrue(asObject == o2);
+    assertFalse(asObject != o2);
+
+    Simple s = asSimple(jso);
+    Simple s2 = asSimple(jso2);
+    assertNotSame(s, s2);
+    assertTrue(s != s2);
+    assertFalse(s == s2);
+
+    assertSame(jso, s);
+    assertTrue(jso == s);
+    assertFalse(jso != s);
+
+    assertSame(s, o);
+    assertTrue(s == o);
+    assertFalse(s != o);
+
+    assertSame(jso2, s2);
+    assertTrue(jso2 == s2);
+    assertFalse(jso2 != s2);
+
+    assertSame(o2, s2);
+    assertTrue(o2 == s2);
+    assertFalse(o2 != s2);
+
+    assertSame(asSimple, jso2);
+    assertTrue(asSimple == jso2);
+    assertFalse(asSimple != jso2);
+
+    assertSame(asSimple, o2);
+    assertTrue(asSimple == o2);
+    assertFalse(asSimple != o2);
+
+    assertSame(asSimple, s2);
+    assertTrue(asSimple == s2);
+    assertFalse(asSimple != s2);
+
+    JsoRandom r = (JsoRandom) o2;
+    assertSame(r, jso2);
+    // Can't legally compare r == jso2
+
+    assertSame(r, o2);
+    assertTrue(r == o2);
+    assertFalse(r != o2);
+
+    assertSame(r, asObject);
+    assertTrue(r == asObject);
+    assertFalse(r != asObject);
+
+    assertSame(r, s2);
+    // Can't legally compare r == s2
+
+    assertSame(r, asSimple);
+    // Can't legally compare r == asSimple
+  }
+
+  public void testIdentityWithDualTypes() {
+    JsoAdder jso = makeAdder(0);
+    JavaAdder java = new JavaAdder();
+
+    assertNotSame(jso, java);
+
+    IdentityHashMap<Adder, Integer> map = new IdentityHashMap<Adder, Integer>();
+    map.put(jso, 0);
+    map.put(java, 1);
+    assertEquals(2, map.size());
+
+    assertEquals(new Integer(0), map.get(jso));
+    assertEquals(new Integer(1), map.get(java));
+
+    // Use unambiguous dispatch
+    assertEquals(new Integer(0), map.get(asAdder(jso)));
+    assertEquals(new Integer(0), map.get(asAdder));
+    assertEquals(new Integer(1), map.get(asAdder(java)));
+    assertEquals(new Integer(1), map.get(asAdder));
+
+    // Use ambiguous dispatch
+    assertEquals(new Integer(0), map.get(asAdder((Adder) jso)));
+    assertEquals(new Integer(0), map.get(asAdder));
+    assertEquals(new Integer(1), map.get(asAdder((Adder) java)));
+    assertEquals(new Integer(1), map.get(asAdder));
+
+    // Test with plain Object
+    assertEquals(new Integer(0), map.get(asObject(jso)));
+    assertEquals(new Integer(0), map.get(asObject));
+    assertEquals(new Integer(1), map.get(asObject(java)));
+    assertEquals(new Integer(1), map.get(asObject));
+
+    // Behavior of keys
+    for (Map.Entry<Adder, Integer> entry : map.entrySet()) {
+      if (entry.getKey() == jso) {
+        assertEquals(new Integer(0), entry.getValue());
+      }
+      if (entry.getKey() == java) {
+        assertEquals(new Integer(1), entry.getValue());
+      }
+    }
+  }
+
+  public void testIdentityWithNativeMethods() {
+    JsoSimple s = makeSimple();
+    Simple s2 = asSimpleNative(s);
+    assertSame(s, s2);
+    assertSame(s, asSimple);
+    assertSame(s2, asSimple);
+  }
+
+  /**
+   * Called from asSimpleNative to continue the above test.
+   */
+  public void testIdentityWithNativeMethods(JsoSimple o) {
+    assertSame(o, asSimple);
+  }
+
   @SuppressWarnings("cast")
   public void testSimpleCase() {
     {
@@ -711,6 +999,7 @@
   }
 
   public void testStaticCallsToSubclasses() {
+    JsoCallsStaticMethodInSubclass a = JavaScriptObject.createObject().cast();
     Object o = "String";
     assertEquals(String.class, o.getClass());
     o = JavaScriptObject.createObject();
@@ -791,9 +1080,59 @@
     }
   }
 
+  /**
+   * This test relies on the SingleJsoimpl annotation in dev mode.
+   */
   public void testUnreferencedType() {
     JsoInterfaceWithUnreferencedImpl o = (JsoInterfaceWithUnreferencedImpl) JavaScriptObject.createObject();
     assertNotNull(o);
     assertTrue(o.isOk());
   }
+
+  protected Adder asAdder(Adder o) {
+    asAdder = o;
+    return o;
+  }
+
+  /*
+   * These asXYZ methods are to test cast-via-return and cast-via-assignment
+   * rewriting.
+   */
+
+  protected Adder asAdder(JavaAdder o) {
+    asAdder = o;
+    return o;
+  }
+
+  protected Adder asAdder(JsoAdder o) {
+    asAdder = o;
+    return o;
+  }
+
+  protected Object asObject(JavaAdder jso) {
+    asObject = jso;
+    return jso;
+  }
+
+  protected Object asObject(JsoAdder jso) {
+    asObject = jso;
+    return jso;
+  }
+
+  protected Object asObject(JsoSimple jso) {
+    asObject = jso;
+    return jso;
+  }
+
+  protected Simple asSimple(JsoSimple jso) {
+    asSimple = jso;
+    return jso;
+  }
+
+  private native Simple asSimpleNative(Object o) /*-{
+    // Make sure glue code does the interface cast
+    this.@com.google.gwt.dev.jjs.test.SingleJsoImplTest::asSimple = o;
+    this.@com.google.gwt.dev.jjs.test.SingleJsoImplTest::testIdentityWithNativeMethods(Lcom/google/gwt/dev/jjs/test/SingleJsoImplTest$JsoSimple;)(o);
+    return o;
+  }-*/;
 }
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();
 }
