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