TypeOracle becomes interfaces.

Refactors TypeOracle into a set of interfaces rather than concrete types.  Moves implementation into a new package.  Functionally, should be essentially the same.

This will allow for alternative implementations of TypeOracle, including server-side type models and GPE integration.

http://gwt-code-reviews.appspot.com/1113801/show


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9363 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JAbstractMethod.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JAbstractMethod.java
index 30cbadd..00c99a5 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JAbstractMethod.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JAbstractMethod.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,282 +15,53 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.dev.util.StringInterner;
-import com.google.gwt.dev.util.collect.Lists;
-
-import java.lang.annotation.Annotation;
-import java.util.List;
-import java.util.Map;
-
 /**
- * Common superclass for {@link JMethod} and {@link JConstructor}.
+ * Common interface for {@link JMethod} and {@link JConstructor}.
  */
 @SuppressWarnings("deprecation")
-public abstract class JAbstractMethod implements HasAnnotations, HasMetaData,
+public interface JAbstractMethod extends HasAnnotations, HasMetaData,
     HasTypeParameters {
 
-  private final Annotations annotations;
-
-  private boolean isVarArgs = false;
-
-  private int modifierBits;
-
-  private final String name;
-
-  private List<JParameter> params = Lists.create();
-
-  private String[] realParameterNames = null;
-
-  private List<JType> thrownTypes = Lists.create();
-
-  private List<JTypeParameter> typeParams = Lists.create();
-
-  JAbstractMethod(JAbstractMethod srcMethod) {
-    this.annotations = new Annotations(srcMethod.annotations);
-    this.isVarArgs = srcMethod.isVarArgs;
-    this.modifierBits = srcMethod.modifierBits;
-    this.name = srcMethod.name;
-  }
-
-  // Only the builder can construct
-  JAbstractMethod(String name,
-      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
-      JTypeParameter[] jtypeParameters) {
-    this.name = StringInterner.get().intern(name);
-    annotations = new Annotations(declaredAnnotations);
-
-    if (jtypeParameters != null) {
-      typeParams = Lists.create(jtypeParameters);
-    }
-  }
-
-  public JParameter findParameter(String name) {
-    for (JParameter param : params) {
-      if (param.getName().equals(name)) {
-        return param;
-      }
-    }
-    return null;
-  }
-
-  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    return annotations.getAnnotation(annotationClass);
-  }
+  JParameter findParameter(String name);
 
   /**
    * Gets the type in which this method or constructor was declared.
    */
-  public abstract JClassType getEnclosingType();
+  JClassType getEnclosingType();
 
-  public JType[] getErasedParameterTypes() {
-    JType[] types = new JType[params.size()];
-    for (int i = 0; i < types.length; ++i) {
-      types[i] = params.get(i).getType().getErasedType();
-    }
-    return types;
-  }
-  
+  JType[] getErasedParameterTypes();
+
   /**
    * Returns a string contating a JSNI reference to the method.
    * 
    * @return <code>@package.Class::method(Lpackage/Param;...)</code>
    */
-  public abstract String getJsniSignature();
+  String getJsniSignature();
 
-  @Deprecated
-  public final String[][] getMetaData(String tagName) {
-    return TypeOracle.NO_STRING_ARR_ARR;
-  }
+  String getName();
 
-  @Deprecated
-  public final String[] getMetaDataTags() {
-    return TypeOracle.NO_STRINGS;
-  }
+  JParameter[] getParameters();
 
-  public String getName() {
-    return name;
-  }
+  JType[] getParameterTypes();
 
-  public JParameter[] getParameters() {
-    // TODO(jat): where do we handle fake arg names?
-    return params.toArray(TypeOracle.NO_JPARAMS);
-  }
+  String getReadableDeclaration();
 
-  public JType[] getParameterTypes() {
-    final JType[] paramTypes = new JType[params.size()];
-    for (int i = 0; i < paramTypes.length; ++i) {
-      paramTypes[i] = params.get(i).getType();
-    }
-    return paramTypes;
-  }
+  JClassType[] getThrows();
 
-  public abstract String getReadableDeclaration();
+  JAnnotationMethod isAnnotationMethod();
 
-  public JType[] getThrows() {
-    return thrownTypes.toArray(TypeOracle.NO_JTYPES);
-  }
-  
-  public JTypeParameter[] getTypeParameters() {
-    return typeParams.toArray(new JTypeParameter[typeParams.size()]);
-  }
+  JConstructor isConstructor();
 
-  public JAnnotationMethod isAnnotationMethod() {
-    return null;
-  }
+  boolean isDefaultAccess();
 
-  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
-    return annotations.isAnnotationPresent(annotationClass);
-  }
+  JMethod isMethod();
 
-  public abstract JConstructor isConstructor();
+  boolean isPrivate();
 
-  public boolean isDefaultAccess() {
-    return 0 == (modifierBits & (TypeOracle.MOD_PUBLIC | TypeOracle.MOD_PRIVATE | TypeOracle.MOD_PROTECTED));
-  }
+  boolean isProtected();
 
-  public abstract JMethod isMethod();
+  boolean isPublic();
 
-  public boolean isPrivate() {
-    return 0 != (modifierBits & TypeOracle.MOD_PRIVATE);
-  }
+  boolean isVarArgs();
 
-  public boolean isProtected() {
-    return 0 != (modifierBits & TypeOracle.MOD_PROTECTED);
-  }
-
-  public boolean isPublic() {
-    return 0 != (modifierBits & TypeOracle.MOD_PUBLIC);
-  }
-
-  public boolean isVarArgs() {
-    return isVarArgs;
-  }
-
-  protected int getModifierBits() {
-    return modifierBits;
-  }
-
-  protected void toStringParamsAndThrows(StringBuilder sb) {
-    sb.append("(");
-    boolean needComma = false;
-    for (int i = 0, c = params.size(); i < c; ++i) {
-      JParameter param = params.get(i);
-      if (needComma) {
-        sb.append(", ");
-      } else {
-        needComma = true;
-      }
-      if (isVarArgs() && i == c - 1) {
-        JArrayType arrayType = param.getType().isArray();
-        assert (arrayType != null);
-        sb.append(arrayType.getComponentType().getParameterizedQualifiedSourceName());
-        sb.append("...");
-      } else {
-        sb.append(param.getType().getParameterizedQualifiedSourceName());
-      }
-      sb.append(" ");
-      sb.append(param.getName());
-    }
-    sb.append(")");
-
-    if (!thrownTypes.isEmpty()) {
-      sb.append(" throws ");
-      needComma = false;
-      for (JType thrownType : thrownTypes) {
-        if (needComma) {
-          sb.append(", ");
-        } else {
-          needComma = true;
-        }
-        sb.append(thrownType.getParameterizedQualifiedSourceName());
-      }
-    }
-  }
-
-  protected void toStringTypeParams(StringBuilder sb) {
-    sb.append("<");
-    boolean needComma = false;
-    for (JTypeParameter typeParam : typeParams) {
-      if (needComma) {
-        sb.append(", ");
-      } else {
-        needComma = true;
-      }
-      sb.append(typeParam.getQualifiedSourceName());
-    }
-    sb.append(">");
-  }
-
-  void addModifierBits(int bits) {
-    modifierBits |= bits;
-  }
-
-  void addParameter(JParameter param) {
-    params = Lists.add(params, param);
-  }
-
-  void addThrows(JType type) {
-    thrownTypes = Lists.add(thrownTypes, type);
-  }
-
-  /**
-   * NOTE: This method is for testing purposes only.
-   */
-  Annotation[] getAnnotations() {
-    return annotations.getAnnotations();
-  }
-
-  /**
-   * NOTE: This method is for testing purposes only.
-   */
-  Annotation[] getDeclaredAnnotations() {
-    return annotations.getDeclaredAnnotations();
-  }
-
-  // Called only by a JParameter, passing itself as a reference for lookup.
-  String getRealParameterName(JParameter parameter) {
-    if (realParameterNames == null) {
-      fetchRealParameterNames();
-    }
-    int n = params.size();
-    for (int i = 0; i < n; ++i) {
-      // Identity tests are ok since identity is durable within an oracle.
-      if (params.get(i) == parameter) {
-        String realParameterName;
-        if (realParameterNames == null) {
-          realParameterName = StringInterner.get().intern("arg" + i);
-        } else {
-          realParameterName = StringInterner.get().intern(realParameterNames[i]);
-        }
-        return realParameterName;
-      }
-    }
-    // TODO: report error if we are asked for an unknown JParameter?
-    return null;
-  }
-
-  boolean hasParamTypes(JType[] paramTypes) {
-    if (params.size() != paramTypes.length) {
-      return false;
-    }
-
-    for (int i = 0; i < paramTypes.length; i++) {
-      JParameter candidate = params.get(i);
-      // Identity tests are ok since identity is durable within an oracle.
-      //
-      if (candidate.getType() != paramTypes[i]) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  void setVarArgs() {
-    isVarArgs = true;
-  }
-
-  private void fetchRealParameterNames() {
-    realParameterNames = getEnclosingType().getOracle().getJavaSourceParser().getArguments(
-        this);
-  }
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JAnnotationMethod.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JAnnotationMethod.java
index f1af6a8..ce36696 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JAnnotationMethod.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JAnnotationMethod.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,26 +15,10 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import java.lang.annotation.Annotation;
-import java.util.Map;
-
 /**
  * Method declared on an annotation type.
  */
-public class JAnnotationMethod extends JMethod {
-  /**
-   * Default value for this annotation element. <code>null</code> is not a valid
-   * default value for an annotation element.
-   */
-  private final Object defaultValue;
-
-  JAnnotationMethod(JClassType enclosingType, String name,
-      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
-      JTypeParameter[] jtypeParameters, Object defaultValue) {
-    super(enclosingType, name, declaredAnnotations, jtypeParameters);
-    this.defaultValue = defaultValue;
-  }
-
+public interface JAnnotationMethod extends JMethod {
   /**
    * Returns the default value for this annotation method or <code>null</code>
    * if there is not one.
@@ -42,12 +26,5 @@
    * @return default value for this annotation method or <code>null</code> if
    *         there is not one
    */
-  public Object getDefaultValue() {
-    return defaultValue;
-  }
-
-  @Override
-  public JAnnotationMethod isAnnotationMethod() {
-    return this;
-  }
+  Object getDefaultValue();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JAnnotationType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JAnnotationType.java
index 12ff49f..f6827d9 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JAnnotationType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JAnnotationType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * 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
@@ -15,41 +15,10 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import java.util.Arrays;
-
 /**
  * Type representing an annotation type.
  */
-public class JAnnotationType extends JRealClassType {
-
-  JAnnotationType(TypeOracle oracle, JPackage declaringPackage,
-      String enclosingTypeName, String name) {
-    super(oracle, declaringPackage, enclosingTypeName, name, true);
-  }
-
-  @Override
-  public JAnnotationMethod getMethod(String name, JType[] paramTypes)
-      throws NotFoundException {
-    return (JAnnotationMethod) super.getMethod(name, paramTypes);
-  }
-
-  @Override
-  public JAnnotationMethod[] getMethods() {
-    JMethod[] methodArray = super.getMethods();
-    return Arrays.asList(methodArray).toArray(
-        new JAnnotationMethod[methodArray.length]);
-  }
-
-  @Override
-  public JAnnotationMethod[] getOverridableMethods() {
-    JMethod[] methodArray = super.getOverridableMethods();
-    return Arrays.asList(methodArray).toArray(
-        new JAnnotationMethod[methodArray.length]);
-  }
-
-  @Override
-  public JAnnotationType isAnnotation() {
-    return this;
-  }
-
+public interface JAnnotationType extends JRealClassType {
+  JAnnotationMethod getMethod(String name, JType[] paramTypes)
+      throws NotFoundException;
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java
index 4f109e2..0e92f19 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,440 +15,13 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.dev.util.StringInterner;
-
-import java.lang.annotation.Annotation;
-import java.util.Map;
-
 /**
  * Type representing a Java array.
  */
-public class JArrayType extends JClassType {
-  private static final JArrayType[] NO_JARRAYS = new JArrayType[0];
+public interface JArrayType extends JClassType {
+  JType getComponentType();
 
-  private JType componentType;
+  int getRank();
 
-  private String lazyQualifiedBinaryName;
-
-  private String lazyQualifiedName;
-
-  private String lazySimpleName;
-
-  private final TypeOracle oracle;
-
-  JArrayType(JType componentType, TypeOracle oracle) {
-    this.componentType = componentType;
-    this.oracle = oracle;
-  }
-
-  @Override
-  public JConstructor findConstructor(JType[] paramTypes) {
-    return null;
-  }
-
-  @Override
-  public JField findField(String name) {
-    return null;
-  }
-
-  @Override
-  public JMethod findMethod(String name, JType[] paramTypes) {
-    return getOracle().getJavaLangObject().findMethod(name, paramTypes);
-  }
-
-  @Override
-  public JClassType findNestedType(String typeName) {
-    return null;
-  }
-
-  @Override
-  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    return null;
-  }
-
-  public JType getComponentType() {
-    return componentType;
-  }
-
-  @Override
-  public JConstructor getConstructor(JType[] paramTypes)
-      throws NotFoundException {
-    throw new NotFoundException();
-  }
-
-  @Override
-  public JConstructor[] getConstructors() {
-    return TypeOracle.NO_JCTORS;
-  }
-
-  @Override
-  public JClassType getEnclosingType() {
-    return null;
-  }
-
-  @Override
-  public JClassType getErasedType() {
-    return getOracle().getArrayType(getComponentType().getErasedType());
-  }
-
-  @Override
-  public JField getField(String name) {
-    return null;
-  }
-
-  @Override
-  public JField[] getFields() {
-    return TypeOracle.NO_JFIELDS;
-  }
-
-  @Override
-  public JClassType[] getImplementedInterfaces() {
-    return TypeOracle.NO_JCLASSES;
-  }
-
-  @Override
-  public JMethod[] getInheritableMethods() {
-    return getOracle().getJavaLangObject().getInheritableMethods();
-  }
-
-  @Override
-  public String getJNISignature() {
-    return "[" + componentType.getJNISignature();
-  }
-
-  @Override
-  public JType getLeafType() {
-    return componentType.getLeafType();
-  }
-
-  @Override
-  public JMethod getMethod(String name, JType[] paramTypes)
-      throws NotFoundException {
-    return getOracle().getJavaLangObject().getMethod(name, paramTypes);
-  }
-
-  @Override
-  public JMethod[] getMethods() {
-    return getOracle().getJavaLangObject().getMethods();
-  }
-
-  @Override
-  public String getName() {
-    return getSimpleSourceName();
-  }
-
-  @Override
-  public JClassType getNestedType(String typeName) throws NotFoundException {
-    throw new NotFoundException();
-  }
-
-  @Override
-  public JClassType[] getNestedTypes() {
-    return TypeOracle.NO_JCLASSES;
-  }
-
-  @Override
-  public TypeOracle getOracle() {
-    return oracle;
-  }
-
-  @Override
-  public JMethod[] getOverloads(String name) {
-    return getOracle().getJavaLangObject().getOverloads(name);
-  }
-
-  @Override
-  public JMethod[] getOverridableMethods() {
-    return getOracle().getJavaLangObject().getOverridableMethods();
-  }
-
-  @Override
-  public JPackage getPackage() {
-    JType leafType = getLeafType();
-    if (leafType.isPrimitive() != null) {
-      // TODO: is there a default package?
-      return null;
-    }
-
-    JClassType leafClass = (JClassType) leafType;
-    return leafClass.getPackage();
-  }
-
-  @Override
-  public String getParameterizedQualifiedSourceName() {
-    return getComponentType().getParameterizedQualifiedSourceName() + "[]";
-  }
-
-  @Override
-  public String getQualifiedBinaryName() {
-    if (lazyQualifiedBinaryName == null) {
-      lazyQualifiedBinaryName = "["
-          + getComponentType().getQualifiedBinaryName();
-    }
-    return lazyQualifiedBinaryName;
-  }
-
-  @Override
-  public String getQualifiedSourceName() {
-    if (lazyQualifiedName == null) {
-      lazyQualifiedName = getComponentType().getQualifiedSourceName() + "[]";
-    }
-    return lazyQualifiedName;
-  }
-
-  public int getRank() {
-    JArrayType componentArrayType = componentType.isArray();
-    if (componentArrayType != null) {
-      return 1 + componentArrayType.getRank();
-    }
-
-    return 1;
-  }
-
-  @Override
-  public String getSimpleSourceName() {
-    if (lazySimpleName == null) {
-      lazySimpleName = StringInterner.get().intern(
-          getComponentType().getSimpleSourceName() + "[]");
-    }
-    return lazySimpleName;
-  }
-
-  @Override
-  public JArrayType[] getSubtypes() {
-    if (getComponentType().isPrimitive() != null) {
-      return NO_JARRAYS;
-    }
-
-    JClassType componentClass = (JClassType) getComponentType();
-    JClassType[] componentSubtypes = componentClass.getSubtypes();
-    JArrayType[] arraySubtypes = new JArrayType[componentSubtypes.length];
-    for (int i = 0; i < componentSubtypes.length; ++i) {
-      arraySubtypes[i] = getOracle().getArrayType(componentSubtypes[i]);
-    }
-
-    return arraySubtypes;
-  }
-
-  @Override
-  public JClassType getSuperclass() {
-    return getOracle().getJavaLangObject();
-  }
-
-  @Override
-  public boolean isAbstract() {
-    return false;
-  }
-
-  @Override
-  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
-    return false;
-  }
-
-  @Override
-  public JArrayType isArray() {
-    return this;
-  }
-
-  @Override
-  public JClassType isClass() {
-    // intentional null
-    return null;
-  }
-
-  @Override
-  public boolean isDefaultInstantiable() {
-    return true;
-  }
-
-  @Override
-  public JEnumType isEnum() {
-    return null;
-  }
-
-  // Refer the documentation for java.lang.Class::getModifiers()
-  @Override
-  public boolean isFinal() {
-    return true;
-  }
-
-  @Override
-  public JGenericType isGenericType() {
-    return null;
-  }
-
-  @Override
-  public JClassType isInterface() {
-    // intentional null
-    return null;
-  }
-
-  @Override
-  public boolean isMemberType() {
-    return false;
-  }
-
-  @Override
-  public JParameterizedType isParameterized() {
-    // intentional null
-    return null;
-  }
-
-  @Override
-  public JPrimitiveType isPrimitive() {
-    // intentional null
-    return null;
-  }
-
-  @Override
-  public boolean isPrivate() {
-    return false;
-  }
-
-  @Override
-  public boolean isProtected() {
-    return false;
-  }
-
-  @Override
-  public boolean isPublic() {
-    return true;
-  }
-
-  @Override
-  public JRawType isRawType() {
-    return null;
-  }
-
-  @Override
-  public boolean isStatic() {
-    return true;
-  }
-
-  @Override
-  public JWildcardType isWildcard() {
-    return null;
-  }
-
-  @Override
-  public String toString() {
-    return getQualifiedSourceName();
-  }
-
-  @Override
-  protected void acceptSubtype(JClassType me) {
-    throw new UnsupportedOperationException("modifying a "
-        + getClass().getSimpleName());
-  }
-
-  @Override
-  protected void getInheritableMethodsOnSuperclassesAndThisClass(
-      Map<String, JMethod> methodsBySignature) {
-    getOracle().getJavaLangObject().getInheritableMethodsOnSuperclassesAndThisClass(
-        methodsBySignature);
-  }
-
-  @Override
-  protected void getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
-      Map<String, JMethod> methodsBySignature) {
-    getOracle().getJavaLangObject().getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
-        methodsBySignature);
-  }
-
-  @Override
-  protected int getModifierBits() {
-    return 0;
-  }
-
-  @Override
-  protected void notifySuperTypesOf(JClassType me) {
-  }
-
-  @Override
-  protected void removeSubtype(JClassType me) {
-  }
-
-  @Override
-  void addConstructor(JConstructor ctor) {
-    throw new UnsupportedOperationException("modifying a "
-        + getClass().getSimpleName());
-  }
-
-  @Override
-  void addField(JField field) {
-    throw new UnsupportedOperationException("modifying a "
-        + getClass().getSimpleName());
-  }
-
-  @Override
-  void addImplementedInterface(JClassType intf) {
-    throw new UnsupportedOperationException("modifying a "
-        + getClass().getSimpleName());
-  }
-
-  @Override
-  void addMethod(JMethod method) {
-    throw new UnsupportedOperationException("modifying a "
-        + getClass().getSimpleName());
-  }
-
-  @Override
-  void addModifierBits(int bits) {
-    throw new UnsupportedOperationException("modifying a "
-        + getClass().getSimpleName());
-  }
-
-  @Override
-  void addNestedType(JClassType type) {
-    throw new UnsupportedOperationException("modifying a "
-        + getClass().getSimpleName());
-  }
-
-  @Override
-  JClassType findNestedTypeImpl(String[] typeName, int index) {
-    return null;
-  }
-
-  /**
-   * NOTE: This method is for testing purposes only.
-   */
-  @Override
-  Annotation[] getAnnotations() {
-    return TypeOracle.NO_ANNOTATIONS;
-  }
-
-  /**
-   * NOTE: This method is for testing purposes only.
-   */
-  @Override
-  Annotation[] getDeclaredAnnotations() {
-    return TypeOracle.NO_ANNOTATIONS;
-  }
-
-  @Override
-  JArrayType getSubstitutedType(JParameterizedType parameterizedType) {
-    return oracle.getArrayType(getComponentType().getSubstitutedType(
-        parameterizedType));
-  }
-
-  @Override
-  void notifySuperTypes() {
-  }
-
-  @Override
-  void removeFromSupertypes() {
-  }
-
-  void setLeafType(JType type) {
-    JArrayType componentTypeIsArray = componentType.isArray();
-    if (componentTypeIsArray != null) {
-      componentTypeIsArray.setLeafType(type);
-    } else {
-      componentType = type;
-    }
-  }
-
-  @Override
-  void setSuperclass(JClassType type) {
-  }
+  JArrayType[] getSubtypes();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
index 174be93..c5d02f3 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,353 +15,16 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.dev.util.collect.HashSet;
-
 import java.lang.annotation.Annotation;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
  * Type used to represent any non-primitive type.
  */
 @SuppressWarnings("deprecation")
-public abstract class JClassType extends JType implements HasAnnotations,
-    HasMetaData {
+public interface JClassType extends JType, HasAnnotations, HasMetaData {
 
-  /**
-   * Returns all of the superclasses and superinterfaces for a given type
-   * including the type itself. The returned set maintains an internal
-   * breadth-first ordering of the type, followed by its interfaces (and their
-   * super-interfaces), then the supertype and its interfaces, and so on.
-   */
-  protected static Set<JClassType> getFlattenedSuperTypeHierarchy(
-      JClassType type) {
-    Set<JClassType> flattened = type.flattenedSupertypes;
-    if (flattened == null) {
-      flattened = new LinkedHashSet<JClassType>();
-      getFlattenedSuperTypeHierarchyRecursive(type, flattened);
-      // flattened.size() > 1 for all types other than Object
-      type.flattenedSupertypes = Collections.unmodifiableSet(flattened);
-    }
-    return flattened;
-  }
-
-  /**
-   * Returns <code>true</code> if the rhs array type can be assigned to the lhs
-   * array type.
-   */
-  private static boolean areArraysAssignable(JArrayType lhsType,
-      JArrayType rhsType) {
-    // areClassTypesAssignable should prevent us from getting here if the types
-    // are referentially equal.
-    assert (lhsType != rhsType);
-
-    JType lhsComponentType = lhsType.getComponentType();
-    JType rhsComponentType = rhsType.getComponentType();
-
-    if (lhsComponentType.isPrimitive() != null
-        || rhsComponentType.isPrimitive() != null) {
-      /*
-       * Arrays are referentially stable so there will only be one int[] no
-       * matter how many times it is referenced in the code. So, if either
-       * component type is a primitive then we know that we are not assignable.
-       */
-      return false;
-    }
-
-    assert (lhsComponentType instanceof JClassType);
-    assert (rhsComponentType instanceof JClassType);
-
-    JClassType thisComponentClass = (JClassType) lhsComponentType;
-    JClassType subtypeComponentClass = (JClassType) rhsComponentType;
-
-    return areClassTypesAssignable(thisComponentClass, subtypeComponentClass);
-  }
-
-  /**
-   * Returns <code>true</code> if the rhsType can be assigned to the lhsType.
-   */
-  private static boolean areClassTypesAssignable(JClassType lhsType,
-      JClassType rhsType) {
-    // The supertypes of rhs will include rhs.
-    Set<JClassType> rhsSupertypes = getFlattenedSuperTypeHierarchy(rhsType);
-    for (JClassType rhsSupertype : rhsSupertypes) {
-      if (areClassTypesAssignableNoSupers(lhsType, rhsSupertype)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  /**
-   * Returns <code>true</code> if the lhs and rhs are assignable without
-   * consideration of the supertypes of the rhs.
-   * 
-   * @param lhsType
-   * @param rhsType
-   * @return true if rhsType can be assigned to lhsType
-   */
-  private static boolean areClassTypesAssignableNoSupers(JClassType lhsType,
-      JClassType rhsType) {
-    if (lhsType == rhsType) {
-      // Done, these are the same types.
-      return true;
-    }
-
-    if (lhsType == lhsType.getOracle().getJavaLangObject()) {
-      // Done, any type can be assigned to object.
-      return true;
-    }
-
-    /*
-     * Get the generic base type, if there is one, for the lhs type and convert
-     * it to a raw type if it is generic.
-     */
-    if (lhsType.isGenericType() != null) {
-      lhsType = lhsType.isGenericType().getRawType();
-    }
-
-    if (rhsType.isGenericType() != null) {
-      // Treat the generic rhs type as a raw type.
-      rhsType = rhsType.isGenericType().getRawType();
-    }
-
-    // Check for JTypeParameters.
-    JTypeParameter lhsTypeParam = lhsType.isTypeParameter();
-    JTypeParameter rhsTypeParam = rhsType.isTypeParameter();
-    if (lhsTypeParam != null) {
-      JClassType[] lhsTypeBounds = lhsTypeParam.getBounds();
-      for (JClassType lhsTypeBound : lhsTypeBounds) {
-        if (!areClassTypesAssignable(lhsTypeBound, rhsType)) {
-          // Done, the rhsType was not assignable to one of the bounds.
-          return false;
-        }
-      }
-
-      // Done, the rhsType was assignable to all of the bounds.
-      return true;
-    } else if (rhsTypeParam != null) {
-      JClassType[] possibleSubtypeBounds = rhsTypeParam.getBounds();
-      for (JClassType possibleSubtypeBound : possibleSubtypeBounds) {
-        if (areClassTypesAssignable(lhsType, possibleSubtypeBound)) {
-          // Done, at least one bound is assignable to this type.
-          return true;
-        }
-      }
-
-      return false;
-    }
-
-    /*
-     * Check for JWildcards. We have not examined this part in great detail
-     * since there should not be top level wildcard types.
-     */
-    JWildcardType lhsWildcard = lhsType.isWildcard();
-    JWildcardType rhsWildcard = rhsType.isWildcard();
-    if (lhsWildcard != null && rhsWildcard != null) {
-      // Both types are wildcards.
-      return areWildcardsAssignable(lhsWildcard, rhsWildcard);
-    } else if (lhsWildcard != null) {
-      // The lhs type is a wildcard but the rhs is not.
-      // ? extends T, U OR ? super T, U
-      JClassType[] lowerBounds = lhsWildcard.getLowerBounds();
-      if (lowerBounds.length > 0) {
-        // ? super T will reach object no matter what the rhs type is
-        return true;
-      } else {
-        return areClassTypesAssignable(lhsWildcard.getFirstBound(), rhsType);
-      }
-    }
-
-    // Check for JArrayTypes.
-    JArrayType lhsArray = lhsType.isArray();
-    JArrayType rhsArray = rhsType.isArray();
-    if (lhsArray != null) {
-      if (rhsArray == null) {
-        return false;
-      } else {
-        return areArraysAssignable(lhsArray, rhsArray);
-      }
-    } else if (rhsArray != null) {
-      // Safe although perhaps not necessary
-      return false;
-    }
-
-    // Check for JParameterizedTypes and JRawTypes.
-    JMaybeParameterizedType lhsMaybeParameterized = lhsType.isMaybeParameterizedType();
-    JMaybeParameterizedType rhsMaybeParameterized = rhsType.isMaybeParameterizedType();
-    if (lhsMaybeParameterized != null && rhsMaybeParameterized != null) {
-      if (lhsMaybeParameterized.getBaseType() == rhsMaybeParameterized.getBaseType()) {
-        if (lhsMaybeParameterized.isRawType() != null
-            || rhsMaybeParameterized.isRawType() != null) {
-          /*
-           * Any raw type can be assigned to or from any parameterization of its
-           * generic type.
-           */
-          return true;
-        }
-
-        assert (lhsMaybeParameterized.isRawType() == null && rhsMaybeParameterized.isRawType() == null);
-        JParameterizedType lhsParameterized = lhsMaybeParameterized.isParameterized();
-        JParameterizedType rhsParameterized = rhsMaybeParameterized.isParameterized();
-        assert (lhsParameterized != null && rhsParameterized != null);
-
-        return areTypeArgumentsAssignable(lhsParameterized, rhsParameterized);
-      }
-    }
-
-    // Default to not being assignable.
-    return false;
-  }
-
-  /**
-   * Returns <code>true</code> if the type arguments of the rhs parameterized
-   * type are assignable to the type arguments of the lhs parameterized type.
-   */
-  private static boolean areTypeArgumentsAssignable(JParameterizedType lhsType,
-      JParameterizedType rhsType) {
-    // areClassTypesAssignable should prevent us from getting here if the types
-    // are referentially equal.
-    assert (lhsType != rhsType);
-    assert (lhsType.getBaseType() == rhsType.getBaseType());
-
-    JClassType[] lhsTypeArgs = lhsType.getTypeArgs();
-    JClassType[] rhsTypeArgs = rhsType.getTypeArgs();
-    JGenericType lhsBaseType = lhsType.getBaseType();
-
-    // Compare at least as many formal type parameters as are declared on the
-    // generic base type. gwt.typeArgs could cause more types to be included.
-
-    JTypeParameter[] lhsTypeParams = lhsBaseType.getTypeParameters();
-    for (int i = 0; i < lhsTypeParams.length; ++i) {
-      if (!doesTypeArgumentContain(lhsTypeArgs[i], rhsTypeArgs[i])) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  /**
-   * Returns <code>true</code> if the rhsWildcard can be assigned to the
-   * lhsWildcard. This method does not consider supertypes of either lhs or rhs.
-   */
-  private static boolean areWildcardsAssignable(JWildcardType lhsWildcard,
-      JWildcardType rhsWildcard) {
-    // areClassTypesAssignable should prevent us from getting here if the types
-    // are referentially equal.
-    assert (lhsWildcard != rhsWildcard);
-    assert (lhsWildcard != null && rhsWildcard != null);
-
-    if (lhsWildcard.getLowerBounds().length > 0
-        && rhsWildcard.getLowerBounds().length > 0) {
-      // lhsType: ? super T, rhsType ? super U
-      return areClassTypesAssignable(rhsWildcard.getFirstBound(),
-          lhsWildcard.getFirstBound());
-    } else if (lhsWildcard.getUpperBounds().length > 0
-        && lhsWildcard.getLowerBounds().length == 0
-        && rhsWildcard.getUpperBounds().length > 0
-        && rhsWildcard.getLowerBounds().length == 0) {
-      // lhsType: ? extends T, rhsType: ? extends U
-      return areClassTypesAssignable(lhsWildcard.getFirstBound(),
-          rhsWildcard.getFirstBound());
-    }
-
-    return false;
-  }
-
-  /**
-   * A restricted version of areClassTypesAssignable that is used for comparing
-   * the type arguments of parameterized types, where the lhsTypeArg is the
-   * container.
-   */
-  private static boolean doesTypeArgumentContain(JClassType lhsTypeArg,
-      JClassType rhsTypeArg) {
-    if (lhsTypeArg == rhsTypeArg) {
-      return true;
-    }
-
-    // Check for wildcard types
-    JWildcardType lhsWildcard = lhsTypeArg.isWildcard();
-    JWildcardType rhsWildcard = rhsTypeArg.isWildcard();
-
-    if (lhsWildcard != null) {
-      if (rhsWildcard != null) {
-        return areWildcardsAssignable(lhsWildcard, rhsWildcard);
-      } else {
-        // LHS is a wildcard but the RHS is not.
-        if (lhsWildcard.getLowerBounds().length > 0) {
-          return areClassTypesAssignable(rhsTypeArg,
-              lhsWildcard.getFirstBound());
-        } else {
-          return areClassTypesAssignable(lhsWildcard.getFirstBound(),
-              rhsTypeArg);
-        }
-      }
-    }
-
-    /*
-     * At this point the arguments are not the same and they are not wildcards
-     * so, they cannot be assignable, Eh.
-     */
-    return false;
-  }
-
-  private static void getFlattenedSuperTypeHierarchyRecursive(JClassType type,
-      Set<JClassType> typesSeen) {
-    if (typesSeen.contains(type)) {
-      return;
-    }
-    typesSeen.add(type);
-
-    // Check the interfaces
-    JClassType[] intfs = type.getImplementedInterfaces();
-    for (JClassType intf : intfs) {
-      typesSeen.addAll(getFlattenedSuperTypeHierarchy(intf));
-    }
-
-    // Superclass
-    JClassType superclass = type.getSuperclass();
-    if (superclass != null) {
-      typesSeen.addAll(getFlattenedSuperTypeHierarchy(superclass));
-    }
-  }
-
-  /**
-   * Cached set of supertypes for this type (including itself). If null, the set
-   * has not been calculated yet.
-   */
-  private Set<JClassType> flattenedSupertypes;
-
-  /**
-   * True if this type may be enhanced with server-only fields. This property is
-   * 'sticky' and may be set but not unset, since we need to generate the
-   * relevant RPC code for handling the server fields if there is any chance the
-   * class will be enhanced.
-   */
-  private boolean isEnhanced = false;
-
-  public JParameterizedType asParameterizationOf(JGenericType type) {
-    Set<JClassType> supertypes = getFlattenedSuperTypeHierarchy(this);
-    for (JClassType supertype : supertypes) {
-      JParameterizedType isParameterized = supertype.isParameterized();
-      if (isParameterized != null && isParameterized.getBaseType() == type) {
-        return isParameterized;
-      }
-
-      JRawType isRaw = supertype.isRawType();
-      if (isRaw != null && isRaw.getBaseType() == type) {
-        return isRaw.asParameterizedByWildcards();
-      }
-    }
-
-    return null;
-  }
+  JParameterizedType asParameterizationOf(JGenericType type);
 
   /**
    * Find an annotation on a type or on one of its superclasses or
@@ -381,71 +44,27 @@
    * @return the desired annotation or <code>null</code> if the annotation is
    *         not present in the type's type hierarchy
    */
-  public <T extends Annotation> T findAnnotationInTypeHierarchy(
-      Class<T> annotationType) {
+  <T extends Annotation> T findAnnotationInTypeHierarchy(Class<T> annotationType);
 
-    // Remember what we've seen to avoid loops
-    Set<JClassType> seen = new HashSet<JClassType>();
+  JConstructor findConstructor(JType[] paramTypes);
 
-    // Work queue
-    List<JClassType> searchTypes = new LinkedList<JClassType>();
-    searchTypes.add(this);
+  JField findField(String name);
 
-    T toReturn = null;
+  JMethod findMethod(String name, JType[] paramTypes);
 
-    while (!searchTypes.isEmpty()) {
-      JClassType current = searchTypes.remove(0);
+  JClassType findNestedType(String typeName);
 
-      if (!seen.add(current)) {
-        continue;
-      }
+  JConstructor getConstructor(JType[] paramTypes) throws NotFoundException;
 
-      toReturn = current.getAnnotation(annotationType);
-      if (toReturn != null) {
-        /*
-         * First one wins. It might be desirable at some point to have a
-         * variation that can return more than one instance of the annotation if
-         * it is present on multiple supertypes.
-         */
-        break;
-      }
+  JConstructor[] getConstructors();
 
-      if (current.getSuperclass() != null) {
-        // Add the superclass at the front of the list
-        searchTypes.add(0, current.getSuperclass());
-      }
+  JClassType getEnclosingType();
 
-      // Superinterfaces
-      Collections.addAll(searchTypes, current.getImplementedInterfaces());
-    }
+  JClassType getErasedType();
 
-    return toReturn;
-  }
+  JField getField(String name);
 
-  public abstract JConstructor findConstructor(JType[] paramTypes);
-
-  public abstract JField findField(String name);
-
-  public abstract JMethod findMethod(String name, JType[] paramTypes);
-
-  public abstract JClassType findNestedType(String typeName);
-
-  public abstract <T extends Annotation> T getAnnotation(
-      Class<T> annotationClass);
-
-  public abstract JConstructor getConstructor(JType[] paramTypes)
-      throws NotFoundException;
-
-  public abstract JConstructor[] getConstructors();
-
-  public abstract JClassType getEnclosingType();
-
-  @Override
-  public abstract JClassType getErasedType();
-
-  public abstract JField getField(String name);
-
-  public abstract JField[] getFields();
+  JField[] getFields();
 
   /**
    * Returns all of the superclasses and superinterfaces for a given type
@@ -453,12 +72,9 @@
    * breadth-first ordering of the type, followed by its interfaces (and their
    * super-interfaces), then the supertype and its interfaces, and so on.
    */
-  public Set<JClassType> getFlattenedSupertypeHierarchy() {
-    // Retuns an immutable set
-    return getFlattenedSuperTypeHierarchy(this);
-  }
+  Set<? extends JClassType> getFlattenedSupertypeHierarchy();
 
-  public abstract JClassType[] getImplementedInterfaces();
+  JClassType[] getImplementedInterfaces();
 
   /**
    * Iterates over the most-derived declaration of each unique inheritable
@@ -473,37 +89,25 @@
    * @return an array of {@link JMethod} objects representing inheritable
    *         methods
    */
-  public abstract JMethod[] getInheritableMethods();
+  JMethod[] getInheritableMethods();
 
-  @Deprecated
-  public final String[][] getMetaData(String tagName) {
-    return TypeOracle.NO_STRING_ARR_ARR;
-  }
-
-  @Deprecated
-  public final String[] getMetaDataTags() {
-    return TypeOracle.NO_STRINGS;
-  }
-
-  public abstract JMethod getMethod(String name, JType[] paramTypes)
-      throws NotFoundException;
+  JMethod getMethod(String name, JType[] paramTypes) throws NotFoundException;
 
   /*
    * Returns the declared methods of this class (not any superclasses or
    * superinterfaces).
    */
-  public abstract JMethod[] getMethods();
+  JMethod[] getMethods();
 
-  public abstract String getName();
+  String getName();
 
-  public abstract JClassType getNestedType(String typeName)
-      throws NotFoundException;
+  JClassType getNestedType(String typeName) throws NotFoundException;
 
-  public abstract JClassType[] getNestedTypes();
+  JClassType[] getNestedTypes();
 
-  public abstract TypeOracle getOracle();
+  TypeOracle getOracle();
 
-  public abstract JMethod[] getOverloads(String name);
+  JMethod[] getOverloads(String name);
 
   /**
    * Iterates over the most-derived declaration of each unique overridable
@@ -522,18 +126,15 @@
    * @return an array of {@link JMethod} objects representing overridable
    *         methods
    */
-  public abstract JMethod[] getOverridableMethods();
+  JMethod[] getOverridableMethods();
 
-  public abstract JPackage getPackage();
+  JPackage getPackage();
 
-  public abstract JClassType[] getSubtypes();
+  JClassType[] getSubtypes();
 
-  public abstract JClassType getSuperclass();
+  JClassType getSuperclass();
 
-  public abstract boolean isAbstract();
-
-  public abstract boolean isAnnotationPresent(
-      Class<? extends Annotation> annotationClass);
+  boolean isAbstract();
 
   /**
    * Returns <code>true</code> if this {@link JClassType} is assignable from the
@@ -546,13 +147,7 @@
    * @throws NullPointerException if <code>possibleSubtype</code> is
    *           <code>null</code>
    */
-  public boolean isAssignableFrom(JClassType possibleSubtype) {
-    if (possibleSubtype == null) {
-      throw new NullPointerException("possibleSubtype");
-    }
-
-    return areClassTypesAssignable(this, possibleSubtype);
-  }
+  boolean isAssignableFrom(JClassType possibleSubtype);
 
   /**
    * Returns <code>true</code> if this {@link JClassType} is assignable to the
@@ -565,13 +160,7 @@
    * @throws NullPointerException if <code>possibleSupertype</code> is
    *           <code>null</code>
    */
-  public boolean isAssignableTo(JClassType possibleSupertype) {
-    if (possibleSupertype == null) {
-      throw new NullPointerException("possibleSupertype");
-    }
-
-    return areClassTypesAssignable(possibleSupertype, this);
-  }
+  boolean isAssignableTo(JClassType possibleSupertype);
 
   /**
    * Determines if the class can be constructed using a simple <code>new</code>
@@ -585,7 +174,7 @@
    * @return <code>true</code> if the type is default instantiable, or
    *         <code>false</code> otherwise
    */
-  public abstract boolean isDefaultInstantiable();
+  boolean isDefaultInstantiable();
 
   /**
    * Returns true if the type may be enhanced on the server to contain extra
@@ -593,25 +182,15 @@
    * 
    * @return <code>true</code> if the type might be enhanced on the server
    */
-  public final boolean isEnhanced() {
-    return isEnhanced;
-  }
+  boolean isEnhanced();
 
-  public abstract boolean isFinal();
-
-  @Override
-  public abstract JGenericType isGenericType();
-
-  @Override
-  public abstract JClassType isInterface();
+  boolean isFinal();
 
   /**
    * @deprecated local types are not modeled
    */
   @Deprecated
-  public final boolean isLocalType() {
-    return false;
-  }
+  boolean isLocalType();
 
   /**
    * Tests if this type is contained within another type.
@@ -619,15 +198,15 @@
    * @return true if this type has an enclosing type, false if this type is a
    *         top-level type
    */
-  public abstract boolean isMemberType();
+  boolean isMemberType();
 
-  public abstract boolean isPrivate();
+  boolean isPrivate();
 
-  public abstract boolean isProtected();
+  boolean isProtected();
 
-  public abstract boolean isPublic();
+  boolean isPublic();
 
-  public abstract boolean isStatic();
+  boolean isStatic();
 
   /**
    * Indicates that the type may be enhanced on the server to contain extra
@@ -635,81 +214,5 @@
    * 
    * TODO(rice): find a better way to do this.
    */
-  public void setEnhanced() {
-    this.isEnhanced = true;
-  }
-
-  @Override
-  public String toString() {
-    return this.getQualifiedSourceName();
-  }
-
-  protected abstract void acceptSubtype(JClassType me);
-
-  protected abstract void getInheritableMethodsOnSuperclassesAndThisClass(
-      Map<String, JMethod> methodsBySignature);
-
-  /**
-   * Gets the methods declared in interfaces that this type extends. If this
-   * type is a class, its own methods are not added. If this type is an
-   * interface, its own methods are added. Used internally by
-   * {@link #getOverridableMethods()}.
-   * 
-   * @param methodsBySignature
-   */
-  protected abstract void getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
-      Map<String, JMethod> methodsBySignature);
-
-  protected abstract int getModifierBits();
-
-  protected JMaybeParameterizedType isMaybeParameterizedType() {
-    return null;
-  }
-
-  /**
-   * Tells this type's superclasses and superinterfaces about it.
-   */
-  protected abstract void notifySuperTypesOf(JClassType me);
-
-  protected abstract void removeSubtype(JClassType me);
-
-  abstract void addConstructor(JConstructor ctor);
-
-  abstract void addField(JField field);
-
-  abstract void addImplementedInterface(JClassType intf);
-
-  abstract void addMethod(JMethod method);
-
-  abstract void addModifierBits(int bits);
-
-  abstract void addNestedType(JClassType type);
-
-  abstract JClassType findNestedTypeImpl(String[] typeName, int index);
-
-  /**
-   * Returns all of the annotations declared or inherited by this instance.
-   * 
-   * NOTE: This method is for testing purposes only.
-   */
-  abstract Annotation[] getAnnotations();
-
-  /**
-   * Returns all of the annotations declared on this instance.
-   * 
-   * NOTE: This method is for testing purposes only.
-   */
-  abstract Annotation[] getDeclaredAnnotations();
-
-  @Override
-  abstract JClassType getSubstitutedType(JParameterizedType parameterizedType);
-
-  abstract void notifySuperTypes();
-
-  /**
-   * Removes references to this instance from all of its super types.
-   */
-  abstract void removeFromSupertypes();
-
-  abstract void setSuperclass(JClassType type);
+  void setEnhanced();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JConstructor.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JConstructor.java
index 08b7274..45cfa37 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JConstructor.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JConstructor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Google Inc.
+ * 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
@@ -15,79 +15,8 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import java.lang.annotation.Annotation;
-import java.util.Map;
-
 /**
  * Represents a constructor declaration.
  */
-public class JConstructor extends JAbstractMethod {
-  private final JClassType enclosingType;
-
-  JConstructor(JClassType enclosingType, JConstructor ctor) {
-    super(ctor);
-    this.enclosingType = enclosingType;
-  }
-
-  JConstructor(JClassType enclosingType, String name) {
-    this(enclosingType, name, null, null);
-  }
-
-  JConstructor(JClassType enclosingType, String name,
-      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
-      JTypeParameter[] jtypeParameters) {
-    super(name, declaredAnnotations, jtypeParameters);
-
-    this.enclosingType = enclosingType;
-    enclosingType.addConstructor(this);
-  }
-
-  @Override
-  public JClassType getEnclosingType() {
-    return enclosingType;
-  }
-
-  @Override
-  public String getJsniSignature() {
-    StringBuilder sb = new StringBuilder("@");
-    sb.append(getEnclosingType().getQualifiedSourceName());
-    sb.append("::new(");
-    for (JParameter param : getParameters()) {
-      sb.append(param.getType().getJNISignature());
-    }
-    sb.append(")");
-    return sb.toString();
-  }
-
-  @Override
-  public String getReadableDeclaration() {
-    String[] names = TypeOracle.modifierBitsToNames(getModifierBits());
-    StringBuilder sb = new StringBuilder();
-    for (String name2 : names) {
-      sb.append(name2);
-      sb.append(" ");
-    }
-    if (getTypeParameters().length > 0) {
-      toStringTypeParams(sb);
-      sb.append(" ");
-    }
-    sb.append(getName());
-    toStringParamsAndThrows(sb);
-    return sb.toString();
-  }
-
-  @Override
-  public JConstructor isConstructor() {
-    return this;
-  }
-
-  @Override
-  public JMethod isMethod() {
-    return null;
-  }
-
-  @Override
-  public String toString() {
-    return getReadableDeclaration();
-  }
+public interface JConstructor extends JAbstractMethod {
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumConstant.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumConstant.java
index 2032ef5..06c6a7d 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumConstant.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumConstant.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * 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
@@ -15,33 +15,15 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import java.lang.annotation.Annotation;
-import java.util.Map;
-
 /**
  * An enumeration constant declared in an enumerated type.
  */
-public class JEnumConstant extends JField {
-  private final int ordinal;
-
-  JEnumConstant(JClassType enclosingType, String name,
-      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
-      int ordinal) {
-    super(enclosingType, name, declaredAnnotations);
-    this.ordinal = ordinal;
-  }
+public interface JEnumConstant extends JField {
 
   /**
    * Returns the ordinal value for this enumeration constant.
    * 
    * @return ordinal value for this enumeration constant
    */
-  public int getOrdinal() {
-    return ordinal;
-  }
-
-  @Override
-  public JEnumConstant isEnumConstant() {
-    return this;
-  }
+  int getOrdinal();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumType.java
index 480165e..8dbeacd 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * 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
@@ -15,42 +15,15 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Type representing a Java enumerated type.
  */
-public class JEnumType extends JRealClassType {
-  private JEnumConstant[] lazyEnumConstants;
-
-  JEnumType(TypeOracle oracle, JPackage declaringPackage,
-      String enclosingTypeName, String name) {
-    super(oracle, declaringPackage, enclosingTypeName, name, false);
-  }
-
+public interface JEnumType extends JRealClassType {
   /**
    * Returns the enumeration constants declared by this enumeration.
    * 
    * @return enumeration constants declared by this enumeration
    */
-  public JEnumConstant[] getEnumConstants() {
-    if (lazyEnumConstants == null) {
-      List<JEnumConstant> enumConstants = new ArrayList<JEnumConstant>();
-      for (JField field : getFields()) {
-        if (field.isEnumConstant() != null) {
-          enumConstants.add(field.isEnumConstant());
-        }
-      }
 
-      lazyEnumConstants = enumConstants.toArray(new JEnumConstant[enumConstants.size()]);
-    }
-
-    return lazyEnumConstants;
-  }
-
-  @Override
-  public JEnumType isEnum() {
-    return this;
-  }
+  JEnumConstant[] getEnumConstants();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JField.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JField.java
index 8a3f3d6..59feefd 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JField.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JField.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,154 +15,33 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.dev.util.StringInterner;
-
-import java.lang.annotation.Annotation;
-import java.util.Map;
-
 /**
  * Represents a field declaration.
  */
 @SuppressWarnings("deprecation")
-public class JField implements HasAnnotations, HasMetaData {
+public interface JField extends HasAnnotations, HasMetaData {
 
-  private final Annotations annotations;
+  JClassType getEnclosingType();
 
-  private final JClassType enclosingType;
+  String getName();
 
-  private int modifierBits;
+  JType getType();
 
-  private final String name;
+  boolean isDefaultAccess();
 
-  private JType type;
+  JEnumConstant isEnumConstant();
 
-  JField(JClassType enclosingType, JField srcField) {
-    this.annotations = new Annotations(srcField.annotations);
-    this.enclosingType = enclosingType;
-    this.modifierBits = srcField.modifierBits;
-    this.name = srcField.name;
-    this.type = srcField.type;
-  }
+  boolean isFinal();
 
-  JField(JClassType enclosingType, String name) {
-    this(enclosingType, name, null);
-  }
+  boolean isPrivate();
 
-  JField(JClassType enclosingType, String name,
-      Map<Class<? extends Annotation>, Annotation> declaredAnnotations) {
-    assert (enclosingType != null);
-    this.enclosingType = enclosingType;
-    this.name = StringInterner.get().intern(name);
-    this.enclosingType.addField(this);
-    annotations = new Annotations(declaredAnnotations);
-  }
+  boolean isProtected();
 
-  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    return annotations.getAnnotation(annotationClass);
-  }
+  boolean isPublic();
 
-  public JClassType getEnclosingType() {
-    return enclosingType;
-  }
+  boolean isStatic();
 
-  @Deprecated
-  public final String[][] getMetaData(String tagName) {
-    return TypeOracle.NO_STRING_ARR_ARR;
-  }
+  boolean isTransient();
 
-  @Deprecated
-  public final String[] getMetaDataTags() {
-    return TypeOracle.NO_STRINGS;
-  }
-
-  public String getName() {
-    assert (name != null);
-    return name;
-  }
-
-  public JType getType() {
-    assert (type != null);
-    return type;
-  }
-
-  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
-    return annotations.isAnnotationPresent(annotationClass);
-  }
-
-  public boolean isDefaultAccess() {
-    return 0 == (modifierBits & (TypeOracle.MOD_PUBLIC | TypeOracle.MOD_PRIVATE | TypeOracle.MOD_PROTECTED));
-  }
-
-  public JEnumConstant isEnumConstant() {
-    return null;
-  }
-
-  public boolean isFinal() {
-    return 0 != (modifierBits & TypeOracle.MOD_FINAL);
-  }
-
-  public boolean isPrivate() {
-    return 0 != (modifierBits & TypeOracle.MOD_PRIVATE);
-  }
-
-  public boolean isProtected() {
-    return 0 != (modifierBits & TypeOracle.MOD_PROTECTED);
-  }
-
-  public boolean isPublic() {
-    return 0 != (modifierBits & TypeOracle.MOD_PUBLIC);
-  }
-
-  public boolean isStatic() {
-    return 0 != (modifierBits & TypeOracle.MOD_STATIC);
-  }
-
-  public boolean isTransient() {
-    return 0 != (modifierBits & TypeOracle.MOD_TRANSIENT);
-  }
-
-  public boolean isVolatile() {
-    return 0 != (modifierBits & TypeOracle.MOD_VOLATILE);
-  }
-
-  @Override
-  public String toString() {
-    String[] names = TypeOracle.modifierBitsToNames(modifierBits);
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < names.length; i++) {
-      if (i > 0) {
-        sb.append(" ");
-      }
-      sb.append(names[i]);
-    }
-    if (names.length > 0) {
-      sb.append(" ");
-    }
-    sb.append(type.getParameterizedQualifiedSourceName());
-    sb.append(" ");
-    sb.append(getName());
-    return sb.toString();
-  }
-
-  void addModifierBits(int modifierBits) {
-    this.modifierBits |= modifierBits;
-  }
-
-  /**
-   * NOTE: This method is for testing purposes only.
-   */
-  Annotation[] getAnnotations() {
-    return annotations.getAnnotations();
-  }
-
-  /**
-   * NOTE: This method is for testing purposes only.
-   */
-  Annotation[] getDeclaredAnnotations() {
-    return annotations.getDeclaredAnnotations();
-  }
-
-  void setType(JType type) {
-    this.type = type;
-  }
+  boolean isVolatile();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java
index 712ac94..83700ef 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,100 +15,12 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
-import com.google.gwt.dev.util.collect.Lists;
-
-import java.util.List;
-
 /**
  * Type declaration that has type parameters.
  */
-public class JGenericType extends JRealClassType implements HasTypeParameters {
+public interface JGenericType extends JRealClassType, HasTypeParameters {
 
-  private JRawType lazyRawType = null;
+  JParameterizedType asParameterizedByWildcards();
 
-  private List<JTypeParameter> typeParams = Lists.create();
-
-  public JGenericType(TypeOracle oracle, JPackage declaringPackage,
-      String enclosingTypeName, String name, boolean isInterface,
-      JTypeParameter[] jtypeParameters) {
-    super(oracle, declaringPackage, enclosingTypeName, name, isInterface);
-
-    if (jtypeParameters != null) {
-      for (JTypeParameter jtypeParameter : jtypeParameters) {
-        addTypeParameter(jtypeParameter);
-      }
-    }
-  }
-
-  public JParameterizedType asParameterizedByWildcards() {
-    JClassType[] typeArgs = new JClassType[typeParams.size()];
-    for (int i = 0; i < typeArgs.length; ++i) {
-      typeArgs[i] = getOracle().getWildcardType(BoundType.EXTENDS,
-          typeParams.get(i).getFirstBound());
-    }
-    return getOracle().getParameterizedType(this, typeArgs);
-  }
-
-  @Override
-  public JClassType getErasedType() {
-    return getRawType();
-  }
-
-  @Override
-  public String getParameterizedQualifiedSourceName() {
-    StringBuffer sb = new StringBuffer();
-
-    if (getEnclosingType() != null) {
-      sb.append(getEnclosingType().getParameterizedQualifiedSourceName());
-      sb.append(".");
-      sb.append(getSimpleSourceName());
-    } else {
-      sb.append(getQualifiedSourceName());
-    }
-
-    sb.append('<');
-    boolean needComma = false;
-    for (JClassType typeParam : typeParams) {
-      if (needComma) {
-        sb.append(", ");
-      } else {
-        needComma = true;
-      }
-      sb.append(typeParam.getParameterizedQualifiedSourceName());
-    }
-    sb.append('>');
-    return sb.toString();
-  }
-
-  public JRawType getRawType() {
-    if (lazyRawType == null) {
-      lazyRawType = new JRawType(this);
-    }
-
-    return lazyRawType;
-  }
-
-  public JTypeParameter[] getTypeParameters() {
-    return typeParams.toArray(new JTypeParameter[typeParams.size()]);
-  }
-
-  @Override
-  public JGenericType isGenericType() {
-    return this;
-  }
-
-  @Override
-  public String toString() {
-    if (isInterface() != null) {
-      return "interface " + getParameterizedQualifiedSourceName();
-    }
-
-    return "class " + getParameterizedQualifiedSourceName();
-  }
-
-  private void addTypeParameter(JTypeParameter typeParameter) {
-    typeParams = Lists.add(typeParams, typeParameter);
-    typeParameter.setDeclaringClass(this);
-  }
+  JRawType getRawType();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JMethod.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JMethod.java
index cffed32..de5a9df 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JMethod.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JMethod.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * 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
@@ -15,137 +15,21 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import java.lang.annotation.Annotation;
-import java.util.Map;
-
 /**
  * Represents a method declaration.
  */
-public class JMethod extends JAbstractMethod {
+public interface JMethod extends JAbstractMethod {
 
-  private final JClassType enclosingType;
+  String getReadableDeclaration(boolean noAccess, boolean noNative,
+      boolean noStatic, boolean noFinal, boolean noAbstract);
 
-  private JType returnType;
+  JType getReturnType();
 
-  JMethod(JClassType enclosingType, JMethod srcMethod) {
-    super(srcMethod);
-    this.enclosingType = enclosingType;
-    this.returnType = srcMethod.returnType;
-  }
+  boolean isAbstract();
 
-  JMethod(JClassType enclosingType, String name) {
-    this(enclosingType, name, null, null);
-  }
+  boolean isFinal();
 
-  JMethod(JClassType enclosingType, String name,
-      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
-      JTypeParameter[] jtypeParameters) {
-    super(name, declaredAnnotations, jtypeParameters);
-    this.enclosingType = enclosingType;
-    enclosingType.addMethod(this);
-  }
+  boolean isNative();
 
-  @Override
-  public JClassType getEnclosingType() {
-    return enclosingType;
-  }
-
-  @Override
-  public String getJsniSignature() {
-    StringBuilder sb = new StringBuilder("@");
-    sb.append(getEnclosingType().getQualifiedSourceName());
-    sb.append("::");
-    sb.append(getName());
-    sb.append("(");
-    for (JParameter param : getParameters()) {
-      sb.append(param.getType().getJNISignature());
-    }
-    sb.append(")");
-    return sb.toString();
-  }
-
-  @Override
-  public String getReadableDeclaration() {
-    return getReadableDeclaration(getModifierBits());
-  }
-
-  public String getReadableDeclaration(boolean noAccess, boolean noNative,
-      boolean noStatic, boolean noFinal, boolean noAbstract) {
-    int bits = getModifierBits();
-    if (noAccess) {
-      bits &= ~(TypeOracle.MOD_PUBLIC | TypeOracle.MOD_PRIVATE | TypeOracle.MOD_PROTECTED);
-    }
-    if (noNative) {
-      bits &= ~TypeOracle.MOD_NATIVE;
-    }
-    if (noStatic) {
-      bits &= ~TypeOracle.MOD_STATIC;
-    }
-    if (noFinal) {
-      bits &= ~TypeOracle.MOD_FINAL;
-    }
-    if (noAbstract) {
-      bits &= ~TypeOracle.MOD_ABSTRACT;
-    }
-    return getReadableDeclaration(bits);
-  }
-
-  public JType getReturnType() {
-    return returnType;
-  }
-
-  public boolean isAbstract() {
-    return 0 != (getModifierBits() & TypeOracle.MOD_ABSTRACT);
-  }
-
-  @Override
-  public JConstructor isConstructor() {
-    return null;
-  }
-
-  public boolean isFinal() {
-    return 0 != (getModifierBits() & TypeOracle.MOD_FINAL);
-  }
-
-  @Override
-  public JMethod isMethod() {
-    return this;
-  }
-
-  public boolean isNative() {
-    return 0 != (getModifierBits() & TypeOracle.MOD_NATIVE);
-  }
-
-  public boolean isStatic() {
-    return 0 != (getModifierBits() & TypeOracle.MOD_STATIC);
-  }
-
-  @Override
-  public String toString() {
-    return getReadableDeclaration();
-  }
-
-  String getReadableDeclaration(int modifierBits) {
-    String[] names = TypeOracle.modifierBitsToNames(modifierBits);
-    StringBuilder sb = new StringBuilder();
-    for (String name2 : names) {
-      sb.append(name2);
-      sb.append(" ");
-    }
-    if (getTypeParameters().length > 0) {
-      toStringTypeParams(sb);
-      sb.append(" ");
-    }
-    sb.append(returnType.getParameterizedQualifiedSourceName());
-    sb.append(" ");
-    sb.append(getName());
-
-    toStringParamsAndThrows(sb);
-
-    return sb.toString();
-  }
-
-  void setReturnType(JType type) {
-    returnType = type;
-  }
+  boolean isStatic();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JPackage.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JPackage.java
index b487ee0..4300512 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JPackage.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JPackage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,103 +15,55 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.dev.util.collect.Maps;
-
-import java.lang.annotation.Annotation;
-import java.util.Map;
-
 /**
  * Represents a logical package.
  */
-public class JPackage implements HasAnnotations {
-
-  private final String name;
-
-  private final Annotations annotations = new Annotations();
-
-  private Map<String, JRealClassType> types = Maps.create();
-
-  JPackage(String name) {
-    this.name = name;
-  }
-
-  void addAnnotations(Map<Class<? extends Annotation>, Annotation> annotations) {
-    this.annotations.addAnnotations(annotations);
-  }
-
-  public JClassType findType(String typeName) {
-    String[] parts = typeName.split("\\.");
-    return findType(parts);
-  }
-
-  public JClassType findType(String[] typeName) {
-    return findTypeImpl(typeName, 0);
-  }
-
-  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    return annotations.getAnnotation(annotationClass);
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public JClassType getType(String typeName) throws NotFoundException {
-    JClassType result = findType(typeName);
-    if (result == null) {
-      throw new NotFoundException();
-    }
-    return result;
-  }
-
-  public JClassType[] getTypes() {
-    return types.values().toArray(TypeOracle.NO_JCLASSES);
-  }
-
-  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
-    return annotations.isAnnotationPresent(annotationClass);
-  }
-
-  public boolean isDefault() {
-    return "".equals(name);
-  }
-
-  @Override
-  public String toString() {
-    return "package " + name;
-  }
-
-  void addType(JRealClassType type) {
-    types = Maps.put(types, type.getSimpleSourceName(), type);
-  }
-
-  JClassType findTypeImpl(String[] typeName, int index) {
-    JClassType found = types.get(typeName[index]);
-    if (found == null) {
-      return null;
-    } else if (index < typeName.length - 1) {
-      return found.findNestedTypeImpl(typeName, index + 1);
-    } else {
-      return found;
-    }
-  }
+public interface JPackage extends HasAnnotations {
 
   /**
-   * NOTE: This method is for testing purposes only.
+   * Finds a type in this package.
+   * 
+   * @param typeName the name of the type; use the <code>.</code> separator to
+   *          find a nested type
+   * @return the type, or <code>null</code> if the type does not exist in this
+   *         package
    */
-  Annotation[] getAnnotations() {
-    return annotations.getAnnotations();
-  }
+  JClassType findType(String typeName);
 
   /**
-   * NOTE: This method is for testing purposes only.
+   * Finds a type in this package.
+   * 
+   * @param typeName the name of the type; use additional array elements to find
+   *          a nested type
+   * @return the type, or <code>null</code> if the type does not exist in this
+   *         package
+   * @deprecated use {@link #findType(String)}
    */
-  Annotation[] getDeclaredAnnotations() {
-    return annotations.getDeclaredAnnotations();
-  }
+  @Deprecated
+  JClassType findType(String[] typeName);
 
-  void remove(JClassType type) {
-    types = Maps.remove(types, type.getSimpleSourceName());
-    // JDT will occasionally remove non-existent items, such as packages.
-  }
+  /**
+   * Returns the name of the package.
+   */
+  String getName();
+
+  /**
+   * Finds a type in this package.
+   * 
+   * @param typeName the name of the type; use the <code>.</code> separated to
+   *          search for a nested type
+   * @return the type, or <code>null</code> if the type does not exist in this
+   *         package
+   */
+  JClassType getType(String typeName) throws NotFoundException;
+
+  /**
+   * Returns all top-level types in this package.
+   */
+  JClassType[] getTypes();
+
+  /**
+   * Returns <code>true</code> only for the default package.
+   */
+  boolean isDefault();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameter.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameter.java
index 0cfe471..59a2b99 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameter.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,120 +15,15 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.dev.util.StringInterner;
-
-import java.lang.annotation.Annotation;
-import java.util.Map;
-
 /**
  * Represents a parameter in a declaration.
  */
 @SuppressWarnings("deprecation")
-public class JParameter implements HasAnnotations, HasMetaData {
+public interface JParameter extends HasAnnotations, HasMetaData {
 
-  private final Annotations annotations;
+  JAbstractMethod getEnclosingMethod();
 
-  private boolean argNameIsReal;
+  String getName();
 
-  private final JAbstractMethod enclosingMethod;
-
-  private String name;
-
-  private JType type;
-
-  JParameter(JAbstractMethod enclosingMethod, JParameter srcParam) {
-    this.enclosingMethod = enclosingMethod;
-    this.type = srcParam.type;
-    this.name = StringInterner.get().intern(srcParam.name);
-    this.annotations = new Annotations(srcParam.annotations);
-  }
-
-  JParameter(JAbstractMethod enclosingMethod, JType type, String name) {
-    this(enclosingMethod, type, name, null);
-  }
-
-  JParameter(JAbstractMethod enclosingMethod, JType type, String name,
-      Map<Class<? extends Annotation>, Annotation> declaredAnnotations) {
-    this(enclosingMethod, type, name, declaredAnnotations, true);
-  }
-
-  JParameter(JAbstractMethod enclosingMethod, JType type, String name,
-      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
-      boolean argNameIsReal) {
-    this.enclosingMethod = enclosingMethod;
-    this.type = type;
-    this.name = StringInterner.get().intern(name);
-    this.argNameIsReal = argNameIsReal;
-
-    enclosingMethod.addParameter(this);
-
-    annotations = new Annotations(declaredAnnotations);
-  }
-
-  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    return annotations.getAnnotation(annotationClass);
-  }
-
-  public JAbstractMethod getEnclosingMethod() {
-    return enclosingMethod;
-  }
-
-  @Deprecated
-  public final String[][] getMetaData(String tagName) {
-    return TypeOracle.NO_STRING_ARR_ARR;
-  }
-
-  @Deprecated
-  public final String[] getMetaDataTags() {
-    return TypeOracle.NO_STRINGS;
-  }
-
-  public String getName() {
-    if (!argNameIsReal) {
-      name = enclosingMethod.getRealParameterName(this);
-      argNameIsReal = true;
-    }
-    return name;
-  }
-
-  public JType getType() {
-    return type;
-  }
-
-  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
-    return annotations.isAnnotationPresent(annotationClass);
-  }
-
-  @Override
-  public String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.append(type.getParameterizedQualifiedSourceName());
-    sb.append(" ");
-    sb.append(getName());
-    return sb.toString();
-  }
-
-  /**
-   * NOTE: This method is for testing purposes only.
-   */
-  Annotation[] getAnnotations() {
-    return annotations.getAnnotations();
-  }
-
-  /**
-   * NOTE: This method is for testing purposes only.
-   */
-  Annotation[] getDeclaredAnnotations() {
-    return annotations.getDeclaredAnnotations();
-  }
-
-  // Only called by JAbstractMethod after real parameter names are fetched.
-  void setName(String name) {
-    this.name = StringInterner.get().intern(name);
-  }
-
-  // Called when parameter types are found to be parameterized
-  void setType(JType type) {
-    this.type = type;
-  }
+  JType getType();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java
index 1088335..3f26dec 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,529 +15,21 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
-import com.google.gwt.dev.util.collect.IdentityHashMap;
-import com.google.gwt.dev.util.collect.Lists;
-import com.google.gwt.dev.util.collect.Maps;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * Represents a parameterized type in a declaration.
  */
-public class JParameterizedType extends JMaybeParameterizedType {
-  /**
-   * Create a parameterized type along with any necessary enclosing
-   * parameterized types. Enclosing parameterized types are necessary when the
-   * base type is a non-static member and the enclosing type is also generic.
-   */
-  private static JParameterizedType createParameterizedTypeRecursive(
-      JGenericType baseType, Map<JTypeParameter, JClassType> substitutionMap) {
-    JClassType enclosingType = baseType.getEnclosingType();
-    if (baseType.isMemberType() && !baseType.isStatic()) {
-      // This base type is a non-static generic type so we build the necessary
-      // enclosing parameterized type and update the enclosing type to be
-      // a parameterized type.
-      JGenericType isGenericEnclosingType = enclosingType.isGenericType();
-      if (isGenericEnclosingType != null) {
-        enclosingType = createParameterizedTypeRecursive(
-            isGenericEnclosingType, substitutionMap);
-      }
-    }
 
-    JTypeParameter[] typeParameters = baseType.getTypeParameters();
-    JClassType[] newTypeArgs = new JClassType[typeParameters.length];
-    TypeOracle oracle = baseType.getOracle();
-    for (int i = 0; i < newTypeArgs.length; ++i) {
-      JClassType newTypeArg = substitutionMap.get(typeParameters[i]);
-      if (newTypeArg == null) {
-        newTypeArg = oracle.getWildcardType(BoundType.EXTENDS,
-            typeParameters[i].getFirstBound());
-      }
+public interface JParameterizedType extends JClassType {
 
-      newTypeArgs[i] = newTypeArg;
-    }
-
-    JParameterizedType parameterizedType = oracle.getParameterizedType(
-        baseType, enclosingType, newTypeArgs);
-    return parameterizedType;
-  }
-
-  private final JClassType enclosingType;
-
-  private List<JClassType> interfaces;
-
-  /**
-   * This map records the JClassType that should be used in place of a given
-   * {@link JTypeParameter}.
-   */
-  private Map<JTypeParameter, JClassType> lazySubstitutionMap;
-
-  private JClassType lazySuperclass;
-
-  private final AbstractMembers members;
-
-  private final List<JClassType> typeArgs;
-
-  JParameterizedType(JGenericType baseType, JClassType enclosingType,
-      JClassType[] typeArgs) {
-    super.setBaseType(baseType);
-
-    this.enclosingType = enclosingType;
-
-    // NOTE: this instance is not considered a nested type of the enclosing type
-
-    final JParameterizedType parameterizedType = this;
-    members = new DelegateMembers(this, baseType, new Substitution() {
-      public JType getSubstitution(JType type) {
-        return type.getSubstitutedType(parameterizedType);
-      }
-    });
-
-    this.typeArgs = Lists.create(typeArgs);
-    assert (this.typeArgs.indexOf(null) == -1) : "Unresolved typeArg creating JParameterizedType from "
-        + baseType;
-
-    // NOTE: Can't perform substitutions until we are done building
-  }
-
-  @Override
-  public JConstructor findConstructor(JType[] paramTypes) {
-    return members.findConstructor(paramTypes);
-  }
-
-  @Override
-  public JField findField(String name) {
-    return members.findField(name);
-  }
-
-  @Override
-  public JMethod findMethod(String name, JType[] paramTypes) {
-    return members.findMethod(name, paramTypes);
-  }
-
-  @Override
-  public JClassType findNestedType(String typeName) {
-    return members.findNestedType(typeName);
-  }
-
-  @Override
-  public JConstructor getConstructor(JType[] paramTypes)
-      throws NotFoundException {
-    return members.getConstructor(paramTypes);
-  }
-
-  @Override
-  public JConstructor[] getConstructors() {
-    return members.getConstructors();
-  }
-
-  @Override
-  public JClassType getEnclosingType() {
-    return enclosingType;
-  }
-
-  @Override
-  public JField getField(String name) {
-    return members.getField(name);
-  }
-
-  @Override
-  public JField[] getFields() {
-    return members.getFields();
-  }
-
-  @Override
-  public JClassType[] getImplementedInterfaces() {
-    if (interfaces == null) {
-      interfaces = new ArrayList<JClassType>();
-      JClassType[] intfs = getBaseType().getImplementedInterfaces();
-      for (JClassType intf : intfs) {
-        JClassType newIntf = intf.getSubstitutedType(this);
-        interfaces.add(newIntf);
-      }
-      interfaces = Lists.normalize(interfaces);
-    }
-    return interfaces.toArray(TypeOracle.NO_JCLASSES);
-  }
-
-  @Override
-  public JMethod[] getInheritableMethods() {
-    return members.getInheritableMethods();
-  }
-
-  @Override
-  public JMethod getMethod(String name, JType[] paramTypes)
-      throws NotFoundException {
-    return members.getMethod(name, paramTypes);
-  }
-
-  @Override
-  public JMethod[] getMethods() {
-    return members.getMethods();
-  }
-
-  @Override
-  public JClassType getNestedType(String typeName) throws NotFoundException {
-    return members.getNestedType(typeName);
-  }
-
-  @Override
-  public JClassType[] getNestedTypes() {
-    return members.getNestedTypes();
-  }
+  JGenericType getBaseType();
 
   /**
    * @deprecated See {@link #getQualifiedSourceName()}
    */
   @Deprecated
-  public String getNonParameterizedQualifiedSourceName() {
-    return getQualifiedSourceName();
-  }
+  String getNonParameterizedQualifiedSourceName();
 
-  @Override
-  public JMethod[] getOverloads(String name) {
-    return members.getOverloads(name);
-  }
+  JClassType getRawType();
 
-  @Override
-  public JMethod[] getOverridableMethods() {
-    return members.getOverridableMethods();
-  }
-
-  @Override
-  public String getParameterizedQualifiedSourceName() {
-    StringBuffer sb = new StringBuffer();
-
-    if (getEnclosingType() != null) {
-      sb.append(getEnclosingType().getParameterizedQualifiedSourceName());
-      sb.append(".");
-      sb.append(getSimpleSourceName());
-    } else {
-      sb.append(getQualifiedSourceName());
-    }
-
-    if (typeArgs.size() > 0) {
-      sb.append('<');
-      boolean needComma = false;
-      for (JType typeArg : typeArgs) {
-        if (needComma) {
-          sb.append(", ");
-        } else {
-          needComma = true;
-        }
-        sb.append(typeArg.getParameterizedQualifiedSourceName());
-      }
-      sb.append('>');
-    } else {
-      /*
-       * Non-static, inner classes of generic types are modeled as generic, even
-       * if they do not declare type parameters or reference the type parameters
-       * of their enclosing generic type.
-       */
-    }
-
-    return sb.toString();
-  }
-
-  @Override
-  public String getQualifiedBinaryName() {
-    return getBaseType().getQualifiedBinaryName();
-  }
-
-  /**
-   * Everything is fully qualified and includes the &lt; and &gt; in the
-   * signature.
-   */
-  @Override
-  public String getQualifiedSourceName() {
-    return getBaseType().getQualifiedSourceName();
-  }
-
-  public JClassType getRawType() {
-    return getBaseType().getRawType();
-  }
-
-  /**
-   * In this case, the raw type name.
-   */
-  @Override
-  public String getSimpleSourceName() {
-    return getBaseType().getSimpleSourceName();
-  }
-
-  /*
-   * Goal: Return a list of possible subtypes of this parameterized type. In the
-   * event that we have generic subtypes and we cannot resolve the all of the
-   * type arguments, we need to wildcard types in place of the arguments that we
-   * cannot resolve.
-   * 
-   * Algorithm: - Ask generic type for its subtypes - Filter subtypes of the
-   * generic which cannot be our subtype.
-   */
-  @Override
-  public JClassType[] getSubtypes() {
-    List<JClassType> subtypeList = new ArrayList<JClassType>();
-
-    // Parameterized types are not tracked in the subtype hierarchy; ask base
-    // type
-    JClassType[] genericSubtypes = getBaseType().getSubtypes();
-    for (JClassType subtype : genericSubtypes) {
-      // Could be a subtype depending on how it is substituted
-      Map<JTypeParameter, JClassType> substitutions = findSubtypeSubstitution(subtype);
-      if (substitutions != null) {
-        JGenericType genericType = subtype.isGenericType();
-        if (genericType != null) {
-          subtype = createParameterizedTypeRecursive(genericType, substitutions);
-        } else {
-          // If this is not a generic type then there should not be any
-          // substitution.
-          assert (substitutions.isEmpty());
-        }
-
-        subtypeList.add(subtype);
-      }
-    }
-
-    return subtypeList.toArray(TypeOracle.NO_JCLASSES);
-  }
-
-  @Override
-  public JClassType getSuperclass() {
-    if (isInterface() != null) {
-      return null;
-    }
-
-    if (lazySuperclass == null) {
-      JGenericType baseType = getBaseType();
-      JClassType superclass = baseType.getSuperclass();
-      assert (superclass != null);
-      lazySuperclass = superclass.getSubstitutedType(this);
-    }
-
-    return lazySuperclass;
-  }
-
-  public JClassType[] getTypeArgs() {
-    return typeArgs.toArray(TypeOracle.NO_JCLASSES);
-  }
-
-  @Override
-  public JGenericType isGenericType() {
-    return null;
-  }
-
-  @Override
-  public JParameterizedType isParameterized() {
-    return this;
-  }
-
-  @Override
-  public JRawType isRawType() {
-    return null;
-  }
-
-  @Override
-  public JWildcardType isWildcard() {
-    return null;
-  }
-
-  @Override
-  public String toString() {
-    if (isInterface() != null) {
-      return "interface " + getParameterizedQualifiedSourceName();
-    }
-
-    return "class " + getParameterizedQualifiedSourceName();
-  }
-
-  @Override
-  protected JClassType findNestedTypeImpl(String[] typeName, int index) {
-    return members.findNestedTypeImpl(typeName, index);
-  }
-
-  @Override
-  protected void getInheritableMethodsOnSuperclassesAndThisClass(
-      Map<String, JMethod> methodsBySignature) {
-    members.getInheritableMethodsOnSuperclassesAndThisClass(methodsBySignature);
-  }
-
-  /**
-   * Gets the methods declared in interfaces that this type extends. If this
-   * type is a class, its own methods are not added. If this type is an
-   * interface, its own methods are added. Used internally by
-   * {@link #getOverridableMethods()}.
-   * 
-   * @param methodsBySignature
-   */
-  @Override
-  protected void getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
-      Map<String, JMethod> methodsBySignature) {
-    members.getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
-  }
-
-  @Override
-  JClassType getSubstitutedType(JParameterizedType parameterizedType) {
-    maybeInitializeTypeParameterSubstitutionMap();
-
-    if (this == parameterizedType) {
-      return this;
-    }
-
-    JClassType[] newTypeArgs = new JClassType[typeArgs.size()];
-    for (int i = 0; i < newTypeArgs.length; ++i) {
-      newTypeArgs[i] = typeArgs.get(i).getSubstitutedType(parameterizedType);
-    }
-
-    return getOracle().getParameterizedType(getBaseType(), getEnclosingType(),
-        newTypeArgs);
-  }
-
-  /**
-   * Returns the {@link JClassType} that is a substitute for the given
-   * {@link JTypeParameter}. If there is no substitution, the original
-   * {@link JTypeParameter} is returned.
-   */
-  JClassType getTypeParameterSubstitution(JTypeParameter typeParameter) {
-    maybeInitializeTypeParameterSubstitutionMap();
-
-    JClassType substitute = lazySubstitutionMap.get(typeParameter);
-    if (substitute != null) {
-      return substitute;
-    }
-
-    return typeParameter;
-  }
-
-  boolean hasTypeArgs(JClassType[] otherArgTypes) {
-    if (otherArgTypes.length != typeArgs.size()) {
-      return false;
-    }
-
-    for (int i = 0; i < otherArgTypes.length; ++i) {
-      // Identity tests are ok since identity is durable within an oracle.
-      //
-      if (otherArgTypes[i] != typeArgs.get(i)) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  /**
-   * Initialize a map of substitutions for {@link JTypeParameter}s to
-   * corresponding {@link JClassType}s. This can only be initialized after the
-   * {@link com.google.gwt.dev.javac.TypeOracleMediator TypeOracleMediator} has
-   * fully resolved all of the {@link JClassType}s.
-   */
-  void maybeInitializeTypeParameterSubstitutionMap() {
-    if (lazySubstitutionMap != null) {
-      return;
-    }
-    lazySubstitutionMap = new IdentityHashMap<JTypeParameter, JClassType>();
-
-    JParameterizedType currentParameterizedType = this;
-
-    while (currentParameterizedType != null) {
-      JGenericType genericType = currentParameterizedType.getBaseType();
-      JTypeParameter[] typeParameters = genericType.getTypeParameters();
-      JClassType[] typeArguments = currentParameterizedType.getTypeArgs();
-
-      for (JTypeParameter typeParameter : typeParameters) {
-        lazySubstitutionMap.put(typeParameter,
-            typeArguments[typeParameter.getOrdinal()]);
-      }
-
-      if (currentParameterizedType.isStatic()) {
-        break;
-      }
-
-      JClassType maybeParameterizedType = currentParameterizedType.getEnclosingType();
-      if (maybeParameterizedType == null
-          || maybeParameterizedType.isParameterized() == null) {
-        break;
-      }
-      currentParameterizedType = maybeParameterizedType.isParameterized();
-    }
-    lazySubstitutionMap = Maps.normalize(lazySubstitutionMap);
-  }
-
-  void setTypeArguments(JClassType[] typeArgs) {
-    this.typeArgs.addAll(Arrays.asList(typeArgs));
-  }
-
-  /**
-   * Returns a map of substitutions that will make the subtype a proper subtype
-   * of this parameterized type. The map maybe empty in the case that it is
-   * already an exact subtype.
-   */
-  private Map<JTypeParameter, JClassType> findSubtypeSubstitution(
-      JClassType subtype) {
-    Map<JTypeParameter, JClassType> substitutions = new IdentityHashMap<JTypeParameter, JClassType>();
-
-    // Get the supertype hierarchy. If this JParameterizedType exists
-    // exactly in this set we are done.
-    Set<JClassType> supertypeHierarchy = getFlattenedSuperTypeHierarchy(subtype);
-    if (supertypeHierarchy.contains(this)) {
-      return substitutions;
-    }
-
-    /*
-     * Try to find a parameterized supertype whose base type is the same as our
-     * own. Because that parameterized supertype might be made into ourself via
-     * substitution.
-     */
-    for (JClassType candidate : supertypeHierarchy) {
-      JParameterizedType parameterizedCandidate = candidate.isParameterized();
-      if (parameterizedCandidate == null) {
-        // If not parameterized then there is no substitution possible.
-        continue;
-      }
-
-      if (parameterizedCandidate.getBaseType() != getBaseType()) {
-        // This candidate be parameterized to us.
-        continue;
-      }
-
-      /*
-       * We have a parameterization of our base type. Now we need to see if it
-       * is possible to parameterize subtype such that candidate becomes
-       * equivalent to us.
-       */
-      JClassType[] candidateTypeArgs = parameterizedCandidate.getTypeArgs();
-      JClassType[] myTypeArgs = getTypeArgs();
-      for (int i = 0; i < myTypeArgs.length; ++i) {
-        JClassType otherTypeArg = candidateTypeArgs[i];
-        JClassType myTypeArg = myTypeArgs[i];
-
-        if (myTypeArg == otherTypeArg) {
-          // There are identical so there is no substitution that is needed.
-          continue;
-        }
-
-        JTypeParameter otherTypeParameter = otherTypeArg.isTypeParameter();
-        if (otherTypeParameter == null) {
-          // Not a type parameter and not equal so no substitution can make it
-          // equal.
-          return null;
-        }
-
-        if (!otherTypeParameter.isAssignableFrom(myTypeArg)) {
-          // Make sure that my type argument can be substituted for this type
-          // parameter.
-          return null;
-        }
-
-        substitutions.put(otherTypeParameter, myTypeArg);
-      }
-    }
-
-    // Legal substitution can be made and is record in substitutions.
-    return substitutions;
-  }
+  JClassType[] getTypeArgs();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JPrimitiveType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JPrimitiveType.java
index 0c6a2b9..a14435d 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JPrimitiveType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JPrimitiveType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -31,46 +31,31 @@
 /**
  * Represents a primitive type in a declaration.
  */
-public class JPrimitiveType extends JType {
-  public static final JPrimitiveType BOOLEAN = create("boolean", "Boolean",
-      DESC_BOOLEAN, "false");
-  public static final JPrimitiveType BYTE = create("byte", "Byte", DESC_BYTE,
-      "0");
-  public static final JPrimitiveType CHAR = create("char", "Character",
-      DESC_CHAR, "0");
-  public static final JPrimitiveType DOUBLE = create("double", "Double",
-      DESC_DOUBLE, "0d");
-  public static final JPrimitiveType FLOAT = create("float", "Float",
-      DESC_FLOAT, "0f");
-  public static final JPrimitiveType INT = create("int", "Integer", DESC_INT,
-      "0");
-  public static final JPrimitiveType LONG = create("long", "Long", DESC_LONG,
-      "0L");
-  public static final JPrimitiveType SHORT = create("short", "Short",
-      DESC_SHORT, "0");
-  public static final JPrimitiveType VOID = create("void", "Void", DESC_VOID,
-      "null");
+public enum JPrimitiveType implements JType {
+  BOOLEAN("boolean", "Boolean", DESC_BOOLEAN, "false"), //
+  BYTE("byte", "Byte", DESC_BYTE, "0"), //
+  CHAR("char", "Character", DESC_CHAR, "0"), //
+  DOUBLE("double", "Double", DESC_DOUBLE, "0d"), //
+  FLOAT("float", "Float", DESC_FLOAT, "0f"), //
+  INT("int", "Integer", DESC_INT, "0"), //
+  LONG("long", "Long", DESC_LONG, "0L"), //
+  SHORT("short", "Short", DESC_SHORT, "0"), //
+  VOID("void", "Void", DESC_VOID, "null");
 
-  private static Map<String, JPrimitiveType> map;
-
-  public static JPrimitiveType valueOf(String typeName) {
-    return getMap().get(typeName);
-  }
-
-  private static JPrimitiveType create(String name, String boxedName, char jni,
-      String defaultValue) {
-    JPrimitiveType type = new JPrimitiveType(name, boxedName,
-        String.valueOf(jni), defaultValue);
-    Object existing = getMap().put(name, type);
-    assert (existing == null);
-    return type;
-  }
-
-  private static Map<String, JPrimitiveType> getMap() {
-    if (map == null) {
-      map = new HashMap<String, JPrimitiveType>();
+  /**
+   * Lazy-initialized map of Java identifier name to enum values.
+   */
+  private static class NameMap {
+    static final Map<String, JPrimitiveType> map = new HashMap<String, JPrimitiveType>();
+    static {
+      for (JPrimitiveType type : JPrimitiveType.values()) {
+        map.put(type.getSimpleSourceName(), type);
+      }
     }
-    return map;
+  }
+
+  public static JPrimitiveType parse(String name) {
+    return NameMap.map.get(name);
   }
 
   private final String boxedName;
@@ -81,25 +66,30 @@
 
   private final String name;
 
-  private JPrimitiveType(String name, String boxedName, String jni,
+  private JPrimitiveType(String name, String boxedName, char jni,
       String defaultValue) {
     this.name = name;
     this.boxedName = boxedName;
-    this.jni = jni;
+    this.jni = String.valueOf(jni);
     this.defaultValue = defaultValue;
   }
 
-  @Override
   public JType getErasedType() {
     return this;
   }
 
-  @Override
   public String getJNISignature() {
     return jni;
   }
 
-  @Override
+  public JType getLeafType() {
+    return this;
+  }
+
+  public String getParameterizedQualifiedSourceName() {
+    return name;
+  }
+
   public String getQualifiedBinaryName() {
     return name;
   }
@@ -108,12 +98,10 @@
     return "java.lang." + boxedName;
   }
 
-  @Override
   public String getQualifiedSourceName() {
     return name;
   }
 
-  @Override
   public String getSimpleSourceName() {
     return name;
   }
@@ -122,52 +110,50 @@
     return defaultValue;
   }
 
-  @Override
+  public JAnnotationType isAnnotation() {
+    return null;
+  }
+
   public JArrayType isArray() {
-    // intentional null
     return null;
   }
 
-  @Override
   public JClassType isClass() {
-    // intentional null
     return null;
   }
 
-  @Override
+  public JClassType isClassOrInterface() {
+    return null;
+  }
+
   public JEnumType isEnum() {
     return null;
   }
 
-  @Override
   public JGenericType isGenericType() {
     return null;
   }
 
-  @Override
   public JClassType isInterface() {
-    // intentional null
     return null;
   }
 
-  @Override
   public JParameterizedType isParameterized() {
-    // intentional null
     return null;
   }
 
-  @Override
   public JPrimitiveType isPrimitive() {
     return this;
   }
 
-  @Override
   public JRawType isRawType() {
-    // intentional null
     return null;
   }
 
-  @Override
+  public JTypeParameter isTypeParameter() {
+    return null;
+  }
+
   public JWildcardType isWildcard() {
     return null;
   }
@@ -176,9 +162,4 @@
   public String toString() {
     return name;
   }
-
-  @Override
-  JPrimitiveType getSubstitutedType(JParameterizedType parameterizedType) {
-    return this;
-  }
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java
index c1f1360..14e4c12 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,197 +15,14 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Represents a raw type; that is a generic type with no type arguments.
  */
-public class JRawType extends JMaybeParameterizedType {
-  private static final Substitution ERASURE_SUBSTITUTION = new Substitution() {
-    public JType getSubstitution(JType type) {
-      return type.getErasedType();
-    }
-  };
+public interface JRawType extends JClassType {
 
-  private List<JClassType> interfaces;
+  JParameterizedType asParameterizedByWildcards();
 
-  private final AbstractMembers members;
+  JGenericType getBaseType();
 
-  JRawType(JGenericType genericType) {
-    super.setBaseType(genericType);
-    members = new DelegateMembers(this, getBaseType(), ERASURE_SUBSTITUTION);
-  }
-
-  public JParameterizedType asParameterizedByWildcards() {
-    return getBaseType().asParameterizedByWildcards();
-  }
-
-  @Override
-  public JConstructor findConstructor(JType[] paramTypes) {
-    return members.findConstructor(paramTypes);
-  }
-
-  @Override
-  public JField findField(String name) {
-    return members.findField(name);
-  }
-
-  @Override
-  public JMethod findMethod(String name, JType[] paramTypes) {
-    return members.findMethod(name, paramTypes);
-  }
-
-  @Override
-  public JClassType findNestedType(String typeName) {
-    return members.findNestedType(typeName);
-  }
-
-  @Override
-  public JConstructor getConstructor(JType[] paramTypes)
-      throws NotFoundException {
-    return members.getConstructor(paramTypes);
-  }
-
-  @Override
-  public JConstructor[] getConstructors() {
-    return members.getConstructors();
-  }
-
-  @Override
-  public JField getField(String name) {
-    return members.getField(name);
-  }
-
-  @Override
-  public JField[] getFields() {
-    return members.getFields();
-  }
-
-  public JGenericType getGenericType() {
-    return getBaseType();
-  }
-
-  @Override
-  public JClassType[] getImplementedInterfaces() {
-    if (interfaces == null) {
-      interfaces = new ArrayList<JClassType>();
-      JClassType[] intfs = getBaseType().getImplementedInterfaces();
-      for (JClassType intf : intfs) {
-        JClassType newIntf = intf.getErasedType();
-        interfaces.add(newIntf);
-      }
-    }
-    return interfaces.toArray(TypeOracle.NO_JCLASSES);
-  }
-
-  @Override
-  public JMethod[] getInheritableMethods() {
-    return members.getInheritableMethods();
-  }
-
-  @Override
-  public JMethod getMethod(String name, JType[] paramTypes)
-      throws NotFoundException {
-    return members.getMethod(name, paramTypes);
-  }
-
-  @Override
-  public JMethod[] getMethods() {
-    return members.getMethods();
-  }
-
-  @Override
-  public JClassType getNestedType(String typeName) throws NotFoundException {
-    return members.getNestedType(typeName);
-  }
-
-  @Override
-  public JClassType[] getNestedTypes() {
-    return members.getNestedTypes();
-  }
-
-  @Override
-  public JMethod[] getOverloads(String name) {
-    return members.getOverloads(name);
-  }
-
-  @Override
-  public JMethod[] getOverridableMethods() {
-    return members.getOverridableMethods();
-  }
-
-  @Override
-  public String getParameterizedQualifiedSourceName() {
-    return getQualifiedSourceName();
-  }
-
-  @Override
-  public String getQualifiedBinaryName() {
-    return getBaseType().getQualifiedBinaryName();
-  }
-
-  @Override
-  public String getQualifiedSourceName() {
-    return getBaseType().getQualifiedSourceName();
-  }
-
-  @Override
-  public String getSimpleSourceName() {
-    return getBaseType().getSimpleSourceName();
-  }
-
-  @Override
-  public JClassType[] getSubtypes() {
-    JClassType[] baseSubTypes = super.getSubtypes();
-    JClassType[] rawSubTypes = new JClassType[baseSubTypes.length];
-    for (int i = 0; i < baseSubTypes.length; ++i) {
-      JClassType subType = baseSubTypes[i];
-      JGenericType isGenericType = subType.isGenericType();
-      if (isGenericType != null) {
-        rawSubTypes[i] = isGenericType.getRawType();
-      } else {
-        rawSubTypes[i] = subType;
-      }
-    }
-    return rawSubTypes;
-  }
-
-  @Override
-  public JClassType getSuperclass() {
-    JClassType baseSuper = getBaseType().getSuperclass();
-    if (baseSuper == null) {
-      return null;
-    }
-
-    return baseSuper.getErasedType();
-  }
-
-  @Override
-  public JGenericType isGenericType() {
-    return null;
-  }
-
-  @Override
-  public JParameterizedType isParameterized() {
-    return null;
-  }
-
-  @Override
-  public JRawType isRawType() {
-    return this;
-  }
-
-  @Override
-  public JWildcardType isWildcard() {
-    return null;
-  }
-
-  @Override
-  JRawType getSubstitutedType(JParameterizedType parameterizedType) {
-    /*
-     * Raw types do not participate in substitution.
-     */
-    return this;
-  }
+  JGenericType getGenericType();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java
index b40ab8d..ad1f909 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,550 +15,8 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.dev.util.StringInterner;
-import com.google.gwt.dev.util.collect.IdentitySets;
-import com.google.gwt.dev.util.collect.Lists;
-
-import java.lang.annotation.Annotation;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * Type representing a Java class or interface type that a user would declare.
  */
-public class JRealClassType extends JClassType {
-
-  private Set<JClassType> allSubtypes = IdentitySets.create();
-
-  private final Annotations annotations = new Annotations();
-
-  private final JPackage declaringPackage;
-
-  /**
-   * Set when this class is resolved, then never modified.
-   */
-  private JClassType enclosingType;
-
-  private List<JClassType> interfaces = Lists.create();
-
-  private final boolean isInterface;
-
-  private String lazyQualifiedBinaryName;
-
-  private String lazyQualifiedName;
-
-  private final Members members = new Members(this);
-
-  private int modifierBits;
-
-  private final String name;
-
-  private final String nestedName;
-
-  private final TypeOracle oracle;
-
-  private JClassType superclass;
-
-  /**
-   * Create a class type that reflects an actual type.
-   * 
-   * @param oracle
-   * @param declaringPackage
-   * @param enclosingTypeName the fully qualified source name of the enclosing
-   *          class or null if a top-level class - setEnclosingType must be
-   *          called later with the proper enclosing type if this is non-null
-   * @param isLocalType
-   * @param name
-   * @param isInterface
-   */
-  JRealClassType(TypeOracle oracle, JPackage declaringPackage,
-      String enclosingTypeName, String name, boolean isInterface) {
-    this.oracle = oracle;
-    this.declaringPackage = declaringPackage;
-    this.name = StringInterner.get().intern(name);
-    this.isInterface = isInterface;
-    if (enclosingTypeName == null) {
-      // Add myself to my package.
-      //
-      declaringPackage.addType(this);
-      // The nested name of a top-level class is its simple name.
-      //
-      nestedName = name;
-    } else {
-      // Compute my "nested name".
-      //
-      nestedName = enclosingTypeName + "." + name;
-
-      // We will add ourselves to the enclosing class when it is set in
-      // setEnclosingType().
-    }
-    oracle.addNewType(this);
-  }
-
-  @Override
-  public void addModifierBits(int bits) {
-    modifierBits |= bits;
-  }
-
-  @Override
-  public JConstructor findConstructor(JType[] paramTypes) {
-    return members.findConstructor(paramTypes);
-  }
-
-  @Override
-  public JField findField(String name) {
-    return members.findField(name);
-  }
-
-  @Override
-  public JMethod findMethod(String name, JType[] paramTypes) {
-    return members.findMethod(name, paramTypes);
-  }
-
-  @Override
-  public JClassType findNestedType(String typeName) {
-    return members.findNestedType(typeName);
-  }
-
-  @Override
-  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    return annotations.getAnnotation(annotationClass);
-  }
-
-  @Override
-  public JConstructor getConstructor(JType[] paramTypes)
-      throws NotFoundException {
-    return members.getConstructor(paramTypes);
-  }
-
-  @Override
-  public JConstructor[] getConstructors() {
-    return members.getConstructors();
-  }
-
-  @Override
-  public JClassType getEnclosingType() {
-    return enclosingType;
-  }
-
-  @Override
-  public JClassType getErasedType() {
-    return this;
-  }
-
-  @Override
-  public JField getField(String name) {
-    return members.getField(name);
-  }
-
-  @Override
-  public JField[] getFields() {
-    return members.getFields();
-  }
-
-  @Override
-  public JClassType[] getImplementedInterfaces() {
-    return interfaces.toArray(TypeOracle.NO_JCLASSES);
-  }
-
-  @Override
-  public JMethod[] getInheritableMethods() {
-    return members.getInheritableMethods();
-  }
-
-  @Override
-  public String getJNISignature() {
-    String typeName = nestedName.replace('.', '$');
-    String packageName = getPackage().getName().replace('.', '/');
-    if (packageName.length() > 0) {
-      packageName += "/";
-    }
-    return "L" + packageName + typeName + ";";
-  }
-
-  @Override
-  public JMethod getMethod(String name, JType[] paramTypes)
-      throws NotFoundException {
-    return members.getMethod(name, paramTypes);
-  }
-
-  @Override
-  public JMethod[] getMethods() {
-    return members.getMethods();
-  }
-
-  @Override
-  public String getName() {
-    return nestedName;
-  }
-
-  @Override
-  public JClassType getNestedType(String typeName) throws NotFoundException {
-    return members.getNestedType(typeName);
-  }
-
-  @Override
-  public JClassType[] getNestedTypes() {
-    return members.getNestedTypes();
-  }
-
-  @Override
-  public TypeOracle getOracle() {
-    return oracle;
-  }
-
-  @Override
-  public JMethod[] getOverloads(String name) {
-    return members.getOverloads(name);
-  }
-
-  @Override
-  public JMethod[] getOverridableMethods() {
-    return members.getOverridableMethods();
-  }
-
-  @Override
-  public JPackage getPackage() {
-    return declaringPackage;
-  }
-
-  @Override
-  public String getQualifiedBinaryName() {
-    if (lazyQualifiedBinaryName == null) {
-      lazyQualifiedBinaryName = "";
-      JPackage pkg = getPackage();
-      if (!pkg.isDefault()) {
-        lazyQualifiedBinaryName = pkg.getName() + ".";
-      }
-      lazyQualifiedBinaryName += nestedName.replace('.', '$');
-    }
-    return lazyQualifiedBinaryName;
-  }
-
-  @Override
-  public String getQualifiedSourceName() {
-    if (lazyQualifiedName == null) {
-      JPackage pkg = getPackage();
-      if (!pkg.isDefault()) {
-        lazyQualifiedName = pkg.getName() + "." + nestedName;
-      } else {
-        lazyQualifiedName = nestedName;
-      }
-      lazyQualifiedName = StringInterner.get().intern(lazyQualifiedName);
-    }
-    return lazyQualifiedName;
-  }
-
-  @Override
-  public String getSimpleSourceName() {
-    return name;
-  }
-
-  @Override
-  public JClassType[] getSubtypes() {
-    return allSubtypes.toArray(TypeOracle.NO_JCLASSES);
-  }
-
-  @Override
-  public JClassType getSuperclass() {
-    return superclass;
-  }
-
-  @Override
-  public boolean isAbstract() {
-    return 0 != (modifierBits & TypeOracle.MOD_ABSTRACT);
-  }
-
-  @Override
-  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
-    return annotations.isAnnotationPresent(annotationClass);
-  }
-
-  @Override
-  public JArrayType isArray() {
-    // intentional null
-    return null;
-  }
-
-  @Override
-  public JClassType isClass() {
-    return isInterface ? null : this;
-  }
-
-  /**
-   * Determines if the class can be constructed using a simple <code>new</code>
-   * operation. Specifically, the class must
-   * <ul>
-   * <li>be a class rather than an interface,</li>
-   * <li>have either no constructors or a parameterless constructor, and</li>
-   * <li>be a top-level class or a static nested class.</li>
-   * </ul>
-   * 
-   * @return <code>true</code> if the type is default instantiable, or
-   *         <code>false</code> otherwise
-   */
-  @Override
-  public boolean isDefaultInstantiable() {
-    if (isInterface() != null || isAbstract()) {
-      return false;
-    }
-    if (isMemberType() && !isStatic()) {
-      return false;
-    }
-    if (getConstructors().length == 0) {
-      return true;
-    }
-    JConstructor ctor = findConstructor(TypeOracle.NO_JTYPES);
-    if (ctor != null) {
-      return true;
-    }
-    return false;
-  }
-
-  @Override
-  public JEnumType isEnum() {
-    return null;
-  }
-
-  @Override
-  public boolean isFinal() {
-    return 0 != (getModifierBits() & TypeOracle.MOD_FINAL);
-  }
-
-  @Override
-  public JGenericType isGenericType() {
-    return null;
-  }
-
-  @Override
-  public JClassType isInterface() {
-    return isInterface ? this : null;
-  }
-
-  /**
-   * Tests if this type is contained within another type.
-   * 
-   * @return true if this type has an enclosing type, false if this type is a
-   *         top-level type
-   */
-  @Override
-  public boolean isMemberType() {
-    return enclosingType != null;
-  }
-
-  @Override
-  public JParameterizedType isParameterized() {
-    // intentional null
-    return null;
-  }
-
-  @Override
-  public JPrimitiveType isPrimitive() {
-    // intentional null
-    return null;
-  }
-
-  @Override
-  public boolean isPrivate() {
-    return 0 != (modifierBits & TypeOracle.MOD_PRIVATE);
-  }
-
-  @Override
-  public boolean isProtected() {
-    return 0 != (modifierBits & TypeOracle.MOD_PROTECTED);
-  }
-
-  @Override
-  public boolean isPublic() {
-    return 0 != (modifierBits & TypeOracle.MOD_PUBLIC);
-  }
-
-  @Override
-  public JRawType isRawType() {
-    // TODO Override in JGenericType?
-    return null;
-  }
-
-  @Override
-  public boolean isStatic() {
-    return 0 != (modifierBits & TypeOracle.MOD_STATIC);
-  }
-
-  @Override
-  public JWildcardType isWildcard() {
-    return null;
-  }
-
-  @Override
-  public String toString() {
-    if (isInterface) {
-      return "interface " + getQualifiedSourceName();
-    } else {
-      return "class " + getQualifiedSourceName();
-    }
-  }
-
-  @Override
-  protected void acceptSubtype(JClassType me) {
-    allSubtypes = IdentitySets.add(allSubtypes, me);
-    notifySuperTypesOf(me);
-  }
-
-  @Override
-  protected void addConstructor(JConstructor ctor) {
-    members.addConstructor(ctor);
-  }
-
-  @Override
-  protected void addField(JField field) {
-    members.addField(field);
-  }
-
-  @Override
-  protected void addMethod(JMethod method) {
-    members.addMethod(method);
-  }
-
-  @Override
-  protected void addNestedType(JClassType type) {
-    members.addNestedType(type);
-  }
-
-  @Override
-  protected JClassType findNestedTypeImpl(String[] typeName, int index) {
-    return members.findNestedTypeImpl(typeName, index);
-  }
-
-  @Override
-  protected void getInheritableMethodsOnSuperclassesAndThisClass(
-      Map<String, JMethod> methodsBySignature) {
-    members.getInheritableMethodsOnSuperclassesAndThisClass(methodsBySignature);
-  }
-
-  /**
-   * Gets the methods declared in interfaces that this type extends. If this
-   * type is a class, its own methods are not added. If this type is an
-   * interface, its own methods are added. Used internally by
-   * {@link #getOverridableMethods()}.
-   * 
-   * @param methodsBySignature
-   */
-  @Override
-  protected void getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
-      Map<String, JMethod> methodsBySignature) {
-    members.getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
-  }
-
-  @Override
-  protected int getModifierBits() {
-    return modifierBits;
-  }
-
-  /**
-   * Tells this type's superclasses and superinterfaces about it.
-   */
-  @Override
-  protected void notifySuperTypesOf(JClassType me) {
-    // TODO(scottb): revisit
-    if (superclass != null) {
-      superclass.acceptSubtype(me);
-    }
-    for (int i = 0, n = interfaces.size(); i < n; ++i) {
-      JClassType intf = interfaces.get(i);
-      intf.acceptSubtype(me);
-    }
-  }
-
-  @Override
-  protected void removeSubtype(JClassType me) {
-    allSubtypes = IdentitySets.remove(allSubtypes, me);
-
-    if (superclass != null) {
-      superclass.removeSubtype(me);
-    }
-
-    for (int i = 0, n = interfaces.size(); i < n; ++i) {
-      JClassType intf = interfaces.get(i);
-
-      intf.removeSubtype(me);
-    }
-  }
-
-  void addAnnotations(
-      Map<Class<? extends Annotation>, Annotation> declaredAnnotations) {
-    annotations.addAnnotations(declaredAnnotations);
-  }
-
-  @Override
-  void addImplementedInterface(JClassType intf) {
-    assert (intf != null);
-    interfaces = Lists.add(interfaces, intf);
-  }
-
-  /**
-   * NOTE: This method is for testing purposes only.
-   */
-  @Override
-  Annotation[] getAnnotations() {
-    return annotations.getAnnotations();
-  }
-
-  /**
-   * NOTE: This method is for testing purposes only.
-   */
-  @Override
-  Annotation[] getDeclaredAnnotations() {
-    return annotations.getDeclaredAnnotations();
-  }
-
-  @Override
-  JRealClassType getSubstitutedType(JParameterizedType parameterizedType) {
-    return this;
-  }
-
-  @Override
-  void notifySuperTypes() {
-    notifySuperTypesOf(this);
-  }
-
-  /**
-   * Removes references to this instance from all of its super types.
-   */
-  @Override
-  void removeFromSupertypes() {
-    removeSubtype(this);
-  }
-
-  void setEnclosingType(JClassType enclosingType) {
-    assert this.enclosingType == null;
-    assert enclosingType != null;
-
-    this.enclosingType = enclosingType;
-
-    // Add myself to my enclosing type.
-    JRawType rawType = enclosingType.isRawType();
-    if (rawType != null) {
-      enclosingType = rawType.getGenericType();
-    }
-    enclosingType.addNestedType(this);
-  }
-
-  @Override
-  void setSuperclass(JClassType type) {
-    assert (type != null);
-    assert (isInterface() == null);
-    this.superclass = type;
-    JRealClassType realSuperType;
-    if (type.isParameterized() != null) {
-      realSuperType = type.isParameterized().getBaseType();
-    } else if (type.isRawType() != null) {
-      realSuperType = type.isRawType().getGenericType();
-    } else if (type instanceof JRealClassType) {
-      realSuperType = (JRealClassType) type;
-    } else {
-      throw new IllegalArgumentException("Unknown type for " + type);
-    }
-    annotations.setParent(realSuperType.annotations);
-  }
+public interface JRealClassType extends JClassType {
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JType.java
index dd92a7c..a5730d4 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Google Inc.
+ * 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
@@ -16,112 +16,61 @@
 package com.google.gwt.core.ext.typeinfo;
 
 /**
- * Abstract superclass for types.
+ * Super interface for types.
  */
-public abstract class JType {
+public interface JType {
 
-  JType() {
-  }
+  JType getErasedType();
 
-  /**
-   * All types use identity for comparison.
-   */
-  @Override
-  public final boolean equals(Object obj) {
-    return super.equals(obj);
-  }
+  String getJNISignature();
 
-  public abstract JType getErasedType();
+  JType getLeafType();
 
-  public abstract String getJNISignature();
-
-  public JType getLeafType() {
-    return this;
-  }
-
-  public String getParameterizedQualifiedSourceName() {
-    return getQualifiedSourceName();
-  }
+  String getParameterizedQualifiedSourceName();
 
   /**
    * A binary type name as specified by the 
    * <a href="http://java.sun.com/docs/books/jls/second_edition/html/binaryComp.doc.html">
    * Java Language Spec, Edition 2</a>.
    */
-  public abstract String getQualifiedBinaryName();
+  String getQualifiedBinaryName();
 
   /**
    * A type name as it would be specified in Java source.
    */
-  public abstract String getQualifiedSourceName();
+  String getQualifiedSourceName();
 
-  public abstract String getSimpleSourceName();
-
-  /**
-   * All types use identity for comparison.
-   */
-  @Override
-  public final int hashCode() {
-    return super.hashCode();
-  }
+  String getSimpleSourceName();
 
   /**
    * Returns this instance if it is a annotation or <code>null</code> if it is
    * not.
-   * 
-   * @return this instance if it is a annotation or <code>null</code> if it is
-   *         not
    */
-  public JAnnotationType isAnnotation() {
-    return null;
-  }
+  JAnnotationType isAnnotation();
 
-  public abstract JArrayType isArray();
+  JArrayType isArray();
 
-  public abstract JClassType isClass();
+  JClassType isClass();
 
-  public JClassType isClassOrInterface() {
-    JClassType type = isClass();
-    if (type != null) {
-      return type;
-    }
-    return isInterface();
-  }
+  JClassType isClassOrInterface();
 
   /**
    * Returns this instance if it is an enumeration or <code>null</code> if it is
    * not.
-   * 
-   * @return this instance if it is an enumeration or <code>null</code> if it is
-   *         not
    */
-  public abstract JEnumType isEnum();
+  JEnumType isEnum();
 
-  // TODO: Rename this to isGeneric
-  public abstract JGenericType isGenericType();
+  JGenericType isGenericType();
 
-  public abstract JClassType isInterface();
+  JClassType isInterface();
 
-  public abstract JParameterizedType isParameterized();
+  JParameterizedType isParameterized();
 
-  public abstract JPrimitiveType isPrimitive();
+  JPrimitiveType isPrimitive();
 
-  // TODO: Rename this to isRaw
-  public abstract JRawType isRawType();
+  JRawType isRawType();
 
-  public JTypeParameter isTypeParameter() {
-    return null;
-  }
+  JTypeParameter isTypeParameter();
 
-  public abstract JWildcardType isWildcard();
-
-  /**
-   * Returns either the substitution of this type based on the parameterized
-   * type or this instance.
-   * 
-   * @param parameterizedType
-   * @return either the substitution of this type based on the parameterized
-   *         type or this instance
-   */
-  abstract JType getSubstitutedType(JParameterizedType parameterizedType);
+  JWildcardType isWildcard();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java
index 1084c4f..a641e5b 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,192 +15,18 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.dev.util.StringInterner;
-
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Represents one of the type parameters in a generic type.
  */
-public class JTypeParameter extends JDelegatingClassType {
-  private JClassType[] bounds;
-  private JGenericType declaringClass;
-  private final int ordinal;
-  private final String typeName;
+public interface JTypeParameter extends JClassType {
 
-  public JTypeParameter(String typeName, int ordinal) {
-    this.typeName = StringInterner.get().intern(typeName);
-    this.ordinal = ordinal;
-  }
+  JClassType getBaseType();
 
-  @Override
-  public JField findField(String name) {
-    return getBaseType().findField(name);
-  }
+  JClassType[] getBounds();
 
-  @Override
-  public JMethod findMethod(String name, JType[] paramTypes) {
-    return getBaseType().findMethod(name, paramTypes);
-  }
+  JGenericType getDeclaringClass();
 
-  public JClassType[] getBounds() {
-    return bounds;
-  }
+  JClassType getFirstBound();
 
-  public JGenericType getDeclaringClass() {
-    return declaringClass;
-  }
-
-  @Override
-  public JClassType getEnclosingType() {
-    // Type parameters do not have an enclosing type.
-    return null;
-  }
-
-  @Override
-  public JField getField(String name) {
-    return getBaseType().getField(name);
-  }
-
-  @Override
-  public JField[] getFields() {
-    return getBaseType().getFields();
-  }
-
-  public JClassType getFirstBound() {
-    return getBaseType();
-  }
-
-  @Override
-  public JMethod getMethod(String name, JType[] paramTypes)
-      throws NotFoundException {
-    return getBaseType().getMethod(name, paramTypes);
-  }
-
-  @Override
-  public JMethod[] getMethods() {
-    return getBaseType().getMethods();
-  }
-
-  @Override
-  public String getName() {
-    return typeName;
-  }
-
-  public int getOrdinal() {
-    return ordinal;
-  }
-
-  @Override
-  public String getParameterizedQualifiedSourceName() {
-    return typeName;
-  }
-
-  @Override
-  public String getQualifiedBinaryName() {
-    // TODO(jat): !! does a binary name have meaning for a type parameter?
-    return toString(true);
-  }
-
-  @Override
-  public String getQualifiedSourceName() {
-    return toString(false);
-  }
-
-  @Override
-  public String getSimpleSourceName() {
-    return toString(true);
-  }
-
-  @Override
-  public JClassType[] getSubtypes() {
-    JClassType[] subtypes = super.getSubtypes();
-    List<JClassType> intersectionTypes = new ArrayList<JClassType>();
-
-    if (getFirstBound().isInterface() == null
-        && isAssignableFrom(getFirstBound())) {
-      // Include the first bound as a subtype if it is not an interface and it
-      // is assignable to all of our bounds.
-      intersectionTypes.add(getFirstBound());
-    }
-
-    for (JClassType subtype : subtypes) {
-      if (isAssignableFrom(subtype)) {
-        intersectionTypes.add(subtype);
-      }
-    }
-
-    // Only types that intersect with all our bounds make it here.
-    return intersectionTypes.toArray(TypeOracle.NO_JCLASSES);
-  }
-
-  @Override
-  public JGenericType isGenericType() {
-    return null;
-  }
-
-  @Override
-  public JParameterizedType isParameterized() {
-    return null;
-  }
-
-  @Override
-  public JRawType isRawType() {
-    return null;
-  }
-
-  @Override
-  public JTypeParameter isTypeParameter() {
-    return this;
-  }
-
-  @Override
-  public JWildcardType isWildcard() {
-    return null;
-  }
-
-  public void setBounds(JClassType[] bounds) {
-    this.bounds = bounds;
-    super.setBaseType(bounds[0]);
-  }
-
-  @Override
-  public String toString() {
-    if (getBaseType().isInterface() != null) {
-      return "interface " + getQualifiedSourceName();
-    } else {
-      return "class " + getQualifiedSourceName();
-    }
-  }
-
-  @Override
-  JClassType getSubstitutedType(JParameterizedType parameterizedType) {
-    return parameterizedType.getTypeParameterSubstitution(this);
-  }
-
-  void setDeclaringClass(JGenericType declaringClass) {
-    this.declaringClass = declaringClass;
-  }
-
-  private String toString(boolean simpleName) {
-    StringBuffer sb = new StringBuffer();
-    sb.append(typeName);
-    sb.append(" extends ");
-    for (int i = 0; i < bounds.length; ++i) {
-      if (i != 0) {
-        sb.append(" & ");
-      }
-
-      String boundName;
-      if (simpleName) {
-        boundName = bounds[i].getSimpleSourceName();
-      } else {
-        boundName = bounds[i].getParameterizedQualifiedSourceName();
-      }
-      sb.append(boundName);
-    }
-
-    return sb.toString();
-  }
+  int getOrdinal();
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java
index 7ab322c..8d0bbe1 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java
@@ -18,7 +18,7 @@
 /**
  * Represents a wildcard type argument to a parameterized type.
  */
-public class JWildcardType extends JDelegatingClassType {
+public interface JWildcardType extends JClassType {
   /**
    * Type of wildcard bound.
    */
@@ -39,47 +39,11 @@
     UNBOUND
   }
 
-  private final BoundType boundType;
-  private JClassType[] lazyLowerBounds;
-  private JClassType[] lazyUpperBounds;
+  JClassType getBaseType();
 
-  JWildcardType(BoundType boundType, JClassType typeBound) {
-    this.boundType = boundType;
-    super.setBaseType(typeBound);
-  }
+  BoundType getBoundType();
 
-  @Override
-  public JField findField(String name) {
-    return getBaseType().findField(name);
-  }
-
-  @Override
-  public JMethod findMethod(String name, JType[] paramTypes) {
-    return getBaseType().findMethod(name, paramTypes);
-  }
-
-  public BoundType getBoundType() {
-    return boundType;
-  }
-
-  @Override
-  public JClassType getErasedType() {
-    return getUpperBound().getErasedType();
-  }
-
-  @Override
-  public JField getField(String name) {
-    return getBaseType().getField(name);
-  }
-
-  @Override
-  public JField[] getFields() {
-    return getBaseType().getFields();
-  }
-
-  public JClassType getFirstBound() {
-    return getBaseType();
-  }
+  JClassType getFirstBound();
 
   /**
    * Returns the lower bounds of this wildcard type. If no lower bounds were
@@ -87,75 +51,9 @@
    * 
    * @return the lower bounds of this wildcard type
    */
-  public JClassType[] getLowerBounds() {
-    if (lazyLowerBounds == null) {
-      if (isUpperBound()) {
-        lazyLowerBounds = TypeOracle.NO_JCLASSES;
-      } else {
-        lazyLowerBounds = new JClassType[]{getFirstBound()};
-      }
-    }
-    return lazyLowerBounds;
-  }
+  JClassType[] getLowerBounds();
 
-  @Override
-  public JMethod getMethod(String name, JType[] paramTypes)
-      throws NotFoundException {
-    return getBaseType().getMethod(name, paramTypes);
-  }
-
-  @Override
-  public JMethod[] getMethods() {
-    return getBaseType().getMethods();
-  }
-
-  @Override
-  public String getQualifiedBinaryName() {
-    // TODO(jat): !! does a binary name have meaning for a wildcard?
-    return toString(true);
-  }
-
-  @Override
-  public String getQualifiedSourceName() {
-    return toString(false);
-  }
-
-  @Override
-  public String getSimpleSourceName() {
-    return toString(true);
-  }
-
-  @Override
-  public JClassType[] getSubtypes() {
-    if (isUpperBound()) {
-      return getFirstBound().getSubtypes();
-    }
-
-    // We are not sure what the correct behavior should be for lower bound
-    // wildcards. ? super Number contains ? super T for all T extends Number,
-    // but it also includes T for Number extends T. For example, Object is a
-    // subtype.
-    return TypeOracle.NO_JCLASSES;
-  }
-
-  @Override
-  public JClassType getSuperclass() {
-    if (isUpperBound()) {
-      // The superclass of an upper bound is the upper bound.
-      return getFirstBound();
-    }
-
-    // The only safe superclass for a ? super T is Object.
-    return getOracle().getJavaLangObject();
-  }
-
-  public JClassType getUpperBound() {
-    if (isUpperBound()) {
-      return getFirstBound();
-    }
-
-    return getOracle().getJavaLangObject();
-  }
+  JClassType getUpperBound();
 
   /**
    * Returns the upper bounds of this wildcard type. If no upper bounds were
@@ -163,77 +61,6 @@
    * 
    * @return the upper bounds of this wildcard type
    */
-  public JClassType[] getUpperBounds() {
-    if (lazyUpperBounds == null) {
-      if (isUpperBound()) {
-        lazyUpperBounds = new JClassType[]{getFirstBound()};
-      } else {
-        // Object is the default upper bound.
-        lazyUpperBounds = new JClassType[]{getOracle().getJavaLangObject()};
-      }
-    }
 
-    return lazyUpperBounds;
-  }
-
-  @Override
-  public JGenericType isGenericType() {
-    return null;
-  }
-
-  @Override
-  public JParameterizedType isParameterized() {
-    return null;
-  }
-
-  @Override
-  public JRawType isRawType() {
-    return null;
-  }
-
-  @Override
-  public JWildcardType isWildcard() {
-    return this;
-  }
-
-  /**
-   * Returns <code>true</code> if this instance has the same bounds that are
-   * requested.
-   * 
-   * @param otherWildcard
-   * @return <code>true</code> if this instance has the same bounds that are
-   *         requested
-   */
-  boolean boundsMatch(JWildcardType otherWildcard) {
-    return isUpperBound() == otherWildcard.isUpperBound()
-        && getFirstBound() == otherWildcard.getFirstBound();
-  }
-
-  @Override
-  JClassType getSubstitutedType(JParameterizedType parameterizedType) {
-    return getOracle().getWildcardType(boundType,
-        getFirstBound().getSubstitutedType(parameterizedType));
-  }
-
-  private boolean isUnbound() {
-    return boundType == BoundType.UNBOUND;
-  }
-
-  private boolean isUpperBound() {
-    return boundType != BoundType.SUPER;
-  }
-
-  private String toString(boolean simpleName) {
-    String str = "?";
-    if (isUnbound()) {
-      return str;
-    } else {
-      str += (isUpperBound() ? " extends " : " super ");
-      if (simpleName) {
-        return str + getFirstBound().getSimpleSourceName();
-      } else {
-        return str + getFirstBound().getParameterizedQualifiedSourceName();
-      }
-    }
-  }
+  JClassType[] getUpperBounds();
 }
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 0957493..c7a4358 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
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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
@@ -15,28 +15,8 @@
  */
 package com.google.gwt.core.ext.typeinfo;
 
-import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
-import com.google.gwt.dev.javac.JavaSourceParser;
-import com.google.gwt.dev.jjs.InternalCompilerException;
-import com.google.gwt.dev.resource.Resource;
-import com.google.gwt.dev.util.Name;
-import com.google.gwt.dev.util.collect.HashMap;
-import com.google.gwt.dev.util.collect.IdentityHashMap;
-
-import org.apache.commons.collections.map.AbstractReferenceMap;
-import org.apache.commons.collections.map.ReferenceIdentityMap;
-import org.apache.commons.collections.map.ReferenceMap;
-
-import java.lang.annotation.Annotation;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.Comparator;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -61,62 +41,7 @@
  * 
  * </p>
  */
-public class TypeOracle {
-
-  private static class ParameterizedTypeKey {
-    private final JClassType enclosingType;
-    private final JGenericType genericType;
-    private final JClassType[] typeArgs;
-
-    public ParameterizedTypeKey(JGenericType genericType,
-        JClassType enclosingType, JClassType[] typeArgs) {
-      this.genericType = genericType;
-      this.enclosingType = enclosingType;
-      this.typeArgs = typeArgs;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (!(obj instanceof ParameterizedTypeKey)) {
-        return false;
-      }
-      ParameterizedTypeKey other = (ParameterizedTypeKey) obj;
-      return genericType == other.genericType
-          && enclosingType == other.enclosingType
-          && Arrays.equals(typeArgs, other.typeArgs);
-    }
-
-    @Override
-    public int hashCode() {
-      return 29 * genericType.hashCode() + 17
-          * ((enclosingType == null) ? 0 : enclosingType.hashCode())
-          + Arrays.hashCode(typeArgs);
-    }
-  }
-
-  private static class WildCardKey {
-    private final BoundType boundType;
-    private final JClassType typeBound;
-
-    public WildCardKey(BoundType boundType, JClassType typeBound) {
-      this.boundType = boundType;
-      this.typeBound = typeBound;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (!(obj instanceof WildCardKey)) {
-        return false;
-      }
-      WildCardKey other = (WildCardKey) obj;
-      return boundType == other.boundType && typeBound == other.typeBound;
-    }
-
-    @Override
-    public int hashCode() {
-      return 29 * typeBound.hashCode() + boundType.hashCode();
-    }
-  }
+public abstract class TypeOracle {
 
   /**
    * A reserved metadata tag to indicates that a field type, method return type
@@ -128,29 +53,6 @@
   @Deprecated
   public static final String TAG_TYPEARGS = "gwt.typeArgs";
 
-  static final int MOD_ABSTRACT = 0x00000001;
-  static final int MOD_FINAL = 0x00000002;
-  static final int MOD_NATIVE = 0x00000004;
-  static final int MOD_PRIVATE = 0x00000008;
-  static final int MOD_PROTECTED = 0x00000010;
-  static final int MOD_PUBLIC = 0x00000020;
-  static final int MOD_STATIC = 0x00000040;
-  static final int MOD_TRANSIENT = 0x00000080;
-  static final int MOD_VOLATILE = 0x00000100;
-
-  static final Annotation[] NO_ANNOTATIONS = new Annotation[0];
-  static final JClassType[] NO_JCLASSES = new JClassType[0];
-  static final JConstructor[] NO_JCTORS = new JConstructor[0];
-  static final JField[] NO_JFIELDS = new JField[0];
-  static final JMethod[] NO_JMETHODS = new JMethod[0];
-  static final JPackage[] NO_JPACKAGES = new JPackage[0];
-  static final JParameter[] NO_JPARAMS = new JParameter[0];
-  static final JType[] NO_JTYPES = new JType[0];
-  static final String[][] NO_STRING_ARR_ARR = new String[0][];
-  static final String[] NO_STRINGS = new String[0];
-
-  private static final String JSO_CLASS = "com.google.gwt.core.client.JavaScriptObject";
-
   /**
    * Convenience method to sort class types in a consistent way. Note that the
    * order is subject to change and is intended to generate an "aesthetically
@@ -210,102 +112,13 @@
     });
   }
 
-  static String[] modifierBitsToNames(int bits) {
-    List<String> strings = new ArrayList<String>();
-
-    // The order is based on the order in which we want them to appear.
-    //
-    if (0 != (bits & MOD_PUBLIC)) {
-      strings.add("public");
-    }
-
-    if (0 != (bits & MOD_PRIVATE)) {
-      strings.add("private");
-    }
-
-    if (0 != (bits & MOD_PROTECTED)) {
-      strings.add("protected");
-    }
-
-    if (0 != (bits & MOD_STATIC)) {
-      strings.add("static");
-    }
-
-    if (0 != (bits & MOD_ABSTRACT)) {
-      strings.add("abstract");
-    }
-
-    if (0 != (bits & MOD_FINAL)) {
-      strings.add("final");
-    }
-
-    if (0 != (bits & MOD_NATIVE)) {
-      strings.add("native");
-    }
-
-    if (0 != (bits & MOD_TRANSIENT)) {
-      strings.add("transient");
-    }
-
-    if (0 != (bits & MOD_VOLATILE)) {
-      strings.add("volatile");
-    }
-
-    return strings.toArray(NO_STRINGS);
-  }
-
-  /**
-   * A map of fully-qualify source names (ie, use "." rather than "$" for nested
-   * classes) to JRealClassTypes.
-   */
-  private final Map<String, JRealClassType> allTypes = new HashMap<String, JRealClassType>();
-
-  @SuppressWarnings("unchecked")
-  private final Map<JType, JArrayType> arrayTypes = new ReferenceIdentityMap(
-      AbstractReferenceMap.WEAK, AbstractReferenceMap.WEAK, true);
-
-  private JClassType javaLangObject;
-
-  private final JavaSourceParser javaSourceParser = new JavaSourceParser();
-
-  /**
-   * Maps SingleJsoImpl interfaces to the implementing JSO subtype.
-   */
-  private final Map<JClassType, JClassType> jsoSingleImpls = new IdentityHashMap<JClassType, JClassType>();
-
-  private final Map<String, JPackage> packages = new HashMap<String, JPackage>();
-
-  @SuppressWarnings("unchecked")
-  private final Map<ParameterizedTypeKey, JParameterizedType> parameterizedTypes = new ReferenceMap(
-      AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK, true);
-
-  /**
-   * A list of recently-added types that will be fully initialized on the next
-   * call to {@link #finish}.
-   */
-  private final List<JRealClassType> recentTypes = new ArrayList<JRealClassType>();
-
-  private JWildcardType unboundWildCardType;
-
-  @SuppressWarnings("unchecked")
-  private final Map<WildCardKey, JWildcardType> wildcardTypes = new ReferenceMap(
-      AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK, true);
-
-  public TypeOracle() {
-    // Always create the default package.
-    //
-    getOrCreatePackage("");
-  }
-
   /**
    * Attempts to find a package by name. All requests for the same package
    * return the same package object.
    * 
    * @return <code>null</code> if the package could not be found
    */
-  public JPackage findPackage(String pkgName) {
-    return packages.get(pkgName);
-  }
+  public abstract JPackage findPackage(String pkgName);
 
   /**
    * Finds a class or interface given its fully-qualified name.
@@ -316,10 +129,7 @@
    * 
    * @return <code>null</code> if the type is not found
    */
-  public JClassType findType(String name) {
-    assert Name.isSourceName(name);
-    return allTypes.get(name);
-  }
+  public abstract JClassType findType(String name);
 
   /**
    * Finds a type given its package-relative name. For nested classes, use its
@@ -328,17 +138,7 @@
    * 
    * @return <code>null</code> if the type is not found
    */
-  public JClassType findType(String pkgName, String typeName) {
-    assert Name.isSourceName(typeName);
-    JPackage pkg = findPackage(pkgName);
-    if (pkg != null) {
-      JClassType type = pkg.findType(typeName);
-      if (type != null) {
-        return type;
-      }
-    }
-    return null;
-  }
+  public abstract JClassType findType(String pkgName, String typeName);
 
   /**
    * Gets the type object that represents an array of the specified type. The
@@ -349,46 +149,19 @@
    *          an array type
    * @return a type object representing an array of the component type
    */
-  public JArrayType getArrayType(JType componentType) {
-    JArrayType arrayType = arrayTypes.get(componentType);
-    if (arrayType == null) {
-      arrayType = new JArrayType(componentType, this);
-      arrayTypes.put(componentType, arrayType);
-    }
-    return arrayType;
-  }
+  public abstract JArrayType getArrayType(JType componentType);
 
   /**
    * Gets a reference to the type object representing
    * <code>java.lang.Object</code>.
    */
-  public JClassType getJavaLangObject() {
-    if (javaLangObject == null) {
-      javaLangObject = findType("java.lang.Object");
-      assert javaLangObject != null;
-    }
-    return javaLangObject;
-  }
+  public abstract JClassType getJavaLangObject();
 
   /**
    * Ensure that a package with the specified name exists as well as its parent
    * packages.
    */
-  public JPackage getOrCreatePackage(String name) {
-    int i = name.lastIndexOf('.');
-    if (i != -1) {
-      // Ensure the parent package is also created.
-      //
-      getOrCreatePackage(name.substring(0, i));
-    }
-
-    JPackage pkg = packages.get(name);
-    if (pkg == null) {
-      pkg = new JPackage(name);
-      packages.put(name, pkg);
-    }
-    return pkg;
-  }
+  public abstract JPackage getOrCreatePackage(String name);
 
   /**
    * Gets a package by name. All requests for the same package return the same
@@ -396,22 +169,14 @@
    * 
    * @return the package object associated with the specified name
    */
-  public JPackage getPackage(String pkgName) throws NotFoundException {
-    JPackage result = findPackage(pkgName);
-    if (result == null) {
-      throw new NotFoundException(pkgName);
-    }
-    return result;
-  }
+  public abstract JPackage getPackage(String pkgName) throws NotFoundException;
 
   /**
    * Gets an array of all packages known to this type oracle.
    * 
    * @return an array of packages, possibly of zero-length
    */
-  public JPackage[] getPackages() {
-    return packages.values().toArray(NO_JPACKAGES);
-  }
+  public abstract JPackage[] getPackages();
 
   /**
    * Gets the parameterized type object that represents the combination of a
@@ -429,51 +194,8 @@
    *           arguments were specified to parameterize the generic type
    * @throws NullPointerException if genericType is <code>null</code>
    */
-  public JParameterizedType getParameterizedType(JGenericType genericType,
-      JClassType enclosingType, JClassType[] typeArgs) {
-    ParameterizedTypeKey key = new ParameterizedTypeKey(genericType,
-        enclosingType, typeArgs);
-    JParameterizedType result = parameterizedTypes.get(key);
-    if (result != null) {
-      return result;
-    }
-
-    if (genericType.isMemberType() && !genericType.isStatic()) {
-      if (genericType.getEnclosingType().isGenericType() != null
-          && enclosingType.isParameterized() == null
-          && enclosingType.isRawType() == null) {
-        /*
-         * If the generic type is a non-static member type enclosed by a generic
-         * type then the enclosing type for this parameterized type should be
-         * raw or parameterized.
-         */
-        throw new IllegalArgumentException("Generic type '"
-            + genericType.getParameterizedQualifiedSourceName()
-            + "' is a non-static member type, but the enclosing type '"
-            + enclosingType.getQualifiedSourceName()
-            + "' is not a parameterized or raw type");
-      }
-    }
-
-    JTypeParameter[] typeParameters = genericType.getTypeParameters();
-    if (typeArgs.length < typeParameters.length) {
-      throw new IllegalArgumentException(
-          "Not enough type arguments were specified to parameterize '"
-              + genericType.getParameterizedQualifiedSourceName() + "'");
-    } else {
-      /*
-       * TODO: Should WARN if we specify too many type arguments but we have no
-       * logger.
-       */
-    }
-
-    // TODO: validate that the type arguments satisfy the generic type parameter
-    // bounds if any were specified
-
-    result = new JParameterizedType(genericType, enclosingType, typeArgs);
-    parameterizedTypes.put(key, result);
-    return result;
-  }
+  public abstract JParameterizedType getParameterizedType(
+      JGenericType genericType, JClassType enclosingType, JClassType[] typeArgs);
 
   /**
    * Gets the parameterized type object that represents the combination of a
@@ -490,10 +212,8 @@
    *           the generic type
    * @throws NullPointerException if genericType is <code>null</code>
    */
-  public JParameterizedType getParameterizedType(JGenericType genericType,
-      JClassType[] typeArgs) {
-    return getParameterizedType(genericType, null, typeArgs);
-  }
+  public abstract JParameterizedType getParameterizedType(
+      JGenericType genericType, JClassType[] typeArgs);
 
   /**
    * @deprecated This method will always return 0 because a TypeOracle never
@@ -501,27 +221,20 @@
    *             manage static state.
    */
   @Deprecated
-  public long getReloadCount() {
-    return 0;
-  }
+  public abstract long getReloadCount();
 
   /**
    * Returns the single implementation type for an interface returned via
    * {@link #getSingleJsoImplInterfaces()} or <code>null</code> if no JSO
    * implementation is defined.
    */
-  public JClassType getSingleJsoImpl(JClassType intf) {
-    assert intf.isInterface() == intf;
-    return jsoSingleImpls.get(intf);
-  }
+  public abstract JClassType getSingleJsoImpl(JClassType intf);
 
   /**
    * Returns an unmodifiable, live view of all interface types that are
    * implemented by exactly one JSO subtype.
    */
-  public Set<JClassType> getSingleJsoImplInterfaces() {
-    return Collections.unmodifiableSet(jsoSingleImpls.keySet());
-  }
+  public abstract Set<? extends JClassType> getSingleJsoImplInterfaces();
 
   /**
    * Finds a type given its fully qualified name. For nested classes, use its
@@ -530,14 +243,7 @@
    * 
    * @return the specified type
    */
-  public JClassType getType(String name) throws NotFoundException {
-    assert Name.isSourceName(name);
-    JClassType type = findType(name);
-    if (type == null) {
-      throw new NotFoundException(name);
-    }
-    return type;
-  }
+  public abstract JClassType getType(String name) throws NotFoundException;
 
   /**
    * Finds a type given its package-relative name. For nested classes, use its
@@ -546,55 +252,18 @@
    * 
    * @return the specified type
    */
-  public JClassType getType(String pkgName, String topLevelTypeSimpleName)
-      throws NotFoundException {
-    assert Name.isSourceName(topLevelTypeSimpleName);
-    JClassType type = findType(pkgName, topLevelTypeSimpleName);
-    if (type == null) {
-      throw new NotFoundException(pkgName + "." + topLevelTypeSimpleName);
-    }
-    return type;
-  }
+  public abstract JClassType getType(String pkgName,
+      String topLevelTypeSimpleName) throws NotFoundException;
 
   /**
    * Gets all types, both top-level and nested.
    * 
    * @return an array of types, possibly of zero length
    */
-  public JClassType[] getTypes() {
-    Collection<JRealClassType> values = allTypes.values();
-    JClassType[] result = values.toArray(new JClassType[values.size()]);
-    Arrays.sort(result, new Comparator<JClassType>() {
-      public int compare(JClassType o1, JClassType o2) {
-        return o1.getQualifiedSourceName().compareTo(
-            o2.getQualifiedSourceName());
-      }
-    });
-    return result;
-  }
+  public abstract JClassType[] getTypes();
 
-  public JWildcardType getWildcardType(JWildcardType.BoundType boundType,
-      JClassType typeBound) {
-    // Special fast case for <? extends Object>
-    // TODO(amitmanjhi): make sure this actually does speed things up!
-    if (typeBound == getJavaLangObject() && boundType == BoundType.UNBOUND) {
-      if (unboundWildCardType == null) {
-        unboundWildCardType = new JWildcardType(boundType, typeBound);
-      }
-      return unboundWildCardType;
-    }
-    // End special case / todo.
-
-    WildCardKey key = new WildCardKey(boundType, typeBound);
-    JWildcardType result = wildcardTypes.get(key);
-    if (result != null) {
-      return result;
-    }
-
-    result = new JWildcardType(boundType, typeBound);
-    wildcardTypes.put(key, result);
-    return result;
-  }
+  public abstract JWildcardType getWildcardType(
+      JWildcardType.BoundType boundType, JClassType typeBound);
 
   /**
    * Parses the string form of a type to produce the corresponding type object.
@@ -617,316 +286,6 @@
    * @param type a type signature to be parsed
    * @return the type object corresponding to the parse type
    */
-  public JType parse(String type) throws TypeOracleException {
-    // Remove all internal and external whitespace.
-    //
-    type = type.replaceAll("\\\\s", "");
 
-    // Recursively parse.
-    //
-    return parseImpl(type);
-  }
-
-  void addNewType(JRealClassType newType) {
-    String fqcn = newType.getQualifiedSourceName();
-    allTypes.put(fqcn, newType);
-    recentTypes.add(newType);
-  }
-
-  /**
-   * Called to add a source reference for a top-level class type.
-   */
-  void addSourceReference(JRealClassType type, Resource sourceFile) {
-    javaSourceParser.addSourceForType(type, sourceFile);
-  }
-
-  /**
-   * Called after a block of new types are added.
-   */
-  void finish() {
-    JClassType[] newTypes = recentTypes.toArray(new JClassType[recentTypes.size()]);
-    computeHierarchyRelationships(newTypes);
-    computeSingleJsoImplData(newTypes);
-    recentTypes.clear();
-  }
-
-  JavaSourceParser getJavaSourceParser() {
-    return javaSourceParser;
-  }
-
-  private List<JClassType> classChain(JClassType cls) {
-    LinkedList<JClassType> chain = new LinkedList<JClassType>();
-    while (cls != null) {
-      chain.addFirst(cls);
-      cls = cls.getSuperclass();
-    }
-    return chain;
-  }
-
-  /**
-   * Determines whether the given class fully implements an interface (either
-   * directly or via inherited methods).
-   */
-  private boolean classFullyImplements(JClassType cls, JClassType intf) {
-    // The class must at least nominally implement the interface.
-    if (!intf.isAssignableFrom(cls)) {
-      return false;
-    }
-
-    // Check to see whether it implements all the interfaces methods.
-    for (JMethod meth : intf.getInheritableMethods()) {
-      if (!classImplementsMethod(cls, meth)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  private boolean classImplementsMethod(JClassType cls, JMethod meth) {
-    while (cls != null) {
-      JMethod found = cls.findMethod(meth.getName(), meth.getParameterTypes());
-      if ((found != null) && !found.isAbstract()) {
-        return true;
-      }
-      cls = cls.getSuperclass();
-    }
-    return false;
-  }
-
-  private void computeHierarchyRelationships(JClassType[] types) {
-    // For each type, walk up its hierarchy chain and tell each supertype
-    // about its subtype.
-    for (JClassType type : types) {
-      type.notifySuperTypes();
-    }
-  }
-
-  /**
-   * Updates the list of jsoSingleImpl types from recently-added types.
-   */
-  private void computeSingleJsoImplData(JClassType... newTypes) {
-    JClassType jsoType = findType(JSO_CLASS);
-    if (jsoType == null) {
-      return;
-    }
-
-    for (JClassType type : newTypes) {
-      if (!jsoType.isAssignableFrom(type)) {
-        continue;
-      }
-
-      for (JClassType intf : JClassType.getFlattenedSuperTypeHierarchy(type)) {
-        // If intf refers to a JParameterizedType, we need to use its generic
-        // base type instead.
-        if (intf instanceof JParameterizedType) {
-          intf = ((JParameterizedType)intf).getBaseType();
-        }
-        
-        if (intf.isInterface() == null) {
-          // Not an interface
-          continue;
-        }
-
-        if (intf.getOverridableMethods().length == 0) {
-          /*
-           * Record a tag interface as being implemented by JSO, since they
-           * don't actually have any methods and we want to avoid spurious
-           * messages about multiple JSO types implementing a common interface.
-           */
-          jsoSingleImpls.put(intf, jsoType);
-          continue;
-        }
-
-        /*
-         * If the previously-registered implementation type for a SingleJsoImpl
-         * interface is a subtype of the type we're currently looking at, we
-         * want to choose the least-derived class.
-         */
-        JClassType previousType = jsoSingleImpls.get(intf);
-        if (previousType == null) {
-          jsoSingleImpls.put(intf, type);
-        } else if (type.isAssignableFrom(previousType)) {
-          jsoSingleImpls.put(intf, type);
-        } else if (type.isAssignableTo(previousType)) {
-          // Do nothing
-        } else {
-          // Special case: If two JSOs implement the same interface, but they
-          // share a common base class that fully implements that interface,
-          // then choose that base class.
-          JClassType impl = findFullyImplementingBase(intf, type, previousType);
-          if (impl != null) {
-            jsoSingleImpls.put(intf, impl);
-          } else {
-            throw new InternalCompilerException(
-                "Already seen an implementing JSO subtype ("
-                    + previousType.getName() + ") for interface ("
-                    + intf.getName() + ") while examining newly-added type ("
-                    + type.getName() + "). This is a bug in "
-                    + "JSORestrictionsChecker.");
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Determines whether both classes A and B share a common superclass which
-   * fully implements the given interface.
-   */
-  private JClassType findFullyImplementingBase(JClassType intf, JClassType a,
-      JClassType b) {
-    JClassType common = findNearestCommonBase(a, b);
-    if (classFullyImplements(common, intf)) {
-      return common;
-    }
-    return null;
-  }
-
-  /**
-   * Finds the nearest common base class of the given classes.
-   */
-  private JClassType findNearestCommonBase(JClassType a, JClassType b) {
-    List<JClassType> as = classChain(a);
-    List<JClassType> bs = classChain(b);
-
-    JClassType match = null;
-    Iterator<JClassType> ait = as.iterator();
-    Iterator<JClassType> bit = bs.iterator();
-    while (ait.hasNext() && bit.hasNext()) {
-      a = ait.next();
-      b = bit.next();
-      if (a.equals(b)) {
-        match = a;
-      } else {
-        break;
-      }
-    }
-    return match;
-  }
-
-  private JType parseImpl(String type) throws NotFoundException,
-      ParseException, BadTypeArgsException {
-    if (type.endsWith("[]")) {
-      String remainder = type.substring(0, type.length() - 2);
-      JType componentType = parseImpl(remainder);
-      return getArrayType(componentType);
-    }
-
-    if (type.endsWith(">")) {
-      int bracket = type.indexOf('<');
-      if (bracket == -1) {
-        throw new ParseException(
-            "Mismatched brackets; expected '<' to match subsequent '>'");
-      }
-
-      // Resolve the raw type.
-      //
-      String rawTypeName = type.substring(0, bracket);
-      JType rawType = parseImpl(rawTypeName);
-      if (rawType.isParameterized() != null) {
-        // The raw type cannot itself be parameterized.
-        //
-        throw new BadTypeArgsException(
-            "Only non-parameterized classes and interface can be parameterized");
-      } else if (rawType.isClassOrInterface() == null) {
-        // The raw type must be a class or interface
-        // (not an array or primitive).
-        //
-        throw new BadTypeArgsException(
-            "Only classes and interface can be parameterized, so "
-                + rawType.getQualifiedSourceName()
-                + " cannot be used in this context");
-      } else if (rawType.isGenericType() == null) {
-        throw new BadTypeArgsException(
-            "'"
-                + rawType.getQualifiedSourceName()
-                + "' is not a generic type; only generic types can be parameterized");
-      }
-
-      // Resolve each type argument.
-      //
-      String typeArgContents = type.substring(bracket + 1, type.length() - 1);
-      JClassType[] typeArgs = parseTypeArgContents(typeArgContents);
-
-      // Intern this type.
-      //
-      return getParameterizedType(rawType.isGenericType(), typeArgs);
-    }
-
-    JType result = JPrimitiveType.valueOf(type);
-    if (result != null) {
-      return result;
-    }
-
-    result = findType(type);
-    if (result != null) {
-      return result;
-    }
-
-    throw new NotFoundException("Unable to recognize '" + type
-        + "' as a type name (is it fully qualified?)");
-  }
-
-  private void parseTypeArgComponent(List<JClassType> typeArgList,
-      String typeArgComponent) throws NotFoundException, ParseException,
-      BadTypeArgsException {
-    JType typeArg = parseImpl(typeArgComponent);
-    if (typeArg.isPrimitive() != null) {
-      // Cannot be primitive.
-      //
-      throw new BadTypeArgsException(
-          "Type arguments cannot be primitives, so '"
-              + typeArg.getQualifiedSourceName()
-              + "' cannot be used in this context");
-    }
-
-    typeArgList.add((JClassType) typeArg);
-  }
-
-  /**
-   * Returns an array of types specified inside of a gwt.typeArgs javadoc
-   * annotation.
-   */
-  private JClassType[] parseTypeArgContents(String typeArgContents)
-      throws ParseException, NotFoundException, BadTypeArgsException {
-    List<JClassType> typeArgList = new ArrayList<JClassType>();
-
-    int start = 0;
-    for (int offset = 0, length = typeArgContents.length(); offset < length; ++offset) {
-      char ch = typeArgContents.charAt(offset);
-      switch (ch) {
-        case '<':
-          // scan for closing '>' while ignoring commas
-          for (int depth = 1; depth > 0;) {
-            if (++offset == length) {
-              throw new ParseException(
-                  "Mismatched brackets; expected '<' to match subsequent '>'");
-            }
-
-            char ich = typeArgContents.charAt(offset);
-            if (ich == '<') {
-              ++depth;
-            } else if (ich == '>') {
-              --depth;
-            }
-          }
-          break;
-        case '>':
-          throw new ParseException("No matching '<' for '>'");
-        case ',':
-          String typeArgComponent = typeArgContents.substring(start, offset);
-          parseTypeArgComponent(typeArgList, typeArgComponent);
-          start = offset + 1;
-          break;
-        default:
-          break;
-      }
-    }
-
-    String typeArgComponent = typeArgContents.substring(start);
-    parseTypeArgComponent(typeArgList, typeArgComponent);
-
-    JClassType[] typeArgs = typeArgList.toArray(new JClassType[typeArgList.size()]);
-    return typeArgs;
-  }
+  public abstract JType parse(String type) throws TypeOracleException;
 }
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationState.java b/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
index dce925e..23d5392 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
@@ -16,8 +16,8 @@
 package com.google.gwt.dev.javac;
 
 import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.dev.javac.CompilationStateBuilder.CompileMoreLater;
+import com.google.gwt.dev.javac.typemodel.TypeOracle;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
diff --git a/dev/core/src/com/google/gwt/dev/javac/JavaSourceParser.java b/dev/core/src/com/google/gwt/dev/javac/JavaSourceParser.java
index 6eb45de..3e45891 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JavaSourceParser.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JavaSourceParser.java
@@ -15,10 +15,10 @@
  */
 package com.google.gwt.dev.javac;
 
-import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JParameter;
 import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.dev.javac.typemodel.JAbstractMethod;
+import com.google.gwt.dev.javac.typemodel.JClassType;
+import com.google.gwt.dev.javac.typemodel.JParameter;
 import com.google.gwt.dev.resource.Resource;
 import com.google.gwt.dev.util.Util;
 import com.google.gwt.dev.util.Name.BinaryName;
diff --git a/dev/core/src/com/google/gwt/dev/javac/Resolver.java b/dev/core/src/com/google/gwt/dev/javac/Resolver.java
index c1ebe77..e1dec40 100644
--- a/dev/core/src/com/google/gwt/dev/javac/Resolver.java
+++ b/dev/core/src/com/google/gwt/dev/javac/Resolver.java
@@ -16,15 +16,15 @@
 package com.google.gwt.dev.javac;
 
 import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JMethod;
-import com.google.gwt.core.ext.typeinfo.JPackage;
-import com.google.gwt.core.ext.typeinfo.JRealClassType;
 import com.google.gwt.core.ext.typeinfo.JType;
-import com.google.gwt.core.ext.typeinfo.JTypeParameter;
-import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.dev.javac.asm.CollectAnnotationData;
+import com.google.gwt.dev.javac.typemodel.JAbstractMethod;
+import com.google.gwt.dev.javac.typemodel.JClassType;
+import com.google.gwt.dev.javac.typemodel.JMethod;
+import com.google.gwt.dev.javac.typemodel.JPackage;
+import com.google.gwt.dev.javac.typemodel.JRealClassType;
+import com.google.gwt.dev.javac.typemodel.JTypeParameter;
+import com.google.gwt.dev.javac.typemodel.TypeOracle;
 
 import java.lang.annotation.Annotation;
 import java.util.List;
@@ -37,7 +37,7 @@
 
   void addImplementedInterface(JRealClassType type, JClassType intf);
 
-  void addThrows(JAbstractMethod method, JType exception);
+  void addThrows(JAbstractMethod method, JClassType exception);
 
   Map<String, JRealClassType> getBinaryMapper();
 
diff --git a/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java b/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
index 68ebdd7..611f12b 100644
--- a/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
+++ b/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
@@ -16,22 +16,8 @@
 package com.google.gwt.dev.javac;
 
 import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
-import com.google.gwt.core.ext.typeinfo.JArrayType;
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JField;
-import com.google.gwt.core.ext.typeinfo.JGenericType;
-import com.google.gwt.core.ext.typeinfo.JMethod;
-import com.google.gwt.core.ext.typeinfo.JPackage;
-import com.google.gwt.core.ext.typeinfo.JParameterizedType;
 import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
-import com.google.gwt.core.ext.typeinfo.JRawType;
-import com.google.gwt.core.ext.typeinfo.JRealClassType;
 import com.google.gwt.core.ext.typeinfo.JType;
-import com.google.gwt.core.ext.typeinfo.JTypeParameter;
-import com.google.gwt.core.ext.typeinfo.JWildcardType;
-import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.core.ext.typeinfo.TypeOracleBuilder;
 import com.google.gwt.dev.asm.ClassReader;
 import com.google.gwt.dev.asm.ClassVisitor;
 import com.google.gwt.dev.asm.Opcodes;
@@ -48,6 +34,20 @@
 import com.google.gwt.dev.javac.asm.ResolveTypeSignature;
 import com.google.gwt.dev.javac.asm.CollectAnnotationData.AnnotationData;
 import com.google.gwt.dev.javac.asm.CollectClassData.AnnotationEnum;
+import com.google.gwt.dev.javac.typemodel.JAbstractMethod;
+import com.google.gwt.dev.javac.typemodel.JArrayType;
+import com.google.gwt.dev.javac.typemodel.JClassType;
+import com.google.gwt.dev.javac.typemodel.JField;
+import com.google.gwt.dev.javac.typemodel.JGenericType;
+import com.google.gwt.dev.javac.typemodel.JMethod;
+import com.google.gwt.dev.javac.typemodel.JPackage;
+import com.google.gwt.dev.javac.typemodel.JParameterizedType;
+import com.google.gwt.dev.javac.typemodel.JRawType;
+import com.google.gwt.dev.javac.typemodel.JRealClassType;
+import com.google.gwt.dev.javac.typemodel.JTypeParameter;
+import com.google.gwt.dev.javac.typemodel.JWildcardType;
+import com.google.gwt.dev.javac.typemodel.TypeOracle;
+import com.google.gwt.dev.javac.typemodel.TypeOracleBuilder;
 import com.google.gwt.dev.util.Name;
 import com.google.gwt.dev.util.Name.InternalName;
 import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
@@ -170,7 +170,7 @@
    */
   private static JType possiblySubstituteRawType(JType type) {
     if (type != null) {
-      JGenericType genericType = type.isGenericType();
+      JGenericType genericType = (JGenericType) type.isGenericType();
       if (genericType != null) {
         type = genericType.getRawType();
       }
@@ -205,7 +205,7 @@
         TypeOracleMediator.this.addImplementedInterface(type, intf);
       }
 
-      public void addThrows(JAbstractMethod method, JType exception) {
+      public void addThrows(JAbstractMethod method, JClassType exception) {
         TypeOracleMediator.this.addThrows(method, exception);
       }
 
@@ -1052,7 +1052,7 @@
         if (exc == null) {
           return false;
         }
-        addThrows(method, exc);
+        addThrows(method, (JClassType) exc);
       }
     }
     return true;
diff --git a/dev/core/src/com/google/gwt/dev/javac/TypeParameterLookup.java b/dev/core/src/com/google/gwt/dev/javac/TypeParameterLookup.java
index 783e96f..fc9eeb0 100644
--- a/dev/core/src/com/google/gwt/dev/javac/TypeParameterLookup.java
+++ b/dev/core/src/com/google/gwt/dev/javac/TypeParameterLookup.java
@@ -15,9 +15,9 @@
  */
 package com.google.gwt.dev.javac;
 
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JGenericType;
-import com.google.gwt.core.ext.typeinfo.JTypeParameter;
+import com.google.gwt.dev.javac.typemodel.JClassType;
+import com.google.gwt.dev.javac.typemodel.JGenericType;
+import com.google.gwt.dev.javac.typemodel.JTypeParameter;
 import com.google.gwt.dev.util.collect.HashMap;
 import com.google.gwt.dev.util.collect.Maps;
 
diff --git a/dev/core/src/com/google/gwt/dev/javac/asm/CollectTypeParams.java b/dev/core/src/com/google/gwt/dev/javac/asm/CollectTypeParams.java
index 27a0802..6e8157e 100644
--- a/dev/core/src/com/google/gwt/dev/javac/asm/CollectTypeParams.java
+++ b/dev/core/src/com/google/gwt/dev/javac/asm/CollectTypeParams.java
@@ -15,7 +15,7 @@
  */
 package com.google.gwt.dev.javac.asm;
 
-import com.google.gwt.core.ext.typeinfo.JTypeParameter;
+import com.google.gwt.dev.javac.typemodel.JTypeParameter;
 
 import java.util.List;
 
diff --git a/dev/core/src/com/google/gwt/dev/javac/asm/ResolveClassSignature.java b/dev/core/src/com/google/gwt/dev/javac/asm/ResolveClassSignature.java
index ad74d7a..8d22395 100644
--- a/dev/core/src/com/google/gwt/dev/javac/asm/ResolveClassSignature.java
+++ b/dev/core/src/com/google/gwt/dev/javac/asm/ResolveClassSignature.java
@@ -16,13 +16,13 @@
 package com.google.gwt.dev.javac.asm;
 
 import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JRealClassType;
 import com.google.gwt.core.ext.typeinfo.JType;
-import com.google.gwt.core.ext.typeinfo.JTypeParameter;
 import com.google.gwt.dev.asm.signature.SignatureVisitor;
 import com.google.gwt.dev.javac.Resolver;
 import com.google.gwt.dev.javac.TypeParameterLookup;
+import com.google.gwt.dev.javac.typemodel.JClassType;
+import com.google.gwt.dev.javac.typemodel.JRealClassType;
+import com.google.gwt.dev.javac.typemodel.JTypeParameter;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/dev/core/src/com/google/gwt/dev/javac/asm/ResolveMethodSignature.java b/dev/core/src/com/google/gwt/dev/javac/asm/ResolveMethodSignature.java
index 236c999..0e76ce3 100644
--- a/dev/core/src/com/google/gwt/dev/javac/asm/ResolveMethodSignature.java
+++ b/dev/core/src/com/google/gwt/dev/javac/asm/ResolveMethodSignature.java
@@ -16,15 +16,15 @@
 package com.google.gwt.dev.javac.asm;
 
 import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
-import com.google.gwt.core.ext.typeinfo.JClassType;
 import com.google.gwt.core.ext.typeinfo.JType;
-import com.google.gwt.core.ext.typeinfo.JTypeParameter;
 import com.google.gwt.dev.asm.Type;
 import com.google.gwt.dev.asm.signature.SignatureVisitor;
 import com.google.gwt.dev.javac.MethodArgNamesLookup;
 import com.google.gwt.dev.javac.Resolver;
 import com.google.gwt.dev.javac.TypeParameterLookup;
+import com.google.gwt.dev.javac.typemodel.JAbstractMethod;
+import com.google.gwt.dev.javac.typemodel.JClassType;
+import com.google.gwt.dev.javac.typemodel.JTypeParameter;
 
 import java.lang.annotation.Annotation;
 import java.util.ArrayList;
@@ -44,7 +44,7 @@
   private final Type[] argTypes;
   private ArrayList<JType[]> bounds = null;
   private JTypeParameter currentParam = null;
-  private final List<JType[]> exceptions = new ArrayList<JType[]>();
+  private final List<JClassType[]> exceptions = new ArrayList<JClassType[]>();
   private final boolean hasReturnType;
   private final TreeLogger logger;
   private final JAbstractMethod method;
@@ -136,7 +136,7 @@
     }
 
     // Handle thrown exceptions
-    for (JType[] exc : exceptions) {
+    for (JClassType[] exc : exceptions) {
       if (exc[0] == null) {
         failed = true;
         continue;
@@ -162,7 +162,7 @@
 
   @Override
   public SignatureVisitor visitExceptionType() {
-    JType[] exc = new JType[1];
+    JClassType[] exc = new JClassType[1];
     exceptions.add(exc);
     return new ResolveTypeSignature(resolver, resolver.getBinaryMapper(),
         logger, exc, typeParamLookup, null);
diff --git a/dev/core/src/com/google/gwt/dev/javac/asm/ResolveTypeSignature.java b/dev/core/src/com/google/gwt/dev/javac/asm/ResolveTypeSignature.java
index 57aa8a7..a7207b0 100644
--- a/dev/core/src/com/google/gwt/dev/javac/asm/ResolveTypeSignature.java
+++ b/dev/core/src/com/google/gwt/dev/javac/asm/ResolveTypeSignature.java
@@ -16,19 +16,19 @@
 package com.google.gwt.dev.javac.asm;
 
 import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JGenericType;
-import com.google.gwt.core.ext.typeinfo.JParameterizedType;
 import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
-import com.google.gwt.core.ext.typeinfo.JRealClassType;
 import com.google.gwt.core.ext.typeinfo.JType;
-import com.google.gwt.core.ext.typeinfo.JTypeParameter;
-import com.google.gwt.core.ext.typeinfo.JWildcardType;
 import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
 import com.google.gwt.core.ext.typeinfo.NotFoundException;
 import com.google.gwt.dev.asm.signature.SignatureVisitor;
 import com.google.gwt.dev.javac.Resolver;
 import com.google.gwt.dev.javac.TypeParameterLookup;
+import com.google.gwt.dev.javac.typemodel.JClassType;
+import com.google.gwt.dev.javac.typemodel.JGenericType;
+import com.google.gwt.dev.javac.typemodel.JParameterizedType;
+import com.google.gwt.dev.javac.typemodel.JRealClassType;
+import com.google.gwt.dev.javac.typemodel.JTypeParameter;
+import com.google.gwt.dev.javac.typemodel.JWildcardType;
 import com.google.gwt.dev.util.Name;
 
 import java.util.ArrayList;
@@ -242,7 +242,7 @@
 
   private JType resolveGeneric(JType type, JClassType outer,
       JClassType[] typeArgs) {
-    JGenericType genericType = type.isGenericType();
+    JGenericType genericType = (JGenericType) type.isGenericType();
     if (genericType != null) {
       int actual = typeArgs.length;
       JTypeParameter[] typeParams = genericType.getTypeParameters();
@@ -322,7 +322,7 @@
   }
 
   private void resolveGenerics() {
-    JGenericType genericType = returnTypeRef[0].isGenericType();
+    JGenericType genericType = (JGenericType) returnTypeRef[0].isGenericType();
     if (genericType != null) {
       int actual = args.size();
       JClassType[] typeArgs = new JClassType[actual];
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/AbstractMembers.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/AbstractMembers.java
similarity index 97%
rename from dev/core/src/com/google/gwt/core/ext/typeinfo/AbstractMembers.java
rename to dev/core/src/com/google/gwt/dev/javac/typemodel/AbstractMembers.java
index 8e4b03e..c0e6c1d 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/AbstractMembers.java
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/AbstractMembers.java
@@ -13,7 +13,10 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
 
 import java.util.ArrayList;
 import java.util.Collection;
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/Annotations.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/Annotations.java
similarity index 97%
rename from dev/core/src/com/google/gwt/core/ext/typeinfo/Annotations.java
rename to dev/core/src/com/google/gwt/dev/javac/typemodel/Annotations.java
index 5da6638..5246151 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/Annotations.java
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/Annotations.java
@@ -13,8 +13,9 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
+import com.google.gwt.core.ext.typeinfo.HasAnnotations;
 import com.google.gwt.dev.util.collect.HashMap;
 import com.google.gwt.dev.util.collect.Maps;
 
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/DelegateMembers.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/DelegateMembers.java
similarity index 91%
rename from dev/core/src/com/google/gwt/core/ext/typeinfo/DelegateMembers.java
rename to dev/core/src/com/google/gwt/dev/javac/typemodel/DelegateMembers.java
index 0d875ed..74f0b98 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/DelegateMembers.java
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/DelegateMembers.java
@@ -13,8 +13,9 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
+import com.google.gwt.core.ext.typeinfo.JType;
 import com.google.gwt.dev.util.collect.HashMap;
 import com.google.gwt.dev.util.collect.Lists;
 import com.google.gwt.dev.util.collect.Maps;
@@ -135,7 +136,7 @@
     for (int i = 0; i < fields.length; ++i) {
       JField baseField = fields[i];
       JField newField = new JField(getParentType(), baseField);
-      newField.setType(substitution.getSubstitution(baseField.getType()));
+      newField.setType(substitute(baseField.getType()));
       fields[i] = newField;
       fieldMap.put(newField.getName(), newField);
     }
@@ -144,7 +145,7 @@
 
   private void initializeExceptions(JAbstractMethod srcMethod,
       JAbstractMethod newMethod) {
-    for (JType thrown : srcMethod.getThrows()) {
+    for (JClassType thrown : srcMethod.getThrows()) {
       // exceptions cannot be parameterized; just copy them over
       newMethod.addThrows(thrown);
     }
@@ -154,7 +155,7 @@
       JAbstractMethod newMethod) {
     for (JParameter srcParam : srcMethod.getParameters()) {
       JParameter newParam = new JParameter(newMethod, srcParam);
-      newParam.setType(substitution.getSubstitution(srcParam.getType()));
+      newParam.setType(substitute(srcParam.getType()));
       newMethod.addParameter(newParam);
     }
   }
@@ -171,7 +172,7 @@
       JMethod baseMethod = methods[i];
       JMethod newMethod = new JMethod(getParentType(), baseMethod);
       initializeParams(baseMethod, newMethod);
-      newMethod.setReturnType(substitution.getSubstitution(baseMethod.getReturnType()));
+      newMethod.setReturnType(substitute(baseMethod.getReturnType()));
       initializeExceptions(baseMethod, newMethod);
       methods[i] = newMethod;
 
@@ -200,4 +201,11 @@
     }
     methodMap = Maps.normalize(methodMap);
   }
+
+  private JType substitute(JType type) {
+    if (type instanceof JClassType) {
+      return substitution.getSubstitution((JClassType) type);
+    }
+    return type;
+  }
 }
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JAbstractMethod.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JAbstractMethod.java
new file mode 100644
index 0000000..76e8c47
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JAbstractMethod.java
@@ -0,0 +1,296 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.dev.util.StringInterner;
+import com.google.gwt.dev.util.collect.Lists;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Common superclass for {@link JMethod} and {@link JConstructor}.
+ */
+public abstract class JAbstractMethod implements
+    com.google.gwt.core.ext.typeinfo.JAbstractMethod {
+
+  private final Annotations annotations;
+
+  private boolean isVarArgs = false;
+
+  private int modifierBits;
+
+  private final String name;
+
+  private List<JParameter> params = Lists.create();
+
+  private String[] realParameterNames = null;
+
+  private List<JClassType> thrownTypes = Lists.create();
+
+  private List<JTypeParameter> typeParams = Lists.create();
+
+  JAbstractMethod(JAbstractMethod srcMethod) {
+    this.annotations = new Annotations(srcMethod.annotations);
+    this.isVarArgs = srcMethod.isVarArgs;
+    this.modifierBits = srcMethod.modifierBits;
+    this.name = srcMethod.name;
+  }
+
+  // Only the builder can construct
+  JAbstractMethod(String name,
+      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
+      JTypeParameter[] jtypeParameters) {
+    this.name = StringInterner.get().intern(name);
+    annotations = new Annotations(declaredAnnotations);
+
+    if (jtypeParameters != null) {
+      typeParams = Lists.create(jtypeParameters);
+    }
+  }
+
+  public JParameter findParameter(String name) {
+    for (JParameter param : params) {
+      if (param.getName().equals(name)) {
+        return param;
+      }
+    }
+    return null;
+  }
+
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+    return annotations.getAnnotation(annotationClass);
+  }
+
+  /**
+   * Gets the type in which this method or constructor was declared.
+   */
+  public abstract JClassType getEnclosingType();
+
+  public JType[] getErasedParameterTypes() {
+    JType[] types = new JType[params.size()];
+    for (int i = 0; i < types.length; ++i) {
+      types[i] = params.get(i).getType().getErasedType();
+    }
+    return types;
+  }
+
+  /**
+   * Returns a string contating a JSNI reference to the method.
+   * 
+   * @return <code>@package.Class::method(Lpackage/Param;...)</code>
+   */
+  public abstract String getJsniSignature();
+
+  @Deprecated
+  public final String[][] getMetaData(String tagName) {
+    return TypeOracle.NO_STRING_ARR_ARR;
+  }
+
+  @Deprecated
+  public final String[] getMetaDataTags() {
+    return TypeOracle.NO_STRINGS;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public JParameter[] getParameters() {
+    // TODO(jat): where do we handle fake arg names?
+    return params.toArray(TypeOracle.NO_JPARAMS);
+  }
+
+  public JType[] getParameterTypes() {
+    final JType[] paramTypes = new JType[params.size()];
+    for (int i = 0; i < paramTypes.length; ++i) {
+      paramTypes[i] = params.get(i).getType();
+    }
+    return paramTypes;
+  }
+
+  public abstract String getReadableDeclaration();
+
+  public JClassType[] getThrows() {
+    return thrownTypes.toArray(TypeOracle.NO_JCLASSES);
+  }
+
+  public JTypeParameter[] getTypeParameters() {
+    return typeParams.toArray(new JTypeParameter[typeParams.size()]);
+  }
+
+  public JAnnotationMethod isAnnotationMethod() {
+    return null;
+  }
+
+  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+    return annotations.isAnnotationPresent(annotationClass);
+  }
+
+  public abstract JConstructor isConstructor();
+
+  public boolean isDefaultAccess() {
+    return 0 == (modifierBits & (TypeOracle.MOD_PUBLIC | TypeOracle.MOD_PRIVATE | TypeOracle.MOD_PROTECTED));
+  }
+
+  public abstract JMethod isMethod();
+
+  public boolean isPrivate() {
+    return 0 != (modifierBits & TypeOracle.MOD_PRIVATE);
+  }
+
+  public boolean isProtected() {
+    return 0 != (modifierBits & TypeOracle.MOD_PROTECTED);
+  }
+
+  public boolean isPublic() {
+    return 0 != (modifierBits & TypeOracle.MOD_PUBLIC);
+  }
+
+  public boolean isVarArgs() {
+    return isVarArgs;
+  }
+
+  protected int getModifierBits() {
+    return modifierBits;
+  }
+
+  protected void toStringParamsAndThrows(StringBuilder sb) {
+    sb.append("(");
+    boolean needComma = false;
+    for (int i = 0, c = params.size(); i < c; ++i) {
+      JParameter param = params.get(i);
+      if (needComma) {
+        sb.append(", ");
+      } else {
+        needComma = true;
+      }
+      if (isVarArgs() && i == c - 1) {
+        JArrayType arrayType = (JArrayType) param.getType().isArray();
+        assert (arrayType != null);
+        sb.append(arrayType.getComponentType().getParameterizedQualifiedSourceName());
+        sb.append("...");
+      } else {
+        sb.append(param.getType().getParameterizedQualifiedSourceName());
+      }
+      sb.append(" ");
+      sb.append(param.getName());
+    }
+    sb.append(")");
+
+    if (!thrownTypes.isEmpty()) {
+      sb.append(" throws ");
+      needComma = false;
+      for (JClassType thrownType : thrownTypes) {
+        if (needComma) {
+          sb.append(", ");
+        } else {
+          needComma = true;
+        }
+        sb.append(thrownType.getParameterizedQualifiedSourceName());
+      }
+    }
+  }
+
+  protected void toStringTypeParams(StringBuilder sb) {
+    sb.append("<");
+    boolean needComma = false;
+    for (JTypeParameter typeParam : typeParams) {
+      if (needComma) {
+        sb.append(", ");
+      } else {
+        needComma = true;
+      }
+      sb.append(typeParam.getQualifiedSourceName());
+    }
+    sb.append(">");
+  }
+
+  void addModifierBits(int bits) {
+    modifierBits |= bits;
+  }
+
+  void addParameter(JParameter param) {
+    params = Lists.add(params, param);
+  }
+
+  void addThrows(JClassType type) {
+    thrownTypes = Lists.add(thrownTypes, type);
+  }
+
+  /**
+   * NOTE: This method is for testing purposes only.
+   */
+  Annotation[] getAnnotations() {
+    return annotations.getAnnotations();
+  }
+
+  /**
+   * NOTE: This method is for testing purposes only.
+   */
+  Annotation[] getDeclaredAnnotations() {
+    return annotations.getDeclaredAnnotations();
+  }
+
+  // Called only by a JParameter, passing itself as a reference for lookup.
+  String getRealParameterName(JParameter parameter) {
+    if (realParameterNames == null) {
+      fetchRealParameterNames();
+    }
+    int n = params.size();
+    for (int i = 0; i < n; ++i) {
+      // Identity tests are ok since identity is durable within an oracle.
+      if (params.get(i) == parameter) {
+        String realParameterName;
+        if (realParameterNames == null) {
+          realParameterName = StringInterner.get().intern("arg" + i);
+        } else {
+          realParameterName = StringInterner.get().intern(realParameterNames[i]);
+        }
+        return realParameterName;
+      }
+    }
+    // TODO: report error if we are asked for an unknown JParameter?
+    return null;
+  }
+
+  boolean hasParamTypes(JType[] paramTypes) {
+    if (params.size() != paramTypes.length) {
+      return false;
+    }
+
+    for (int i = 0; i < paramTypes.length; i++) {
+      JParameter candidate = params.get(i);
+      // Identity tests are ok since identity is durable within an oracle.
+      //
+      if (candidate.getType() != paramTypes[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  void setVarArgs() {
+    isVarArgs = true;
+  }
+
+  private void fetchRealParameterNames() {
+    realParameterNames = getEnclosingType().getOracle().getJavaSourceParser().getArguments(
+        this);
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JAnnotationMethod.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JAnnotationMethod.java
new file mode 100644
index 0000000..e358421
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JAnnotationMethod.java
@@ -0,0 +1,54 @@
+/*
+ * 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.javac.typemodel;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+/**
+ * Method declared on an annotation type.
+ */
+public class JAnnotationMethod extends JMethod implements
+    com.google.gwt.core.ext.typeinfo.JAnnotationMethod {
+  /**
+   * Default value for this annotation element. <code>null</code> is not a valid
+   * default value for an annotation element.
+   */
+  private final Object defaultValue;
+
+  JAnnotationMethod(JClassType enclosingType, String name,
+      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
+      JTypeParameter[] jtypeParameters, Object defaultValue) {
+    super(enclosingType, name, declaredAnnotations, jtypeParameters);
+    this.defaultValue = defaultValue;
+  }
+
+  /**
+   * Returns the default value for this annotation method or <code>null</code>
+   * if there is not one.
+   * 
+   * @return default value for this annotation method or <code>null</code> if
+   *         there is not one
+   */
+  public Object getDefaultValue() {
+    return defaultValue;
+  }
+
+  @Override
+  public JAnnotationMethod isAnnotationMethod() {
+    return this;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JAnnotationType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JAnnotationType.java
new file mode 100644
index 0000000..2ebac41
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JAnnotationType.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+
+import java.util.Arrays;
+
+/**
+ * Type representing an annotation type.
+ */
+public class JAnnotationType extends JRealClassType implements
+    com.google.gwt.core.ext.typeinfo.JAnnotationType {
+
+  JAnnotationType(TypeOracle oracle, JPackage declaringPackage,
+      String enclosingTypeName, String name) {
+    super(oracle, declaringPackage, enclosingTypeName, name, true);
+  }
+
+  @Override
+  public JAnnotationMethod getMethod(String name, JType[] paramTypes)
+      throws NotFoundException {
+    return (JAnnotationMethod) super.getMethod(name, paramTypes);
+  }
+
+  @Override
+  public JAnnotationMethod[] getMethods() {
+    JMethod[] methodArray = super.getMethods();
+    return Arrays.asList(methodArray).toArray(
+        new JAnnotationMethod[methodArray.length]);
+  }
+
+  @Override
+  public JAnnotationMethod[] getOverridableMethods() {
+    JMethod[] methodArray = super.getOverridableMethods();
+    return Arrays.asList(methodArray).toArray(
+        new JAnnotationMethod[methodArray.length]);
+  }
+
+  @Override
+  public JAnnotationType isAnnotation() {
+    return this;
+  }
+
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JArrayType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JArrayType.java
new file mode 100644
index 0000000..1ccf17c
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JArrayType.java
@@ -0,0 +1,462 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.util.StringInterner;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+/**
+ * Type representing a Java array.
+ */
+public class JArrayType extends JClassType implements
+    com.google.gwt.core.ext.typeinfo.JArrayType {
+  private static final JArrayType[] NO_JARRAYS = new JArrayType[0];
+
+  private JType componentType;
+
+  private String lazyQualifiedBinaryName;
+
+  private String lazyQualifiedName;
+
+  private String lazySimpleName;
+
+  private final TypeOracle oracle;
+
+  JArrayType(JType componentType, TypeOracle oracle) {
+    this.componentType = componentType;
+    this.oracle = oracle;
+  }
+
+  @Override
+  public JConstructor findConstructor(JType[] paramTypes) {
+    return null;
+  }
+
+  @Override
+  public JField findField(String name) {
+    return null;
+  }
+
+  @Override
+  public JMethod findMethod(String name, JType[] paramTypes) {
+    return getOracle().getJavaLangObject().findMethod(name, paramTypes);
+  }
+
+  @Override
+  public JClassType findNestedType(String typeName) {
+    return null;
+  }
+
+  @Override
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+    return null;
+  }
+
+  public JType getComponentType() {
+    return componentType;
+  }
+
+  @Override
+  public JConstructor getConstructor(JType[] paramTypes)
+      throws NotFoundException {
+    throw new NotFoundException();
+  }
+
+  @Override
+  public JConstructor[] getConstructors() {
+    return TypeOracle.NO_JCTORS;
+  }
+
+  @Override
+  public JClassType getEnclosingType() {
+    return null;
+  }
+
+  @Override
+  public JClassType getErasedType() {
+    return getOracle().getArrayType(getComponentType().getErasedType());
+  }
+
+  @Override
+  public JField getField(String name) {
+    return null;
+  }
+
+  @Override
+  public JField[] getFields() {
+    return TypeOracle.NO_JFIELDS;
+  }
+
+  @Override
+  public JClassType[] getImplementedInterfaces() {
+    return TypeOracle.NO_JCLASSES;
+  }
+
+  @Override
+  public JMethod[] getInheritableMethods() {
+    return getOracle().getJavaLangObject().getInheritableMethods();
+  }
+
+  @Override
+  public String getJNISignature() {
+    return "[" + componentType.getJNISignature();
+  }
+
+  @Override
+  public JType getLeafType() {
+    return componentType.getLeafType();
+  }
+
+  @Override
+  public JMethod getMethod(String name, JType[] paramTypes)
+      throws NotFoundException {
+    return getOracle().getJavaLangObject().getMethod(name, paramTypes);
+  }
+
+  @Override
+  public JMethod[] getMethods() {
+    return getOracle().getJavaLangObject().getMethods();
+  }
+
+  @Override
+  public String getName() {
+    return getSimpleSourceName();
+  }
+
+  @Override
+  public JClassType getNestedType(String typeName) throws NotFoundException {
+    throw new NotFoundException();
+  }
+
+  @Override
+  public JClassType[] getNestedTypes() {
+    return TypeOracle.NO_JCLASSES;
+  }
+
+  @Override
+  public TypeOracle getOracle() {
+    return oracle;
+  }
+
+  @Override
+  public JMethod[] getOverloads(String name) {
+    return getOracle().getJavaLangObject().getOverloads(name);
+  }
+
+  @Override
+  public JMethod[] getOverridableMethods() {
+    return getOracle().getJavaLangObject().getOverridableMethods();
+  }
+
+  @Override
+  public JPackage getPackage() {
+    JType leafType = getLeafType();
+    if (leafType.isPrimitive() != null) {
+      // TODO: is there a default package?
+      return null;
+    }
+
+    JClassType leafClass = (JClassType) leafType;
+    return leafClass.getPackage();
+  }
+
+  @Override
+  public String getParameterizedQualifiedSourceName() {
+    return getComponentType().getParameterizedQualifiedSourceName() + "[]";
+  }
+
+  @Override
+  public String getQualifiedBinaryName() {
+    if (lazyQualifiedBinaryName == null) {
+      lazyQualifiedBinaryName = "["
+          + getComponentType().getQualifiedBinaryName();
+    }
+    return lazyQualifiedBinaryName;
+  }
+
+  @Override
+  public String getQualifiedSourceName() {
+    if (lazyQualifiedName == null) {
+      lazyQualifiedName = getComponentType().getQualifiedSourceName() + "[]";
+    }
+    return lazyQualifiedName;
+  }
+
+  public int getRank() {
+    JArrayType componentArrayType = (JArrayType) componentType.isArray();
+    if (componentArrayType != null) {
+      return 1 + componentArrayType.getRank();
+    }
+
+    return 1;
+  }
+
+  @Override
+  public String getSimpleSourceName() {
+    if (lazySimpleName == null) {
+      lazySimpleName = StringInterner.get().intern(
+          getComponentType().getSimpleSourceName() + "[]");
+    }
+    return lazySimpleName;
+  }
+
+  @Override
+  public JArrayType[] getSubtypes() {
+    if (getComponentType().isPrimitive() != null) {
+      return NO_JARRAYS;
+    }
+
+    JClassType componentClass = (JClassType) getComponentType();
+    JClassType[] componentSubtypes = componentClass.getSubtypes();
+    JArrayType[] arraySubtypes = new JArrayType[componentSubtypes.length];
+    for (int i = 0; i < componentSubtypes.length; ++i) {
+      arraySubtypes[i] = getOracle().getArrayType(componentSubtypes[i]);
+    }
+
+    return arraySubtypes;
+  }
+
+  @Override
+  public JClassType getSuperclass() {
+    return getOracle().getJavaLangObject();
+  }
+
+  @Override
+  public boolean isAbstract() {
+    return false;
+  }
+
+  @Override
+  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+    return false;
+  }
+
+  @Override
+  public JArrayType isArray() {
+    return this;
+  }
+
+  @Override
+  public JClassType isClass() {
+    // intentional null
+    return null;
+  }
+
+  @Override
+  public boolean isDefaultInstantiable() {
+    return true;
+  }
+
+  @Override
+  public JEnumType isEnum() {
+    return null;
+  }
+
+  // Refer the documentation for java.lang.Class::getModifiers()
+  @Override
+  public boolean isFinal() {
+    return true;
+  }
+
+  @Override
+  public JGenericType isGenericType() {
+    return null;
+  }
+
+  @Override
+  public JClassType isInterface() {
+    // intentional null
+    return null;
+  }
+
+  @Override
+  public boolean isMemberType() {
+    return false;
+  }
+
+  @Override
+  public JParameterizedType isParameterized() {
+    // intentional null
+    return null;
+  }
+
+  @Override
+  public JPrimitiveType isPrimitive() {
+    // intentional null
+    return null;
+  }
+
+  @Override
+  public boolean isPrivate() {
+    return false;
+  }
+
+  @Override
+  public boolean isProtected() {
+    return false;
+  }
+
+  @Override
+  public boolean isPublic() {
+    return true;
+  }
+
+  @Override
+  public JRawType isRawType() {
+    return null;
+  }
+
+  @Override
+  public boolean isStatic() {
+    return true;
+  }
+
+  @Override
+  public JWildcardType isWildcard() {
+    return null;
+  }
+
+  @Override
+  public String toString() {
+    return getQualifiedSourceName();
+  }
+
+  @Override
+  protected void acceptSubtype(JClassType me) {
+    throw new UnsupportedOperationException("modifying a "
+        + getClass().getSimpleName());
+  }
+
+  @Override
+  protected void getInheritableMethodsOnSuperclassesAndThisClass(
+      Map<String, JMethod> methodsBySignature) {
+    getOracle().getJavaLangObject().getInheritableMethodsOnSuperclassesAndThisClass(
+        methodsBySignature);
+  }
+
+  @Override
+  protected void getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
+      Map<String, JMethod> methodsBySignature) {
+    getOracle().getJavaLangObject().getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
+        methodsBySignature);
+  }
+
+  @Override
+  protected int getModifierBits() {
+    return 0;
+  }
+
+  @Override
+  protected void notifySuperTypesOf(JClassType me) {
+  }
+
+  @Override
+  protected void removeSubtype(JClassType me) {
+  }
+
+  @Override
+  void addConstructor(JConstructor ctor) {
+    throw new UnsupportedOperationException("modifying a "
+        + getClass().getSimpleName());
+  }
+
+  @Override
+  void addField(JField field) {
+    throw new UnsupportedOperationException("modifying a "
+        + getClass().getSimpleName());
+  }
+
+  @Override
+  void addImplementedInterface(JClassType intf) {
+    throw new UnsupportedOperationException("modifying a "
+        + getClass().getSimpleName());
+  }
+
+  @Override
+  void addMethod(JMethod method) {
+    throw new UnsupportedOperationException("modifying a "
+        + getClass().getSimpleName());
+  }
+
+  @Override
+  void addModifierBits(int bits) {
+    throw new UnsupportedOperationException("modifying a "
+        + getClass().getSimpleName());
+  }
+
+  @Override
+  void addNestedType(JClassType type) {
+    throw new UnsupportedOperationException("modifying a "
+        + getClass().getSimpleName());
+  }
+
+  @Override
+  JClassType findNestedTypeImpl(String[] typeName, int index) {
+    return null;
+  }
+
+  /**
+   * NOTE: This method is for testing purposes only.
+   */
+  @Override
+  Annotation[] getAnnotations() {
+    return TypeOracle.NO_ANNOTATIONS;
+  }
+
+  /**
+   * NOTE: This method is for testing purposes only.
+   */
+  @Override
+  Annotation[] getDeclaredAnnotations() {
+    return TypeOracle.NO_ANNOTATIONS;
+  }
+
+  @Override
+  JArrayType getSubstitutedType(JParameterizedType parameterizedType) {
+    if (getComponentType() instanceof JClassType) {
+      JClassType classType = (JClassType) getComponentType();
+      return oracle.getArrayType(classType.getSubstitutedType(parameterizedType));
+    } else {
+      return this;
+    }
+  }
+
+  @Override
+  void notifySuperTypes() {
+  }
+
+  @Override
+  void removeFromSupertypes() {
+  }
+
+  void setLeafType(JType type) {
+    JArrayType componentTypeIsArray = (JArrayType) componentType.isArray();
+    if (componentTypeIsArray != null) {
+      componentTypeIsArray.setLeafType(type);
+    } else {
+      componentType = type;
+    }
+  }
+
+  @Override
+  void setSuperclass(JClassType type) {
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JClassType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JClassType.java
new file mode 100644
index 0000000..33b442c
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JClassType.java
@@ -0,0 +1,805 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.util.collect.HashSet;
+
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Type used to represent any non-primitive type.
+ */
+public abstract class JClassType implements
+    com.google.gwt.core.ext.typeinfo.JClassType {
+
+  /**
+   * Returns all of the superclasses and superinterfaces for a given type
+   * including the type itself. The returned set maintains an internal
+   * breadth-first ordering of the type, followed by its interfaces (and their
+   * super-interfaces), then the supertype and its interfaces, and so on.
+   */
+  protected static Set<JClassType> getFlattenedSuperTypeHierarchy(
+      JClassType type) {
+    Set<JClassType> flattened = type.flattenedSupertypes;
+    if (flattened == null) {
+      flattened = new LinkedHashSet<JClassType>();
+      getFlattenedSuperTypeHierarchyRecursive(type, flattened);
+      // flattened.size() > 1 for all types other than Object
+      type.flattenedSupertypes = Collections.unmodifiableSet(flattened);
+    }
+    return flattened;
+  }
+
+  /**
+   * Returns <code>true</code> if the rhs array type can be assigned to the lhs
+   * array type.
+   */
+  private static boolean areArraysAssignable(JArrayType lhsType,
+      JArrayType rhsType) {
+    // areClassTypesAssignable should prevent us from getting here if the types
+    // are referentially equal.
+    assert (lhsType != rhsType);
+
+    JType lhsComponentType = lhsType.getComponentType();
+    JType rhsComponentType = rhsType.getComponentType();
+
+    if (lhsComponentType.isPrimitive() != null
+        || rhsComponentType.isPrimitive() != null) {
+      /*
+       * Arrays are referentially stable so there will only be one int[] no
+       * matter how many times it is referenced in the code. So, if either
+       * component type is a primitive then we know that we are not assignable.
+       */
+      return false;
+    }
+
+    assert (lhsComponentType instanceof JClassType);
+    assert (rhsComponentType instanceof JClassType);
+
+    JClassType thisComponentClass = (JClassType) lhsComponentType;
+    JClassType subtypeComponentClass = (JClassType) rhsComponentType;
+
+    return areClassTypesAssignable(thisComponentClass, subtypeComponentClass);
+  }
+
+  /**
+   * Returns <code>true</code> if the rhsType can be assigned to the lhsType.
+   */
+  private static boolean areClassTypesAssignable(
+      com.google.gwt.core.ext.typeinfo.JClassType lhsType,
+      com.google.gwt.core.ext.typeinfo.JClassType rhsType) {
+    // The supertypes of rhs will include rhs.
+    Set<JClassType> rhsSupertypes = getFlattenedSuperTypeHierarchy((JClassType) rhsType);
+    for (JClassType rhsSupertype : rhsSupertypes) {
+      if (areClassTypesAssignableNoSupers((JClassType) lhsType, rhsSupertype)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Returns <code>true</code> if the lhs and rhs are assignable without
+   * consideration of the supertypes of the rhs.
+   * 
+   * @param lhsType
+   * @param rhsType
+   * @return true if rhsType can be assigned to lhsType
+   */
+  private static boolean areClassTypesAssignableNoSupers(JClassType lhsType,
+      JClassType rhsType) {
+    if (lhsType == rhsType) {
+      // Done, these are the same types.
+      return true;
+    }
+
+    if (lhsType == lhsType.getOracle().getJavaLangObject()) {
+      // Done, any type can be assigned to object.
+      return true;
+    }
+
+    /*
+     * Get the generic base type, if there is one, for the lhs type and convert
+     * it to a raw type if it is generic.
+     */
+    if (lhsType.isGenericType() != null) {
+      lhsType = lhsType.isGenericType().getRawType();
+    }
+
+    if (rhsType.isGenericType() != null) {
+      // Treat the generic rhs type as a raw type.
+      rhsType = rhsType.isGenericType().getRawType();
+    }
+
+    // Check for JTypeParameters.
+    JTypeParameter lhsTypeParam = lhsType.isTypeParameter();
+    JTypeParameter rhsTypeParam = rhsType.isTypeParameter();
+    if (lhsTypeParam != null) {
+      JClassType[] lhsTypeBounds = lhsTypeParam.getBounds();
+      for (JClassType lhsTypeBound : lhsTypeBounds) {
+        if (!areClassTypesAssignable(lhsTypeBound, rhsType)) {
+          // Done, the rhsType was not assignable to one of the bounds.
+          return false;
+        }
+      }
+
+      // Done, the rhsType was assignable to all of the bounds.
+      return true;
+    } else if (rhsTypeParam != null) {
+      JClassType[] possibleSubtypeBounds = rhsTypeParam.getBounds();
+      for (JClassType possibleSubtypeBound : possibleSubtypeBounds) {
+        if (areClassTypesAssignable(lhsType, possibleSubtypeBound)) {
+          // Done, at least one bound is assignable to this type.
+          return true;
+        }
+      }
+
+      return false;
+    }
+
+    /*
+     * Check for JWildcards. We have not examined this part in great detail
+     * since there should not be top level wildcard types.
+     */
+    JWildcardType lhsWildcard = lhsType.isWildcard();
+    JWildcardType rhsWildcard = rhsType.isWildcard();
+    if (lhsWildcard != null && rhsWildcard != null) {
+      // Both types are wildcards.
+      return areWildcardsAssignable(lhsWildcard, rhsWildcard);
+    } else if (lhsWildcard != null) {
+      // The lhs type is a wildcard but the rhs is not.
+      // ? extends T, U OR ? super T, U
+      JClassType[] lowerBounds = lhsWildcard.getLowerBounds();
+      if (lowerBounds.length > 0) {
+        // ? super T will reach object no matter what the rhs type is
+        return true;
+      } else {
+        return areClassTypesAssignable(lhsWildcard.getFirstBound(), rhsType);
+      }
+    }
+
+    // Check for JArrayTypes.
+    JArrayType lhsArray = lhsType.isArray();
+    JArrayType rhsArray = rhsType.isArray();
+    if (lhsArray != null) {
+      if (rhsArray == null) {
+        return false;
+      } else {
+        return areArraysAssignable(lhsArray, rhsArray);
+      }
+    } else if (rhsArray != null) {
+      // Safe although perhaps not necessary
+      return false;
+    }
+
+    // Check for JParameterizedTypes and JRawTypes.
+    JMaybeParameterizedType lhsMaybeParameterized = lhsType.isMaybeParameterizedType();
+    JMaybeParameterizedType rhsMaybeParameterized = rhsType.isMaybeParameterizedType();
+    if (lhsMaybeParameterized != null && rhsMaybeParameterized != null) {
+      if (lhsMaybeParameterized.getBaseType() == rhsMaybeParameterized.getBaseType()) {
+        if (lhsMaybeParameterized.isRawType() != null
+            || rhsMaybeParameterized.isRawType() != null) {
+          /*
+           * Any raw type can be assigned to or from any parameterization of its
+           * generic type.
+           */
+          return true;
+        }
+
+        assert (lhsMaybeParameterized.isRawType() == null && rhsMaybeParameterized.isRawType() == null);
+        JParameterizedType lhsParameterized = lhsMaybeParameterized.isParameterized();
+        JParameterizedType rhsParameterized = rhsMaybeParameterized.isParameterized();
+        assert (lhsParameterized != null && rhsParameterized != null);
+
+        return areTypeArgumentsAssignable(lhsParameterized, rhsParameterized);
+      }
+    }
+
+    // Default to not being assignable.
+    return false;
+  }
+
+  /**
+   * Returns <code>true</code> if the type arguments of the rhs parameterized
+   * type are assignable to the type arguments of the lhs parameterized type.
+   */
+  private static boolean areTypeArgumentsAssignable(JParameterizedType lhsType,
+      JParameterizedType rhsType) {
+    // areClassTypesAssignable should prevent us from getting here if the types
+    // are referentially equal.
+    assert (lhsType != rhsType);
+    assert (lhsType.getBaseType() == rhsType.getBaseType());
+
+    JClassType[] lhsTypeArgs = lhsType.getTypeArgs();
+    JClassType[] rhsTypeArgs = rhsType.getTypeArgs();
+    JGenericType lhsBaseType = lhsType.getBaseType();
+
+    // Compare at least as many formal type parameters as are declared on the
+    // generic base type. gwt.typeArgs could cause more types to be included.
+
+    JTypeParameter[] lhsTypeParams = lhsBaseType.getTypeParameters();
+    for (int i = 0; i < lhsTypeParams.length; ++i) {
+      if (!doesTypeArgumentContain(lhsTypeArgs[i], rhsTypeArgs[i])) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * Returns <code>true</code> if the rhsWildcard can be assigned to the
+   * lhsWildcard. This method does not consider supertypes of either lhs or rhs.
+   */
+  private static boolean areWildcardsAssignable(JWildcardType lhsWildcard,
+      JWildcardType rhsWildcard) {
+    // areClassTypesAssignable should prevent us from getting here if the types
+    // are referentially equal.
+    assert (lhsWildcard != rhsWildcard);
+    assert (lhsWildcard != null && rhsWildcard != null);
+
+    if (lhsWildcard.getLowerBounds().length > 0
+        && rhsWildcard.getLowerBounds().length > 0) {
+      // lhsType: ? super T, rhsType ? super U
+      return areClassTypesAssignable(rhsWildcard.getFirstBound(),
+          lhsWildcard.getFirstBound());
+    } else if (lhsWildcard.getUpperBounds().length > 0
+        && lhsWildcard.getLowerBounds().length == 0
+        && rhsWildcard.getUpperBounds().length > 0
+        && rhsWildcard.getLowerBounds().length == 0) {
+      // lhsType: ? extends T, rhsType: ? extends U
+      return areClassTypesAssignable(lhsWildcard.getFirstBound(),
+          rhsWildcard.getFirstBound());
+    }
+
+    return false;
+  }
+
+  /**
+   * A restricted version of areClassTypesAssignable that is used for comparing
+   * the type arguments of parameterized types, where the lhsTypeArg is the
+   * container.
+   */
+  private static boolean doesTypeArgumentContain(JClassType lhsTypeArg,
+      JClassType rhsTypeArg) {
+    if (lhsTypeArg == rhsTypeArg) {
+      return true;
+    }
+
+    // Check for wildcard types
+    JWildcardType lhsWildcard = lhsTypeArg.isWildcard();
+    JWildcardType rhsWildcard = rhsTypeArg.isWildcard();
+
+    if (lhsWildcard != null) {
+      if (rhsWildcard != null) {
+        return areWildcardsAssignable(lhsWildcard, rhsWildcard);
+      } else {
+        // LHS is a wildcard but the RHS is not.
+        if (lhsWildcard.getLowerBounds().length > 0) {
+          return areClassTypesAssignable(rhsTypeArg,
+              lhsWildcard.getFirstBound());
+        } else {
+          return areClassTypesAssignable(lhsWildcard.getFirstBound(),
+              rhsTypeArg);
+        }
+      }
+    }
+
+    /*
+     * At this point the arguments are not the same and they are not wildcards
+     * so, they cannot be assignable, Eh.
+     */
+    return false;
+  }
+
+  private static void getFlattenedSuperTypeHierarchyRecursive(JClassType type,
+      Set<JClassType> typesSeen) {
+    if (typesSeen.contains(type)) {
+      return;
+    }
+    typesSeen.add(type);
+
+    // Check the interfaces
+    JClassType[] intfs = type.getImplementedInterfaces();
+    for (JClassType intf : intfs) {
+      typesSeen.addAll(getFlattenedSuperTypeHierarchy(intf));
+    }
+
+    // Superclass
+    JClassType superclass = type.getSuperclass();
+    if (superclass != null) {
+      typesSeen.addAll(getFlattenedSuperTypeHierarchy(superclass));
+    }
+  }
+
+  /**
+   * Cached set of supertypes for this type (including itself). If null, the set
+   * has not been calculated yet.
+   */
+  private Set<JClassType> flattenedSupertypes;
+
+  /**
+   * True if this type may be enhanced with server-only fields. This property is
+   * 'sticky' and may be set but not unset, since we need to generate the
+   * relevant RPC code for handling the server fields if there is any chance the
+   * class will be enhanced.
+   */
+  private boolean isEnhanced = false;
+
+  public JParameterizedType asParameterizationOf(
+      com.google.gwt.core.ext.typeinfo.JGenericType type) {
+    Set<JClassType> supertypes = getFlattenedSuperTypeHierarchy(this);
+    for (JClassType supertype : supertypes) {
+      JParameterizedType isParameterized = supertype.isParameterized();
+      if (isParameterized != null && isParameterized.getBaseType() == type) {
+        return isParameterized;
+      }
+
+      JRawType isRaw = supertype.isRawType();
+      if (isRaw != null && isRaw.getBaseType() == type) {
+        return isRaw.asParameterizedByWildcards();
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * All types use identity for comparison.
+   */
+  @Override
+  public final boolean equals(Object obj) {
+    return super.equals(obj);
+  }
+
+  /**
+   * Find an annotation on a type or on one of its superclasses or
+   * superinterfaces.
+   * <p>
+   * This provides semantics similar to that of
+   * {@link java.lang.annotation.Inherited} except that it checks all types to
+   * which this type is assignable. {@code @Inherited} only works on
+   * superclasses, not superinterfaces.
+   * <p>
+   * Annotations present on the superclass chain will be returned preferentially
+   * over those found in the superinterface hierarchy. Note that the annotation
+   * does not need to be tagged with {@code @Inherited} in order to be returned
+   * from the superclass chain.
+   * 
+   * @param annotationType the type of the annotation to look for
+   * @return the desired annotation or <code>null</code> if the annotation is
+   *         not present in the type's type hierarchy
+   */
+  public <T extends Annotation> T findAnnotationInTypeHierarchy(
+      Class<T> annotationType) {
+
+    // Remember what we've seen to avoid loops
+    Set<JClassType> seen = new HashSet<JClassType>();
+
+    // Work queue
+    List<JClassType> searchTypes = new LinkedList<JClassType>();
+    searchTypes.add(this);
+
+    T toReturn = null;
+
+    while (!searchTypes.isEmpty()) {
+      JClassType current = searchTypes.remove(0);
+
+      if (!seen.add(current)) {
+        continue;
+      }
+
+      toReturn = current.getAnnotation(annotationType);
+      if (toReturn != null) {
+        /*
+         * First one wins. It might be desirable at some point to have a
+         * variation that can return more than one instance of the annotation if
+         * it is present on multiple supertypes.
+         */
+        break;
+      }
+
+      if (current.getSuperclass() != null) {
+        // Add the superclass at the front of the list
+        searchTypes.add(0, current.getSuperclass());
+      }
+
+      // Superinterfaces
+      Collections.addAll(searchTypes, current.getImplementedInterfaces());
+    }
+
+    return toReturn;
+  }
+
+  public abstract JConstructor findConstructor(JType[] paramTypes);
+
+  public abstract JField findField(String name);
+
+  public abstract JMethod findMethod(String name, JType[] paramTypes);
+
+  public abstract JClassType findNestedType(String typeName);
+
+  public abstract <T extends Annotation> T getAnnotation(
+      Class<T> annotationClass);
+
+  public abstract JConstructor getConstructor(JType[] paramTypes)
+      throws NotFoundException;
+
+  public abstract JConstructor[] getConstructors();
+
+  public abstract JClassType getEnclosingType();
+
+  public abstract JClassType getErasedType();
+
+  public abstract JField getField(String name);
+
+  public abstract JField[] getFields();
+
+  /**
+   * Returns all of the superclasses and superinterfaces for a given type
+   * including the type itself. The returned set maintains an internal
+   * breadth-first ordering of the type, followed by its interfaces (and their
+   * super-interfaces), then the supertype and its interfaces, and so on.
+   */
+  public Set<JClassType> getFlattenedSupertypeHierarchy() {
+    // Retuns an immutable set
+    return getFlattenedSuperTypeHierarchy(this);
+  }
+
+  public abstract JClassType[] getImplementedInterfaces();
+
+  /**
+   * Iterates over the most-derived declaration of each unique inheritable
+   * method available in the type hierarchy of the specified type, including
+   * those found in superclasses and superinterfaces. A method is inheritable if
+   * its accessibility is <code>public</code>, <code>protected</code>, or
+   * package protected.
+   * 
+   * This method offers a convenient way for Generators to find candidate
+   * methods to call from a subclass.
+   * 
+   * @return an array of {@link JMethod} objects representing inheritable
+   *         methods
+   */
+  public abstract JMethod[] getInheritableMethods();
+
+  public abstract String getJNISignature();
+
+  public JType getLeafType() {
+    return this;
+  }
+
+  @Deprecated
+  public final String[][] getMetaData(String tagName) {
+    return TypeOracle.NO_STRING_ARR_ARR;
+  }
+
+  @Deprecated
+  public final String[] getMetaDataTags() {
+    return TypeOracle.NO_STRINGS;
+  }
+
+  public abstract JMethod getMethod(String name, JType[] paramTypes)
+      throws NotFoundException;
+
+  /*
+   * Returns the declared methods of this class (not any superclasses or
+   * superinterfaces).
+   */
+  public abstract JMethod[] getMethods();
+
+  public abstract String getName();
+
+  public abstract JClassType getNestedType(String typeName)
+      throws NotFoundException;
+
+  public abstract JClassType[] getNestedTypes();
+
+  public abstract TypeOracle getOracle();
+
+  public abstract JMethod[] getOverloads(String name);
+
+  /**
+   * Iterates over the most-derived declaration of each unique overridable
+   * method available in the type hierarchy of the specified type, including
+   * those found in superclasses and superinterfaces. A method is overridable if
+   * it is not <code>final</code> and its accessibility is <code>public</code>,
+   * <code>protected</code>, or package protected.
+   * 
+   * Deferred binding generators often need to generate method implementations;
+   * this method offers a convenient way to find candidate methods to implement.
+   * 
+   * Note that the behavior does not match
+   * {@link Class#getMethod(String, Class[])}, which does not return the most
+   * derived method in some cases.
+   * 
+   * @return an array of {@link JMethod} objects representing overridable
+   *         methods
+   */
+  public abstract JMethod[] getOverridableMethods();
+
+  public abstract JPackage getPackage();
+
+  public String getParameterizedQualifiedSourceName() {
+    return getQualifiedSourceName();
+  }
+
+  /**
+   * TODO(scottb): remove if we can resolve param names differently.
+   */
+  public abstract String getQualifiedBinaryName();
+
+  public abstract String getQualifiedSourceName();
+
+  public abstract String getSimpleSourceName();
+
+  public abstract JClassType[] getSubtypes();
+
+  public abstract JClassType getSuperclass();
+
+  /**
+   * All types use identity for comparison.
+   */
+  @Override
+  public final int hashCode() {
+    return super.hashCode();
+  }
+
+  public abstract boolean isAbstract();
+
+  /**
+   * Returns this instance if it is a annotation or <code>null</code> if it is
+   * not.
+   * 
+   * @return this instance if it is a annotation or <code>null</code> if it is
+   *         not
+   */
+  public JAnnotationType isAnnotation() {
+    return null;
+  }
+
+  public abstract boolean isAnnotationPresent(
+      Class<? extends Annotation> annotationClass);
+
+  public abstract JArrayType isArray();
+
+  /**
+   * Returns <code>true</code> if this {@link JClassType} is assignable from the
+   * specified {@link JClassType} parameter.
+   * 
+   * @param possibleSubtype possible subtype of this {@link JClassType}
+   * @return <code>true</code> if this {@link JClassType} is assignable from the
+   *         specified {@link JClassType} parameter
+   * 
+   * @throws NullPointerException if <code>possibleSubtype</code> is
+   *           <code>null</code>
+   */
+  public boolean isAssignableFrom(
+      com.google.gwt.core.ext.typeinfo.JClassType possibleSubtype) {
+    if (possibleSubtype == null) {
+      throw new NullPointerException("possibleSubtype");
+    }
+
+    return areClassTypesAssignable(this, possibleSubtype);
+  }
+
+  /**
+   * Returns <code>true</code> if this {@link JClassType} is assignable to the
+   * specified {@link JClassType} parameter.
+   * 
+   * @param possibleSupertype possible supertype of this {@link JClassType}
+   * @return <code>true</code> if this {@link JClassType} is assignable to the
+   *         specified {@link JClassType} parameter
+   * 
+   * @throws NullPointerException if <code>possibleSupertype</code> is
+   *           <code>null</code>
+   */
+  public boolean isAssignableTo(
+      com.google.gwt.core.ext.typeinfo.JClassType possibleSupertype) {
+    if (possibleSupertype == null) {
+      throw new NullPointerException("possibleSupertype");
+    }
+
+    return areClassTypesAssignable(possibleSupertype, this);
+  }
+
+  public abstract JClassType isClass();
+
+  public JClassType isClassOrInterface() {
+    JClassType type = isClass();
+    if (type != null) {
+      return type;
+    }
+    return isInterface();
+  }
+
+  /**
+   * Determines if the class can be constructed using a simple <code>new</code>
+   * operation. Specifically, the class must
+   * <ul>
+   * <li>be a class rather than an interface,</li>
+   * <li>have either no constructors or a parameterless constructor, and</li>
+   * <li>be a top-level class or a static nested class.</li>
+   * </ul>
+   * 
+   * @return <code>true</code> if the type is default instantiable, or
+   *         <code>false</code> otherwise
+   */
+  public abstract boolean isDefaultInstantiable();
+
+  /**
+   * Returns true if the type may be enhanced on the server to contain extra
+   * fields that are unknown to client code.
+   * 
+   * @return <code>true</code> if the type might be enhanced on the server
+   */
+  public final boolean isEnhanced() {
+    return isEnhanced;
+  }
+
+  /**
+   * Returns this instance if it is an enumeration or <code>null</code> if it is
+   * not.
+   * 
+   * @return this instance if it is an enumeration or <code>null</code> if it is
+   *         not
+   */
+  public abstract JEnumType isEnum();
+
+  public abstract boolean isFinal();
+
+  public abstract JGenericType isGenericType();
+
+  public abstract JClassType isInterface();
+
+  /**
+   * @deprecated local types are not modeled
+   */
+  @Deprecated
+  public final boolean isLocalType() {
+    return false;
+  }
+
+  /**
+   * Tests if this type is contained within another type.
+   * 
+   * @return true if this type has an enclosing type, false if this type is a
+   *         top-level type
+   */
+  public abstract boolean isMemberType();
+
+  public abstract JParameterizedType isParameterized();
+
+  public abstract JPrimitiveType isPrimitive();
+
+  public abstract boolean isPrivate();
+
+  public abstract boolean isProtected();
+
+  public abstract boolean isPublic();
+
+  // TODO: Rename this to isRaw
+  public abstract JRawType isRawType();
+
+  public abstract boolean isStatic();
+
+  public JTypeParameter isTypeParameter() {
+    return null;
+  }
+
+  public abstract JWildcardType isWildcard();
+
+  /**
+   * Indicates that the type may be enhanced on the server to contain extra
+   * fields that are unknown to client code.
+   * 
+   * TODO(rice): find a better way to do this.
+   */
+  public void setEnhanced() {
+    this.isEnhanced = true;
+  }
+
+  @Override
+  public String toString() {
+    return this.getQualifiedSourceName();
+  }
+
+  protected abstract void acceptSubtype(JClassType me);
+
+  protected abstract void getInheritableMethodsOnSuperclassesAndThisClass(
+      Map<String, JMethod> methodsBySignature);
+
+  /**
+   * Gets the methods declared in interfaces that this type extends. If this
+   * type is a class, its own methods are not added. If this type is an
+   * interface, its own methods are added. Used internally by
+   * {@link #getOverridableMethods()}.
+   * 
+   * @param methodsBySignature
+   */
+  protected abstract void getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
+      Map<String, JMethod> methodsBySignature);
+
+  protected abstract int getModifierBits();
+
+  protected JMaybeParameterizedType isMaybeParameterizedType() {
+    return null;
+  }
+
+  /**
+   * Tells this type's superclasses and superinterfaces about it.
+   */
+  protected abstract void notifySuperTypesOf(JClassType me);
+
+  protected abstract void removeSubtype(JClassType me);
+
+  abstract void addConstructor(JConstructor ctor);
+
+  abstract void addField(JField field);
+
+  abstract void addImplementedInterface(JClassType intf);
+
+  abstract void addMethod(JMethod method);
+
+  abstract void addModifierBits(int bits);
+
+  abstract void addNestedType(JClassType type);
+
+  abstract JClassType findNestedTypeImpl(String[] typeName, int index);
+
+  /**
+   * Returns all of the annotations declared or inherited by this instance.
+   * 
+   * NOTE: This method is for testing purposes only.
+   */
+  abstract Annotation[] getAnnotations();
+
+  /**
+   * Returns all of the annotations declared on this instance.
+   * 
+   * NOTE: This method is for testing purposes only.
+   */
+  abstract Annotation[] getDeclaredAnnotations();
+
+  /**
+   * Returns either the substitution of this type based on the parameterized
+   * type or this instance.
+   * 
+   * @param parameterizedType
+   * @return either the substitution of this type based on the parameterized
+   *         type or this instance
+   */
+  abstract JClassType getSubstitutedType(JParameterizedType parameterizedType);
+
+  abstract void notifySuperTypes();
+
+  /**
+   * Removes references to this instance from all of its super types.
+   */
+  abstract void removeFromSupertypes();
+
+  abstract void setSuperclass(JClassType type);
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JConstructor.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JConstructor.java
new file mode 100644
index 0000000..d8ba76f
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JConstructor.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2006 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.javac.typemodel;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+/**
+ * Represents a constructor declaration.
+ */
+public class JConstructor extends JAbstractMethod implements
+    com.google.gwt.core.ext.typeinfo.JConstructor {
+  private final JClassType enclosingType;
+
+  JConstructor(JClassType enclosingType, JConstructor ctor) {
+    super(ctor);
+    this.enclosingType = enclosingType;
+  }
+
+  JConstructor(JClassType enclosingType, String name) {
+    this(enclosingType, name, null, null);
+  }
+
+  JConstructor(JClassType enclosingType, String name,
+      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
+      JTypeParameter[] jtypeParameters) {
+    super(name, declaredAnnotations, jtypeParameters);
+
+    this.enclosingType = enclosingType;
+    enclosingType.addConstructor(this);
+  }
+
+  @Override
+  public JClassType getEnclosingType() {
+    return enclosingType;
+  }
+
+  @Override
+  public String getJsniSignature() {
+    StringBuilder sb = new StringBuilder("@");
+    sb.append(getEnclosingType().getQualifiedSourceName());
+    sb.append("::new(");
+    for (JParameter param : getParameters()) {
+      sb.append(param.getType().getJNISignature());
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  @Override
+  public String getReadableDeclaration() {
+    String[] names = TypeOracle.modifierBitsToNames(getModifierBits());
+    StringBuilder sb = new StringBuilder();
+    for (String name : names) {
+      sb.append(name);
+      sb.append(" ");
+    }
+    if (getTypeParameters().length > 0) {
+      toStringTypeParams(sb);
+      sb.append(" ");
+    }
+    sb.append(getName());
+    toStringParamsAndThrows(sb);
+    return sb.toString();
+  }
+
+  @Override
+  public JConstructor isConstructor() {
+    return this;
+  }
+
+  @Override
+  public JMethod isMethod() {
+    return null;
+  }
+
+  @Override
+  public String toString() {
+    return getReadableDeclaration();
+  }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JDelegatingClassType.java
similarity index 95%
rename from dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java
rename to dev/core/src/com/google/gwt/dev/javac/typemodel/JDelegatingClassType.java
index ac22777..97a3947 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JDelegatingClassType.java
@@ -13,7 +13,11 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
 
 import java.lang.annotation.Annotation;
 import java.util.Map;
@@ -29,18 +33,6 @@
   JDelegatingClassType() {
   }
 
-  @Override
-  public final void addImplementedInterface(JClassType intf) {
-    throw new UnsupportedOperationException("modifying a "
-        + getClass().getSimpleName());
-  }
-
-  @Override
-  public final void addModifierBits(int bits) {
-    throw new UnsupportedOperationException("modifying a "
-        + getClass().getSimpleName());
-  }
-
   /**
    * Delegating types generally cannot be constructed.
    */
@@ -277,12 +269,6 @@
   }
 
   @Override
-  public void setSuperclass(JClassType type) {
-    throw new UnsupportedOperationException("modifying a "
-        + getClass().getSimpleName());
-  }
-
-  @Override
   public String toString() {
     if (baseType.isInterface() != null) {
       return "interface " + getQualifiedSourceName();
@@ -334,12 +320,24 @@
   }
 
   @Override
+  final void addImplementedInterface(JClassType intf) {
+    throw new UnsupportedOperationException("modifying a "
+        + getClass().getSimpleName());
+  }
+
+  @Override
   final void addMethod(JMethod method) {
     throw new UnsupportedOperationException("modifying a "
         + getClass().getSimpleName());
   }
 
   @Override
+  final void addModifierBits(int bits) {
+    throw new UnsupportedOperationException("modifying a "
+        + getClass().getSimpleName());
+  }
+
+  @Override
   final void addNestedType(JClassType type) {
     throw new UnsupportedOperationException("modifying a "
         + getClass().getSimpleName());
@@ -377,4 +375,10 @@
   final void setBaseType(JClassType baseType) {
     this.baseType = baseType;
   }
+
+  @Override
+  void setSuperclass(JClassType type) {
+    throw new UnsupportedOperationException("modifying a "
+        + getClass().getSimpleName());
+  }
 }
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JEnumConstant.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JEnumConstant.java
new file mode 100644
index 0000000..74b0c27
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JEnumConstant.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 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.javac.typemodel;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+/**
+ * An enumeration constant declared in an enumerated type.
+ */
+public class JEnumConstant extends JField implements
+    com.google.gwt.core.ext.typeinfo.JEnumConstant {
+  private final int ordinal;
+
+  JEnumConstant(JClassType enclosingType, String name,
+      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
+      int ordinal) {
+    super(enclosingType, name, declaredAnnotations);
+    this.ordinal = ordinal;
+  }
+
+  /**
+   * Returns the ordinal value for this enumeration constant.
+   * 
+   * @return ordinal value for this enumeration constant
+   */
+  public int getOrdinal() {
+    return ordinal;
+  }
+
+  @Override
+  public JEnumConstant isEnumConstant() {
+    return this;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JEnumType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JEnumType.java
new file mode 100644
index 0000000..468ed64
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JEnumType.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2007 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.javac.typemodel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type representing a Java enumerated type.
+ */
+public class JEnumType extends JRealClassType implements
+    com.google.gwt.core.ext.typeinfo.JEnumType {
+  private JEnumConstant[] lazyEnumConstants;
+
+  JEnumType(TypeOracle oracle, JPackage declaringPackage,
+      String enclosingTypeName, String name) {
+    super(oracle, declaringPackage, enclosingTypeName, name, false);
+  }
+
+  /**
+   * Returns the enumeration constants declared by this enumeration.
+   * 
+   * @return enumeration constants declared by this enumeration
+   */
+  public JEnumConstant[] getEnumConstants() {
+    if (lazyEnumConstants == null) {
+      List<JEnumConstant> enumConstants = new ArrayList<JEnumConstant>();
+      for (JField field : getFields()) {
+        if (field.isEnumConstant() != null) {
+          enumConstants.add(field.isEnumConstant());
+        }
+      }
+
+      lazyEnumConstants = enumConstants.toArray(new JEnumConstant[enumConstants.size()]);
+    }
+
+    return lazyEnumConstants;
+  }
+
+  @Override
+  public JEnumType isEnum() {
+    return this;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JField.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JField.java
new file mode 100644
index 0000000..f14af37
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JField.java
@@ -0,0 +1,168 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.dev.util.StringInterner;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+/**
+ * Represents a field declaration.
+ */
+public class JField implements com.google.gwt.core.ext.typeinfo.JField {
+
+  private final Annotations annotations;
+
+  private final JClassType enclosingType;
+
+  private int modifierBits;
+
+  private final String name;
+
+  private JType type;
+
+  JField(JClassType enclosingType, JField srcField) {
+    this.annotations = new Annotations(srcField.annotations);
+    this.enclosingType = enclosingType;
+    this.modifierBits = srcField.modifierBits;
+    this.name = srcField.name;
+    this.type = srcField.type;
+  }
+
+  JField(JClassType enclosingType, String name) {
+    this(enclosingType, name, null);
+  }
+
+  JField(JClassType enclosingType, String name,
+      Map<Class<? extends Annotation>, Annotation> declaredAnnotations) {
+    assert (enclosingType != null);
+    this.enclosingType = enclosingType;
+    this.name = StringInterner.get().intern(name);
+    this.enclosingType.addField(this);
+    annotations = new Annotations(declaredAnnotations);
+  }
+
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+    return annotations.getAnnotation(annotationClass);
+  }
+
+  public JClassType getEnclosingType() {
+    return enclosingType;
+  }
+
+  @Deprecated
+  public final String[][] getMetaData(String tagName) {
+    return TypeOracle.NO_STRING_ARR_ARR;
+  }
+
+  @Deprecated
+  public final String[] getMetaDataTags() {
+    return TypeOracle.NO_STRINGS;
+  }
+
+  public String getName() {
+    assert (name != null);
+    return name;
+  }
+
+  public JType getType() {
+    assert (type != null);
+    return type;
+  }
+
+  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+    return annotations.isAnnotationPresent(annotationClass);
+  }
+
+  public boolean isDefaultAccess() {
+    return 0 == (modifierBits & (TypeOracle.MOD_PUBLIC | TypeOracle.MOD_PRIVATE | TypeOracle.MOD_PROTECTED));
+  }
+
+  public JEnumConstant isEnumConstant() {
+    return null;
+  }
+
+  public boolean isFinal() {
+    return 0 != (modifierBits & TypeOracle.MOD_FINAL);
+  }
+
+  public boolean isPrivate() {
+    return 0 != (modifierBits & TypeOracle.MOD_PRIVATE);
+  }
+
+  public boolean isProtected() {
+    return 0 != (modifierBits & TypeOracle.MOD_PROTECTED);
+  }
+
+  public boolean isPublic() {
+    return 0 != (modifierBits & TypeOracle.MOD_PUBLIC);
+  }
+
+  public boolean isStatic() {
+    return 0 != (modifierBits & TypeOracle.MOD_STATIC);
+  }
+
+  public boolean isTransient() {
+    return 0 != (modifierBits & TypeOracle.MOD_TRANSIENT);
+  }
+
+  public boolean isVolatile() {
+    return 0 != (modifierBits & TypeOracle.MOD_VOLATILE);
+  }
+
+  @Override
+  public String toString() {
+    String[] names = TypeOracle.modifierBitsToNames(modifierBits);
+    StringBuffer sb = new StringBuffer();
+    for (int i = 0; i < names.length; i++) {
+      if (i > 0) {
+        sb.append(" ");
+      }
+      sb.append(names[i]);
+    }
+    if (names.length > 0) {
+      sb.append(" ");
+    }
+    sb.append(type.getParameterizedQualifiedSourceName());
+    sb.append(" ");
+    sb.append(getName());
+    return sb.toString();
+  }
+
+  void addModifierBits(int modifierBits) {
+    this.modifierBits |= modifierBits;
+  }
+
+  /**
+   * NOTE: This method is for testing purposes only.
+   */
+  Annotation[] getAnnotations() {
+    return annotations.getAnnotations();
+  }
+
+  /**
+   * NOTE: This method is for testing purposes only.
+   */
+  Annotation[] getDeclaredAnnotations() {
+    return annotations.getDeclaredAnnotations();
+  }
+
+  void setType(JType type) {
+    this.type = type;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JGenericType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JGenericType.java
new file mode 100644
index 0000000..71adee5
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JGenericType.java
@@ -0,0 +1,115 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
+import com.google.gwt.dev.util.collect.Lists;
+
+import java.util.List;
+
+/**
+ * Type declaration that has type parameters.
+ */
+public class JGenericType extends JRealClassType implements
+    com.google.gwt.core.ext.typeinfo.JGenericType {
+
+  private JRawType lazyRawType = null;
+
+  private List<JTypeParameter> typeParams = Lists.create();
+
+  public JGenericType(TypeOracle oracle, JPackage declaringPackage,
+      String enclosingTypeName, String name, boolean isInterface,
+      JTypeParameter[] jtypeParameters) {
+    super(oracle, declaringPackage, enclosingTypeName, name, isInterface);
+
+    if (jtypeParameters != null) {
+      for (JTypeParameter jtypeParameter : jtypeParameters) {
+        addTypeParameter(jtypeParameter);
+      }
+    }
+  }
+
+  public JParameterizedType asParameterizedByWildcards() {
+    JClassType[] typeArgs = new JClassType[typeParams.size()];
+    for (int i = 0; i < typeArgs.length; ++i) {
+      typeArgs[i] = getOracle().getWildcardType(BoundType.EXTENDS,
+          typeParams.get(i).getFirstBound());
+    }
+    return getOracle().getParameterizedType(this, typeArgs);
+  }
+
+  @Override
+  public JClassType getErasedType() {
+    return getRawType();
+  }
+
+  @Override
+  public String getParameterizedQualifiedSourceName() {
+    StringBuffer sb = new StringBuffer();
+
+    if (getEnclosingType() != null) {
+      sb.append(getEnclosingType().getParameterizedQualifiedSourceName());
+      sb.append(".");
+      sb.append(getSimpleSourceName());
+    } else {
+      sb.append(getQualifiedSourceName());
+    }
+
+    sb.append('<');
+    boolean needComma = false;
+    for (JClassType typeParam : typeParams) {
+      if (needComma) {
+        sb.append(", ");
+      } else {
+        needComma = true;
+      }
+      sb.append(typeParam.getParameterizedQualifiedSourceName());
+    }
+    sb.append('>');
+    return sb.toString();
+  }
+
+  public JRawType getRawType() {
+    if (lazyRawType == null) {
+      lazyRawType = new JRawType(this);
+    }
+
+    return lazyRawType;
+  }
+
+  public JTypeParameter[] getTypeParameters() {
+    return typeParams.toArray(new JTypeParameter[typeParams.size()]);
+  }
+
+  @Override
+  public JGenericType isGenericType() {
+    return this;
+  }
+
+  @Override
+  public String toString() {
+    if (isInterface() != null) {
+      return "interface " + getParameterizedQualifiedSourceName();
+    }
+
+    return "class " + getParameterizedQualifiedSourceName();
+  }
+
+  private void addTypeParameter(JTypeParameter typeParameter) {
+    typeParams = Lists.add(typeParams, typeParameter);
+    typeParameter.setDeclaringClass(this);
+  }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JMaybeParameterizedType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JMaybeParameterizedType.java
similarity index 95%
rename from dev/core/src/com/google/gwt/core/ext/typeinfo/JMaybeParameterizedType.java
rename to dev/core/src/com/google/gwt/dev/javac/typemodel/JMaybeParameterizedType.java
index ee130ef..fe1e0a1 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JMaybeParameterizedType.java
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JMaybeParameterizedType.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 /**
  * Super class for parameterized types or raw types.
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JMethod.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JMethod.java
new file mode 100644
index 0000000..c87476e
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JMethod.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2007 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+/**
+ * Represents a method declaration.
+ */
+public class JMethod extends JAbstractMethod implements
+    com.google.gwt.core.ext.typeinfo.JMethod {
+
+  private final JClassType enclosingType;
+
+  private JType returnType;
+
+  JMethod(JClassType enclosingType, JMethod srcMethod) {
+    super(srcMethod);
+    this.enclosingType = enclosingType;
+    this.returnType = srcMethod.returnType;
+  }
+
+  JMethod(JClassType enclosingType, String name) {
+    this(enclosingType, name, null, null);
+  }
+
+  JMethod(JClassType enclosingType, String name,
+      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
+      JTypeParameter[] jtypeParameters) {
+    super(name, declaredAnnotations, jtypeParameters);
+    this.enclosingType = enclosingType;
+    enclosingType.addMethod(this);
+  }
+
+  @Override
+  public JClassType getEnclosingType() {
+    return enclosingType;
+  }
+
+  @Override
+  public String getJsniSignature() {
+    StringBuilder sb = new StringBuilder("@");
+    sb.append(getEnclosingType().getQualifiedSourceName());
+    sb.append("::");
+    sb.append(getName());
+    sb.append("(");
+    for (JParameter param : getParameters()) {
+      sb.append(param.getType().getJNISignature());
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  @Override
+  public String getReadableDeclaration() {
+    return getReadableDeclaration(getModifierBits());
+  }
+
+  public String getReadableDeclaration(boolean noAccess, boolean noNative,
+      boolean noStatic, boolean noFinal, boolean noAbstract) {
+    int bits = getModifierBits();
+    if (noAccess) {
+      bits &= ~(TypeOracle.MOD_PUBLIC | TypeOracle.MOD_PRIVATE | TypeOracle.MOD_PROTECTED);
+    }
+    if (noNative) {
+      bits &= ~TypeOracle.MOD_NATIVE;
+    }
+    if (noStatic) {
+      bits &= ~TypeOracle.MOD_STATIC;
+    }
+    if (noFinal) {
+      bits &= ~TypeOracle.MOD_FINAL;
+    }
+    if (noAbstract) {
+      bits &= ~TypeOracle.MOD_ABSTRACT;
+    }
+    return getReadableDeclaration(bits);
+  }
+
+  public JType getReturnType() {
+    return returnType;
+  }
+
+  public boolean isAbstract() {
+    return 0 != (getModifierBits() & TypeOracle.MOD_ABSTRACT);
+  }
+
+  @Override
+  public JConstructor isConstructor() {
+    return null;
+  }
+
+  public boolean isFinal() {
+    return 0 != (getModifierBits() & TypeOracle.MOD_FINAL);
+  }
+
+  @Override
+  public JMethod isMethod() {
+    return this;
+  }
+
+  public boolean isNative() {
+    return 0 != (getModifierBits() & TypeOracle.MOD_NATIVE);
+  }
+
+  public boolean isStatic() {
+    return 0 != (getModifierBits() & TypeOracle.MOD_STATIC);
+  }
+
+  @Override
+  public String toString() {
+    return getReadableDeclaration();
+  }
+
+  String getReadableDeclaration(int modifierBits) {
+    String[] names = TypeOracle.modifierBitsToNames(modifierBits);
+    StringBuilder sb = new StringBuilder();
+    for (String name : names) {
+      sb.append(name);
+      sb.append(" ");
+    }
+    if (getTypeParameters().length > 0) {
+      toStringTypeParams(sb);
+      sb.append(" ");
+    }
+    sb.append(returnType.getParameterizedQualifiedSourceName());
+    sb.append(" ");
+    sb.append(getName());
+
+    toStringParamsAndThrows(sb);
+
+    return sb.toString();
+  }
+
+  void setReturnType(JType type) {
+    returnType = type;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JPackage.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JPackage.java
new file mode 100644
index 0000000..edf9cc8
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JPackage.java
@@ -0,0 +1,99 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.util.collect.Maps;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+/**
+ * Represents a logical package.
+ */
+public class JPackage implements com.google.gwt.core.ext.typeinfo.JPackage {
+
+  private final Annotations annotations = new Annotations();
+
+  private final String name;
+
+  private Map<String, JRealClassType> types = Maps.create();
+
+  JPackage(String name) {
+    this.name = name;
+  }
+
+  public JClassType findType(String typeName) {
+    String[] parts = typeName.split("\\.");
+    return findType(parts);
+  }
+
+  public JClassType findType(String[] typeName) {
+    return findTypeImpl(typeName, 0);
+  }
+
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+    return annotations.getAnnotation(annotationClass);
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public JClassType getType(String typeName) throws NotFoundException {
+    JClassType result = findType(typeName);
+    if (result == null) {
+      throw new NotFoundException();
+    }
+    return result;
+  }
+
+  public JClassType[] getTypes() {
+    return types.values().toArray(TypeOracle.NO_JCLASSES);
+  }
+
+  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+    return annotations.isAnnotationPresent(annotationClass);
+  }
+
+  public boolean isDefault() {
+    return "".equals(name);
+  }
+
+  @Override
+  public String toString() {
+    return "package " + name;
+  }
+
+  void addAnnotations(Map<Class<? extends Annotation>, Annotation> annotations) {
+    this.annotations.addAnnotations(annotations);
+  }
+
+  void addType(JRealClassType type) {
+    types = Maps.put(types, type.getSimpleSourceName(), type);
+  }
+
+  JClassType findTypeImpl(String[] typeName, int index) {
+    JClassType found = types.get(typeName[index]);
+    if (found == null) {
+      return null;
+    } else if (index < typeName.length - 1) {
+      return found.findNestedTypeImpl(typeName, index + 1);
+    } else {
+      return found;
+    }
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JParameter.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JParameter.java
new file mode 100644
index 0000000..f781132
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JParameter.java
@@ -0,0 +1,134 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.dev.util.StringInterner;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+/**
+ * Represents a parameter in a declaration.
+ */
+public class JParameter implements com.google.gwt.core.ext.typeinfo.JParameter {
+
+  private final Annotations annotations;
+
+  private boolean argNameIsReal;
+
+  private final JAbstractMethod enclosingMethod;
+
+  private String name;
+
+  private JType type;
+
+  JParameter(JAbstractMethod enclosingMethod, JParameter srcParam) {
+    this.enclosingMethod = enclosingMethod;
+    this.type = srcParam.type;
+    this.name = StringInterner.get().intern(srcParam.name);
+    this.annotations = new Annotations(srcParam.annotations);
+  }
+
+  JParameter(JAbstractMethod enclosingMethod, JType type, String name) {
+    this(enclosingMethod, type, name, null);
+  }
+
+  JParameter(JAbstractMethod enclosingMethod, JType type, String name,
+      Map<Class<? extends Annotation>, Annotation> declaredAnnotations) {
+    this(enclosingMethod, type, name, declaredAnnotations, true);
+  }
+
+  JParameter(JAbstractMethod enclosingMethod, JType type, String name,
+      Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
+      boolean argNameIsReal) {
+    this.enclosingMethod = enclosingMethod;
+    this.type = type;
+    this.name = StringInterner.get().intern(name);
+    this.argNameIsReal = argNameIsReal;
+
+    enclosingMethod.addParameter(this);
+
+    annotations = new Annotations(declaredAnnotations);
+  }
+
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+    return annotations.getAnnotation(annotationClass);
+  }
+
+  public JAbstractMethod getEnclosingMethod() {
+    return enclosingMethod;
+  }
+
+  @Deprecated
+  public final String[][] getMetaData(String tagName) {
+    return TypeOracle.NO_STRING_ARR_ARR;
+  }
+
+  @Deprecated
+  public final String[] getMetaDataTags() {
+    return TypeOracle.NO_STRINGS;
+  }
+
+  public String getName() {
+    if (!argNameIsReal) {
+      name = enclosingMethod.getRealParameterName(this);
+      argNameIsReal = true;
+    }
+    return name;
+  }
+
+  public JType getType() {
+    return type;
+  }
+
+  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+    return annotations.isAnnotationPresent(annotationClass);
+  }
+
+  @Override
+  public String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.append(type.getParameterizedQualifiedSourceName());
+    sb.append(" ");
+    sb.append(getName());
+    return sb.toString();
+  }
+
+  /**
+   * NOTE: This method is for testing purposes only.
+   */
+  Annotation[] getAnnotations() {
+    return annotations.getAnnotations();
+  }
+
+  /**
+   * NOTE: This method is for testing purposes only.
+   */
+  Annotation[] getDeclaredAnnotations() {
+    return annotations.getDeclaredAnnotations();
+  }
+
+  // Only called by JAbstractMethod after real parameter names are fetched.
+  void setName(String name) {
+    this.name = StringInterner.get().intern(name);
+  }
+
+  // Called when parameter types are found to be parameterized
+  void setType(JType type) {
+    this.type = type;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JParameterizedType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JParameterizedType.java
new file mode 100644
index 0000000..f6b98eb
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JParameterizedType.java
@@ -0,0 +1,546 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
+import com.google.gwt.dev.util.collect.IdentityHashMap;
+import com.google.gwt.dev.util.collect.Lists;
+import com.google.gwt.dev.util.collect.Maps;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents a parameterized type in a declaration.
+ */
+public class JParameterizedType extends JMaybeParameterizedType implements
+    com.google.gwt.core.ext.typeinfo.JParameterizedType {
+  /**
+   * Create a parameterized type along with any necessary enclosing
+   * parameterized types. Enclosing parameterized types are necessary when the
+   * base type is a non-static member and the enclosing type is also generic.
+   */
+  private static JParameterizedType createParameterizedTypeRecursive(
+      JGenericType baseType, Map<JTypeParameter, JClassType> substitutionMap) {
+    JClassType enclosingType = baseType.getEnclosingType();
+    if (baseType.isMemberType() && !baseType.isStatic()) {
+      // This base type is a non-static generic type so we build the necessary
+      // enclosing parameterized type and update the enclosing type to be
+      // a parameterized type.
+      JGenericType isGenericEnclosingType = enclosingType.isGenericType();
+      if (isGenericEnclosingType != null) {
+        enclosingType = createParameterizedTypeRecursive(
+            isGenericEnclosingType, substitutionMap);
+      }
+    }
+
+    JTypeParameter[] typeParameters = baseType.getTypeParameters();
+    JClassType[] newTypeArgs = new JClassType[typeParameters.length];
+    TypeOracle oracle = baseType.getOracle();
+    for (int i = 0; i < newTypeArgs.length; ++i) {
+      JClassType newTypeArg = substitutionMap.get(typeParameters[i]);
+      if (newTypeArg == null) {
+        newTypeArg = oracle.getWildcardType(BoundType.EXTENDS,
+            typeParameters[i].getFirstBound());
+      }
+
+      newTypeArgs[i] = newTypeArg;
+    }
+
+    JParameterizedType parameterizedType = oracle.getParameterizedType(
+        baseType, enclosingType, newTypeArgs);
+    return parameterizedType;
+  }
+
+  private final JClassType enclosingType;
+
+  private List<JClassType> interfaces;
+
+  /**
+   * This map records the JClassType that should be used in place of a given
+   * {@link JTypeParameter}.
+   */
+  private Map<JTypeParameter, JClassType> lazySubstitutionMap;
+
+  private JClassType lazySuperclass;
+
+  private final AbstractMembers members;
+
+  private final List<JClassType> typeArgs;
+
+  JParameterizedType(JGenericType baseType, JClassType enclosingType,
+      JClassType[] typeArgs) {
+    super.setBaseType(baseType);
+
+    this.enclosingType = enclosingType;
+
+    // NOTE: this instance is not considered a nested type of the enclosing type
+
+    final JParameterizedType parameterizedType = this;
+    members = new DelegateMembers(this, baseType, new Substitution() {
+      public JClassType getSubstitution(JClassType type) {
+        return type.getSubstitutedType(parameterizedType);
+      }
+    });
+
+    this.typeArgs = Lists.create(typeArgs);
+    assert (this.typeArgs.indexOf(null) == -1) : "Unresolved typeArg creating JParameterizedType from "
+        + baseType;
+
+    // NOTE: Can't perform substitutions until we are done building
+  }
+
+  @Override
+  public JConstructor findConstructor(JType[] paramTypes) {
+    return members.findConstructor(paramTypes);
+  }
+
+  @Override
+  public JField findField(String name) {
+    return members.findField(name);
+  }
+
+  @Override
+  public JMethod findMethod(String name, JType[] paramTypes) {
+    return members.findMethod(name, paramTypes);
+  }
+
+  @Override
+  public JClassType findNestedType(String typeName) {
+    return members.findNestedType(typeName);
+  }
+
+  @Override
+  public JConstructor getConstructor(JType[] paramTypes)
+      throws NotFoundException {
+    return members.getConstructor(paramTypes);
+  }
+
+  @Override
+  public JConstructor[] getConstructors() {
+    return members.getConstructors();
+  }
+
+  @Override
+  public JClassType getEnclosingType() {
+    return enclosingType;
+  }
+
+  @Override
+  public JField getField(String name) {
+    return members.getField(name);
+  }
+
+  @Override
+  public JField[] getFields() {
+    return members.getFields();
+  }
+
+  @Override
+  public JClassType[] getImplementedInterfaces() {
+    if (interfaces == null) {
+      interfaces = new ArrayList<JClassType>();
+      JClassType[] intfs = getBaseType().getImplementedInterfaces();
+      for (JClassType intf : intfs) {
+        JClassType newIntf = intf.getSubstitutedType(this);
+        interfaces.add(newIntf);
+      }
+      interfaces = Lists.normalize(interfaces);
+    }
+    return interfaces.toArray(TypeOracle.NO_JCLASSES);
+  }
+
+  @Override
+  public JMethod[] getInheritableMethods() {
+    return members.getInheritableMethods();
+  }
+
+  @Override
+  public JMethod getMethod(String name, JType[] paramTypes)
+      throws NotFoundException {
+    return members.getMethod(name, paramTypes);
+  }
+
+  @Override
+  public JMethod[] getMethods() {
+    return members.getMethods();
+  }
+
+  @Override
+  public JClassType getNestedType(String typeName) throws NotFoundException {
+    return members.getNestedType(typeName);
+  }
+
+  @Override
+  public JClassType[] getNestedTypes() {
+    return members.getNestedTypes();
+  }
+
+  /**
+   * @deprecated See {@link #getQualifiedSourceName()}
+   */
+  @Deprecated
+  public String getNonParameterizedQualifiedSourceName() {
+    return getQualifiedSourceName();
+  }
+
+  @Override
+  public JMethod[] getOverloads(String name) {
+    return members.getOverloads(name);
+  }
+
+  @Override
+  public JMethod[] getOverridableMethods() {
+    return members.getOverridableMethods();
+  }
+
+  @Override
+  public String getParameterizedQualifiedSourceName() {
+    StringBuffer sb = new StringBuffer();
+
+    if (getEnclosingType() != null) {
+      sb.append(getEnclosingType().getParameterizedQualifiedSourceName());
+      sb.append(".");
+      sb.append(getSimpleSourceName());
+    } else {
+      sb.append(getQualifiedSourceName());
+    }
+
+    if (typeArgs.size() > 0) {
+      sb.append('<');
+      boolean needComma = false;
+      for (JType typeArg : typeArgs) {
+        if (needComma) {
+          sb.append(", ");
+        } else {
+          needComma = true;
+        }
+        sb.append(typeArg.getParameterizedQualifiedSourceName());
+      }
+      sb.append('>');
+    } else {
+      /*
+       * Non-static, inner classes of generic types are modeled as generic, even
+       * if they do not declare type parameters or reference the type parameters
+       * of their enclosing generic type.
+       */
+    }
+
+    return sb.toString();
+  }
+
+  @Override
+  public String getQualifiedBinaryName() {
+    return getBaseType().getQualifiedBinaryName();
+  }
+
+  /**
+   * Everything is fully qualified and includes the &lt; and &gt; in the
+   * signature.
+   */
+  @Override
+  public String getQualifiedSourceName() {
+    return getBaseType().getQualifiedSourceName();
+  }
+
+  public JClassType getRawType() {
+    return getBaseType().getRawType();
+  }
+
+  /**
+   * In this case, the raw type name.
+   */
+  @Override
+  public String getSimpleSourceName() {
+    return getBaseType().getSimpleSourceName();
+  }
+
+  /*
+   * Goal: Return a list of possible subtypes of this parameterized type. In the
+   * event that we have generic subtypes and we cannot resolve the all of the
+   * type arguments, we need to wildcard types in place of the arguments that we
+   * cannot resolve.
+   * 
+   * Algorithm: - Ask generic type for its subtypes - Filter subtypes of the
+   * generic which cannot be our subtype.
+   */
+  @Override
+  public JClassType[] getSubtypes() {
+    List<JClassType> subtypeList = new ArrayList<JClassType>();
+
+    // Parameterized types are not tracked in the subtype hierarchy; ask base
+    // type
+    JClassType[] genericSubtypes = getBaseType().getSubtypes();
+    for (JClassType subtype : genericSubtypes) {
+      // Could be a subtype depending on how it is substituted
+      Map<JTypeParameter, JClassType> substitutions = findSubtypeSubstitution(subtype);
+      if (substitutions != null) {
+        JGenericType genericType = subtype.isGenericType();
+        if (genericType != null) {
+          subtype = createParameterizedTypeRecursive(genericType, substitutions);
+        } else {
+          // If this is not a generic type then there should not be any
+          // substitution.
+          assert (substitutions.isEmpty());
+        }
+
+        subtypeList.add(subtype);
+      }
+    }
+
+    return subtypeList.toArray(TypeOracle.NO_JCLASSES);
+  }
+
+  @Override
+  public JClassType getSuperclass() {
+    if (isInterface() != null) {
+      return null;
+    }
+
+    if (lazySuperclass == null) {
+      JGenericType baseType = getBaseType();
+      JClassType superclass = baseType.getSuperclass();
+      assert (superclass != null);
+      lazySuperclass = superclass.getSubstitutedType(this);
+    }
+
+    return lazySuperclass;
+  }
+
+  public JClassType[] getTypeArgs() {
+    return typeArgs.toArray(TypeOracle.NO_JCLASSES);
+  }
+
+  @Override
+  public JGenericType isGenericType() {
+    return null;
+  }
+
+  @Override
+  public JParameterizedType isParameterized() {
+    return this;
+  }
+
+  @Override
+  public JRawType isRawType() {
+    return null;
+  }
+
+  @Override
+  public JWildcardType isWildcard() {
+    return null;
+  }
+
+  @Override
+  public String toString() {
+    if (isInterface() != null) {
+      return "interface " + getParameterizedQualifiedSourceName();
+    }
+
+    return "class " + getParameterizedQualifiedSourceName();
+  }
+
+  @Override
+  protected JClassType findNestedTypeImpl(String[] typeName, int index) {
+    return members.findNestedTypeImpl(typeName, index);
+  }
+
+  @Override
+  protected void getInheritableMethodsOnSuperclassesAndThisClass(
+      Map<String, JMethod> methodsBySignature) {
+    members.getInheritableMethodsOnSuperclassesAndThisClass(methodsBySignature);
+  }
+
+  /**
+   * Gets the methods declared in interfaces that this type extends. If this
+   * type is a class, its own methods are not added. If this type is an
+   * interface, its own methods are added. Used internally by
+   * {@link #getOverridableMethods()}.
+   * 
+   * @param methodsBySignature
+   */
+  @Override
+  protected void getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
+      Map<String, JMethod> methodsBySignature) {
+    members.getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
+  }
+
+  @Override
+  JClassType getSubstitutedType(JParameterizedType parameterizedType) {
+    maybeInitializeTypeParameterSubstitutionMap();
+
+    if (this == parameterizedType) {
+      return this;
+    }
+
+    JClassType[] newTypeArgs = new JClassType[typeArgs.size()];
+    for (int i = 0; i < newTypeArgs.length; ++i) {
+      newTypeArgs[i] = typeArgs.get(i).getSubstitutedType(parameterizedType);
+    }
+
+    return getOracle().getParameterizedType(getBaseType(), getEnclosingType(),
+        newTypeArgs);
+  }
+
+  /**
+   * Returns the {@link JClassType} that is a substitute for the given
+   * {@link JTypeParameter}. If there is no substitution, the original
+   * {@link JTypeParameter} is returned.
+   */
+  JClassType getTypeParameterSubstitution(JTypeParameter typeParameter) {
+    maybeInitializeTypeParameterSubstitutionMap();
+
+    JClassType substitute = lazySubstitutionMap.get(typeParameter);
+    if (substitute != null) {
+      return substitute;
+    }
+
+    return typeParameter;
+  }
+
+  boolean hasTypeArgs(JClassType[] otherArgTypes) {
+    if (otherArgTypes.length != typeArgs.size()) {
+      return false;
+    }
+
+    for (int i = 0; i < otherArgTypes.length; ++i) {
+      // Identity tests are ok since identity is durable within an oracle.
+      //
+      if (otherArgTypes[i] != typeArgs.get(i)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * Initialize a map of substitutions for {@link JTypeParameter}s to
+   * corresponding {@link JClassType}s. This can only be initialized after the
+   * {@link com.google.gwt.dev.javac.TypeOracleMediator TypeOracleMediator} has
+   * fully resolved all of the {@link JClassType}s.
+   */
+  void maybeInitializeTypeParameterSubstitutionMap() {
+    if (lazySubstitutionMap != null) {
+      return;
+    }
+    lazySubstitutionMap = new IdentityHashMap<JTypeParameter, JClassType>();
+
+    JParameterizedType currentParameterizedType = this;
+
+    while (currentParameterizedType != null) {
+      JGenericType genericType = currentParameterizedType.getBaseType();
+      JTypeParameter[] typeParameters = genericType.getTypeParameters();
+      JClassType[] typeArguments = currentParameterizedType.getTypeArgs();
+
+      for (JTypeParameter typeParameter : typeParameters) {
+        lazySubstitutionMap.put(typeParameter,
+            typeArguments[typeParameter.getOrdinal()]);
+      }
+
+      if (currentParameterizedType.isStatic()) {
+        break;
+      }
+
+      JClassType maybeParameterizedType = currentParameterizedType.getEnclosingType();
+      if (maybeParameterizedType == null
+          || maybeParameterizedType.isParameterized() == null) {
+        break;
+      }
+      currentParameterizedType = maybeParameterizedType.isParameterized();
+    }
+    lazySubstitutionMap = Maps.normalize(lazySubstitutionMap);
+  }
+
+  void setTypeArguments(JClassType[] typeArgs) {
+    this.typeArgs.addAll(Arrays.asList(typeArgs));
+  }
+
+  /**
+   * Returns a map of substitutions that will make the subtype a proper subtype
+   * of this parameterized type. The map maybe empty in the case that it is
+   * already an exact subtype.
+   */
+  private Map<JTypeParameter, JClassType> findSubtypeSubstitution(
+      JClassType subtype) {
+    Map<JTypeParameter, JClassType> substitutions = new IdentityHashMap<JTypeParameter, JClassType>();
+
+    // Get the supertype hierarchy. If this JParameterizedType exists
+    // exactly in this set we are done.
+    Set<JClassType> supertypeHierarchy = getFlattenedSuperTypeHierarchy(subtype);
+    if (supertypeHierarchy.contains(this)) {
+      return substitutions;
+    }
+
+    /*
+     * Try to find a parameterized supertype whose base type is the same as our
+     * own. Because that parameterized supertype might be made into ourself via
+     * substitution.
+     */
+    for (JClassType candidate : supertypeHierarchy) {
+      JParameterizedType parameterizedCandidate = candidate.isParameterized();
+      if (parameterizedCandidate == null) {
+        // If not parameterized then there is no substitution possible.
+        continue;
+      }
+
+      if (parameterizedCandidate.getBaseType() != getBaseType()) {
+        // This candidate be parameterized to us.
+        continue;
+      }
+
+      /*
+       * We have a parameterization of our base type. Now we need to see if it
+       * is possible to parameterize subtype such that candidate becomes
+       * equivalent to us.
+       */
+      JClassType[] candidateTypeArgs = parameterizedCandidate.getTypeArgs();
+      JClassType[] myTypeArgs = getTypeArgs();
+      for (int i = 0; i < myTypeArgs.length; ++i) {
+        JClassType otherTypeArg = candidateTypeArgs[i];
+        JClassType myTypeArg = myTypeArgs[i];
+
+        if (myTypeArg == otherTypeArg) {
+          // There are identical so there is no substitution that is needed.
+          continue;
+        }
+
+        JTypeParameter otherTypeParameter = otherTypeArg.isTypeParameter();
+        if (otherTypeParameter == null) {
+          // Not a type parameter and not equal so no substitution can make it
+          // equal.
+          return null;
+        }
+
+        if (!otherTypeParameter.isAssignableFrom(myTypeArg)) {
+          // Make sure that my type argument can be substituted for this type
+          // parameter.
+          return null;
+        }
+
+        substitutions.put(otherTypeParameter, myTypeArg);
+      }
+    }
+
+    // Legal substitution can be made and is record in substitutions.
+    return substitutions;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JRawType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JRawType.java
new file mode 100644
index 0000000..4770000
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JRawType.java
@@ -0,0 +1,215 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a raw type; that is a generic type with no type arguments.
+ */
+public class JRawType extends JMaybeParameterizedType implements
+    com.google.gwt.core.ext.typeinfo.JRawType {
+  private static final Substitution ERASURE_SUBSTITUTION = new Substitution() {
+    public JClassType getSubstitution(JClassType type) {
+      return type.getErasedType();
+    }
+  };
+
+  private List<JClassType> interfaces;
+
+  private final AbstractMembers members;
+
+  JRawType(JGenericType genericType) {
+    super.setBaseType(genericType);
+    members = new DelegateMembers(this, getBaseType(), ERASURE_SUBSTITUTION);
+  }
+
+  public JParameterizedType asParameterizedByWildcards() {
+    return getBaseType().asParameterizedByWildcards();
+  }
+
+  @Override
+  public JConstructor findConstructor(JType[] paramTypes) {
+    return members.findConstructor(paramTypes);
+  }
+
+  @Override
+  public JField findField(String name) {
+    return members.findField(name);
+  }
+
+  @Override
+  public JMethod findMethod(String name, JType[] paramTypes) {
+    return members.findMethod(name, paramTypes);
+  }
+
+  @Override
+  public JClassType findNestedType(String typeName) {
+    return members.findNestedType(typeName);
+  }
+
+  @Override
+  public JConstructor getConstructor(JType[] paramTypes)
+      throws NotFoundException {
+    return members.getConstructor(paramTypes);
+  }
+
+  @Override
+  public JConstructor[] getConstructors() {
+    return members.getConstructors();
+  }
+
+  @Override
+  public JField getField(String name) {
+    return members.getField(name);
+  }
+
+  @Override
+  public JField[] getFields() {
+    return members.getFields();
+  }
+
+  public JGenericType getGenericType() {
+    return getBaseType();
+  }
+
+  @Override
+  public JClassType[] getImplementedInterfaces() {
+    if (interfaces == null) {
+      interfaces = new ArrayList<JClassType>();
+      JClassType[] intfs = getBaseType().getImplementedInterfaces();
+      for (JClassType intf : intfs) {
+        JClassType newIntf = intf.getErasedType();
+        interfaces.add(newIntf);
+      }
+    }
+    return interfaces.toArray(TypeOracle.NO_JCLASSES);
+  }
+
+  @Override
+  public JMethod[] getInheritableMethods() {
+    return members.getInheritableMethods();
+  }
+
+  @Override
+  public JMethod getMethod(String name, JType[] paramTypes)
+      throws NotFoundException {
+    return members.getMethod(name, paramTypes);
+  }
+
+  @Override
+  public JMethod[] getMethods() {
+    return members.getMethods();
+  }
+
+  @Override
+  public JClassType getNestedType(String typeName) throws NotFoundException {
+    return members.getNestedType(typeName);
+  }
+
+  @Override
+  public JClassType[] getNestedTypes() {
+    return members.getNestedTypes();
+  }
+
+  @Override
+  public JMethod[] getOverloads(String name) {
+    return members.getOverloads(name);
+  }
+
+  @Override
+  public JMethod[] getOverridableMethods() {
+    return members.getOverridableMethods();
+  }
+
+  @Override
+  public String getParameterizedQualifiedSourceName() {
+    return getQualifiedSourceName();
+  }
+
+  @Override
+  public String getQualifiedBinaryName() {
+    return getBaseType().getQualifiedBinaryName();
+  }
+
+  @Override
+  public String getQualifiedSourceName() {
+    return getBaseType().getQualifiedSourceName();
+  }
+
+  @Override
+  public String getSimpleSourceName() {
+    return getBaseType().getSimpleSourceName();
+  }
+
+  @Override
+  public JClassType[] getSubtypes() {
+    JClassType[] baseSubTypes = super.getSubtypes();
+    JClassType[] rawSubTypes = new JClassType[baseSubTypes.length];
+    for (int i = 0; i < baseSubTypes.length; ++i) {
+      JClassType subType = baseSubTypes[i];
+      JGenericType isGenericType = subType.isGenericType();
+      if (isGenericType != null) {
+        rawSubTypes[i] = isGenericType.getRawType();
+      } else {
+        rawSubTypes[i] = subType;
+      }
+    }
+    return rawSubTypes;
+  }
+
+  @Override
+  public JClassType getSuperclass() {
+    JClassType baseSuper = getBaseType().getSuperclass();
+    if (baseSuper == null) {
+      return null;
+    }
+
+    return baseSuper.getErasedType();
+  }
+
+  @Override
+  public JGenericType isGenericType() {
+    return null;
+  }
+
+  @Override
+  public JParameterizedType isParameterized() {
+    return null;
+  }
+
+  @Override
+  public JRawType isRawType() {
+    return this;
+  }
+
+  @Override
+  public JWildcardType isWildcard() {
+    return null;
+  }
+
+  @Override
+  JRawType getSubstitutedType(JParameterizedType parameterizedType) {
+    /*
+     * Raw types do not participate in substitution.
+     */
+    return this;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JRealClassType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JRealClassType.java
new file mode 100644
index 0000000..9be9b78
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JRealClassType.java
@@ -0,0 +1,568 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.util.StringInterner;
+import com.google.gwt.dev.util.collect.IdentitySets;
+import com.google.gwt.dev.util.collect.Lists;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Type representing a Java class or interface type that a user would declare.
+ */
+public class JRealClassType extends JClassType implements
+    com.google.gwt.core.ext.typeinfo.JRealClassType {
+
+  private Set<JClassType> allSubtypes = IdentitySets.create();
+
+  private final Annotations annotations = new Annotations();
+
+  private final JPackage declaringPackage;
+
+  /**
+   * Set when this class is resolved, then never modified.
+   */
+  private JClassType enclosingType;
+
+  private List<JClassType> interfaces = Lists.create();
+
+  private final boolean isInterface;
+
+  private String lazyQualifiedBinaryName;
+
+  private String lazyQualifiedName;
+
+  private final Members members = new Members(this);
+
+  private int modifierBits;
+
+  private final String name;
+
+  private final String nestedName;
+
+  private final TypeOracle oracle;
+
+  private JClassType superclass;
+
+  /**
+   * Create a class type that reflects an actual type.
+   * 
+   * @param oracle
+   * @param declaringPackage
+   * @param enclosingTypeName the fully qualified source name of the enclosing
+   *          class or null if a top-level class - setEnclosingType must be
+   *          called later with the proper enclosing type if this is non-null
+   * @param isLocalType
+   * @param name
+   * @param isInterface
+   */
+  JRealClassType(TypeOracle oracle, JPackage declaringPackage,
+      String enclosingTypeName, String name, boolean isInterface) {
+    this.oracle = oracle;
+    this.declaringPackage = declaringPackage;
+    this.name = StringInterner.get().intern(name);
+    this.isInterface = isInterface;
+    if (enclosingTypeName == null) {
+      // Add myself to my package.
+      //
+      declaringPackage.addType(this);
+      // The nested name of a top-level class is its simple name.
+      //
+      nestedName = name;
+    } else {
+      // Compute my "nested name".
+      //
+      nestedName = enclosingTypeName + "." + name;
+
+      // We will add ourselves to the enclosing class when it is set in
+      // setEnclosingType().
+    }
+    oracle.addNewType(this);
+  }
+
+  @Override
+  public void addModifierBits(int bits) {
+    modifierBits |= bits;
+  }
+
+  @Override
+  public JConstructor findConstructor(JType[] paramTypes) {
+    return members.findConstructor(paramTypes);
+  }
+
+  @Override
+  public JField findField(String name) {
+    return members.findField(name);
+  }
+
+  @Override
+  public JMethod findMethod(String name, JType[] paramTypes) {
+    return members.findMethod(name, paramTypes);
+  }
+
+  @Override
+  public JClassType findNestedType(String typeName) {
+    return members.findNestedType(typeName);
+  }
+
+  @Override
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+    return annotations.getAnnotation(annotationClass);
+  }
+
+  @Override
+  public JConstructor getConstructor(JType[] paramTypes)
+      throws NotFoundException {
+    return members.getConstructor(paramTypes);
+  }
+
+  @Override
+  public JConstructor[] getConstructors() {
+    return members.getConstructors();
+  }
+
+  @Override
+  public JClassType getEnclosingType() {
+    return enclosingType;
+  }
+
+  @Override
+  public JClassType getErasedType() {
+    return this;
+  }
+
+  @Override
+  public JField getField(String name) {
+    return members.getField(name);
+  }
+
+  @Override
+  public JField[] getFields() {
+    return members.getFields();
+  }
+
+  @Override
+  public JClassType[] getImplementedInterfaces() {
+    return interfaces.toArray(TypeOracle.NO_JCLASSES);
+  }
+
+  @Override
+  public JMethod[] getInheritableMethods() {
+    return members.getInheritableMethods();
+  }
+
+  @Override
+  public String getJNISignature() {
+    String typeName = nestedName.replace('.', '$');
+    String packageName = getPackage().getName().replace('.', '/');
+    if (packageName.length() > 0) {
+      packageName += "/";
+    }
+    return "L" + packageName + typeName + ";";
+  }
+
+  @Override
+  public JMethod getMethod(String name, JType[] paramTypes)
+      throws NotFoundException {
+    return members.getMethod(name, paramTypes);
+  }
+
+  @Override
+  public JMethod[] getMethods() {
+    return members.getMethods();
+  }
+
+  @Override
+  public String getName() {
+    return nestedName;
+  }
+
+  @Override
+  public JClassType getNestedType(String typeName) throws NotFoundException {
+    return members.getNestedType(typeName);
+  }
+
+  @Override
+  public JClassType[] getNestedTypes() {
+    return members.getNestedTypes();
+  }
+
+  @Override
+  public TypeOracle getOracle() {
+    return oracle;
+  }
+
+  @Override
+  public JMethod[] getOverloads(String name) {
+    return members.getOverloads(name);
+  }
+
+  @Override
+  public JMethod[] getOverridableMethods() {
+    return members.getOverridableMethods();
+  }
+
+  @Override
+  public JPackage getPackage() {
+    return declaringPackage;
+  }
+
+  @Override
+  public String getQualifiedBinaryName() {
+    if (lazyQualifiedBinaryName == null) {
+      lazyQualifiedBinaryName = "";
+      JPackage pkg = getPackage();
+      if (!pkg.isDefault()) {
+        lazyQualifiedBinaryName = pkg.getName() + ".";
+      }
+      lazyQualifiedBinaryName += nestedName.replace('.', '$');
+    }
+    return lazyQualifiedBinaryName;
+  }
+
+  @Override
+  public String getQualifiedSourceName() {
+    if (lazyQualifiedName == null) {
+      JPackage pkg = getPackage();
+      if (!pkg.isDefault()) {
+        lazyQualifiedName = pkg.getName() + "." + nestedName;
+      } else {
+        lazyQualifiedName = nestedName;
+      }
+      lazyQualifiedName = StringInterner.get().intern(lazyQualifiedName);
+    }
+    return lazyQualifiedName;
+  }
+
+  @Override
+  public String getSimpleSourceName() {
+    return name;
+  }
+
+  @Override
+  public JClassType[] getSubtypes() {
+    return allSubtypes.toArray(TypeOracle.NO_JCLASSES);
+  }
+
+  @Override
+  public JClassType getSuperclass() {
+    return superclass;
+  }
+
+  @Override
+  public boolean isAbstract() {
+    return 0 != (modifierBits & TypeOracle.MOD_ABSTRACT);
+  }
+
+  @Override
+  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+    return annotations.isAnnotationPresent(annotationClass);
+  }
+
+  @Override
+  public JArrayType isArray() {
+    // intentional null
+    return null;
+  }
+
+  @Override
+  public JClassType isClass() {
+    return isInterface ? null : this;
+  }
+
+  /**
+   * Determines if the class can be constructed using a simple <code>new</code>
+   * operation. Specifically, the class must
+   * <ul>
+   * <li>be a class rather than an interface,</li>
+   * <li>have either no constructors or a parameterless constructor, and</li>
+   * <li>be a top-level class or a static nested class.</li>
+   * </ul>
+   * 
+   * @return <code>true</code> if the type is default instantiable, or
+   *         <code>false</code> otherwise
+   */
+  @Override
+  public boolean isDefaultInstantiable() {
+    if (isInterface() != null || isAbstract()) {
+      return false;
+    }
+    if (isMemberType() && !isStatic()) {
+      return false;
+    }
+    if (getConstructors().length == 0) {
+      return true;
+    }
+    JConstructor ctor = findConstructor(TypeOracle.NO_JTYPES);
+    if (ctor != null) {
+      return true;
+    }
+    return false;
+  }
+
+  @Override
+  public JEnumType isEnum() {
+    return null;
+  }
+
+  @Override
+  public boolean isFinal() {
+    return 0 != (getModifierBits() & TypeOracle.MOD_FINAL);
+  }
+
+  @Override
+  public JGenericType isGenericType() {
+    return null;
+  }
+
+  @Override
+  public JClassType isInterface() {
+    return isInterface ? this : null;
+  }
+
+  /**
+   * Tests if this type is contained within another type.
+   * 
+   * @return true if this type has an enclosing type, false if this type is a
+   *         top-level type
+   */
+  @Override
+  public boolean isMemberType() {
+    return enclosingType != null;
+  }
+
+  @Override
+  public JParameterizedType isParameterized() {
+    // intentional null
+    return null;
+  }
+
+  @Override
+  public JPrimitiveType isPrimitive() {
+    // intentional null
+    return null;
+  }
+
+  @Override
+  public boolean isPrivate() {
+    return 0 != (modifierBits & TypeOracle.MOD_PRIVATE);
+  }
+
+  @Override
+  public boolean isProtected() {
+    return 0 != (modifierBits & TypeOracle.MOD_PROTECTED);
+  }
+
+  @Override
+  public boolean isPublic() {
+    return 0 != (modifierBits & TypeOracle.MOD_PUBLIC);
+  }
+
+  @Override
+  public JRawType isRawType() {
+    // TODO Override in JGenericType?
+    return null;
+  }
+
+  @Override
+  public boolean isStatic() {
+    return 0 != (modifierBits & TypeOracle.MOD_STATIC);
+  }
+
+  @Override
+  public JWildcardType isWildcard() {
+    return null;
+  }
+
+  @Override
+  public String toString() {
+    if (isInterface) {
+      return "interface " + getQualifiedSourceName();
+    } else {
+      return "class " + getQualifiedSourceName();
+    }
+  }
+
+  @Override
+  protected void acceptSubtype(JClassType me) {
+    allSubtypes = IdentitySets.add(allSubtypes, me);
+    notifySuperTypesOf(me);
+  }
+
+  @Override
+  protected void addConstructor(JConstructor ctor) {
+    members.addConstructor(ctor);
+  }
+
+  @Override
+  protected void addField(JField field) {
+    members.addField(field);
+  }
+
+  @Override
+  protected void addMethod(JMethod method) {
+    members.addMethod(method);
+  }
+
+  @Override
+  protected void addNestedType(JClassType type) {
+    members.addNestedType(type);
+  }
+
+  @Override
+  protected JClassType findNestedTypeImpl(String[] typeName, int index) {
+    return members.findNestedTypeImpl(typeName, index);
+  }
+
+  @Override
+  protected void getInheritableMethodsOnSuperclassesAndThisClass(
+      Map<String, JMethod> methodsBySignature) {
+    members.getInheritableMethodsOnSuperclassesAndThisClass(methodsBySignature);
+  }
+
+  /**
+   * Gets the methods declared in interfaces that this type extends. If this
+   * type is a class, its own methods are not added. If this type is an
+   * interface, its own methods are added. Used internally by
+   * {@link #getOverridableMethods()}.
+   * 
+   * @param methodsBySignature
+   */
+  @Override
+  protected void getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
+      Map<String, JMethod> methodsBySignature) {
+    members.getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
+  }
+
+  @Override
+  protected int getModifierBits() {
+    return modifierBits;
+  }
+
+  /**
+   * Tells this type's superclasses and superinterfaces about it.
+   */
+  @Override
+  protected void notifySuperTypesOf(JClassType me) {
+    // TODO(scottb): revisit
+    if (superclass != null) {
+      superclass.acceptSubtype(me);
+    }
+    for (int i = 0, n = interfaces.size(); i < n; ++i) {
+      JClassType intf = interfaces.get(i);
+      intf.acceptSubtype(me);
+    }
+  }
+
+  @Override
+  protected void removeSubtype(JClassType me) {
+    allSubtypes = IdentitySets.remove(allSubtypes, me);
+
+    if (superclass != null) {
+      superclass.removeSubtype(me);
+    }
+
+    for (int i = 0, n = interfaces.size(); i < n; ++i) {
+      JClassType intf = interfaces.get(i);
+
+      intf.removeSubtype(me);
+    }
+  }
+
+  void addAnnotations(
+      Map<Class<? extends Annotation>, Annotation> declaredAnnotations) {
+    annotations.addAnnotations(declaredAnnotations);
+  }
+
+  @Override
+  void addImplementedInterface(JClassType intf) {
+    assert (intf != null);
+    interfaces = Lists.add(interfaces, intf);
+  }
+
+  /**
+   * NOTE: This method is for testing purposes only.
+   */
+  @Override
+  Annotation[] getAnnotations() {
+    return annotations.getAnnotations();
+  }
+
+  /**
+   * NOTE: This method is for testing purposes only.
+   */
+  @Override
+  Annotation[] getDeclaredAnnotations() {
+    return annotations.getDeclaredAnnotations();
+  }
+
+  @Override
+  JRealClassType getSubstitutedType(JParameterizedType parameterizedType) {
+    return this;
+  }
+
+  @Override
+  void notifySuperTypes() {
+    notifySuperTypesOf(this);
+  }
+
+  /**
+   * Removes references to this instance from all of its super types.
+   */
+  @Override
+  void removeFromSupertypes() {
+    removeSubtype(this);
+  }
+
+  void setEnclosingType(JClassType enclosingType) {
+    assert this.enclosingType == null;
+    assert enclosingType != null;
+
+    this.enclosingType = enclosingType;
+
+    // Add myself to my enclosing type.
+    JRawType rawType = enclosingType.isRawType();
+    if (rawType != null) {
+      enclosingType = rawType.getGenericType();
+    }
+    enclosingType.addNestedType(this);
+  }
+
+  @Override
+  void setSuperclass(JClassType type) {
+    assert (type != null);
+    assert (isInterface() == null);
+    this.superclass = type;
+    JRealClassType realSuperType;
+    if (type.isParameterized() != null) {
+      realSuperType = type.isParameterized().getBaseType();
+    } else if (type.isRawType() != null) {
+      realSuperType = type.isRawType().getGenericType();
+    } else if (type instanceof JRealClassType) {
+      realSuperType = (JRealClassType) type;
+    } else {
+      throw new IllegalArgumentException("Unknown type for " + type);
+    }
+    annotations.setParent(realSuperType.annotations);
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JTypeParameter.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JTypeParameter.java
new file mode 100644
index 0000000..41e908a
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JTypeParameter.java
@@ -0,0 +1,209 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.util.StringInterner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents one of the type parameters in a generic type.
+ */
+public class JTypeParameter extends JDelegatingClassType implements
+    com.google.gwt.core.ext.typeinfo.JTypeParameter {
+  private JClassType[] bounds;
+  private JGenericType declaringClass;
+  private final int ordinal;
+  private final String typeName;
+
+  public JTypeParameter(String typeName, int ordinal) {
+    this.typeName = StringInterner.get().intern(typeName);
+    this.ordinal = ordinal;
+  }
+
+  @Override
+  public JField findField(String name) {
+    return getBaseType().findField(name);
+  }
+
+  @Override
+  public JMethod findMethod(String name, JType[] paramTypes) {
+    return getBaseType().findMethod(name, paramTypes);
+  }
+
+  public JClassType[] getBounds() {
+    return bounds;
+  }
+
+  public JGenericType getDeclaringClass() {
+    return declaringClass;
+  }
+
+  @Override
+  public JClassType getEnclosingType() {
+    // Type parameters do not have an enclosing type.
+    return null;
+  }
+
+  @Override
+  public JField getField(String name) {
+    return getBaseType().getField(name);
+  }
+
+  @Override
+  public JField[] getFields() {
+    return getBaseType().getFields();
+  }
+
+  public JClassType getFirstBound() {
+    return getBaseType();
+  }
+
+  @Override
+  public JMethod getMethod(String name, JType[] paramTypes)
+      throws NotFoundException {
+    return getBaseType().getMethod(name, paramTypes);
+  }
+
+  @Override
+  public JMethod[] getMethods() {
+    return getBaseType().getMethods();
+  }
+
+  @Override
+  public String getName() {
+    return typeName;
+  }
+
+  public int getOrdinal() {
+    return ordinal;
+  }
+
+  @Override
+  public String getParameterizedQualifiedSourceName() {
+    return typeName;
+  }
+
+  @Override
+  public String getQualifiedBinaryName() {
+    // TODO(jat): !! does a binary name have meaning for a type parameter?
+    return toString(true);
+  }
+
+  @Override
+  public String getQualifiedSourceName() {
+    return toString(false);
+  }
+
+  @Override
+  public String getSimpleSourceName() {
+    return toString(true);
+  }
+
+  @Override
+  public JClassType[] getSubtypes() {
+    JClassType[] subtypes = super.getSubtypes();
+    List<JClassType> intersectionTypes = new ArrayList<JClassType>();
+
+    if (getFirstBound().isInterface() == null
+        && isAssignableFrom(getFirstBound())) {
+      // Include the first bound as a subtype if it is not an interface and it
+      // is assignable to all of our bounds.
+      intersectionTypes.add(getFirstBound());
+    }
+
+    for (JClassType subtype : subtypes) {
+      if (isAssignableFrom(subtype)) {
+        intersectionTypes.add(subtype);
+      }
+    }
+
+    // Only types that intersect with all our bounds make it here.
+    return intersectionTypes.toArray(TypeOracle.NO_JCLASSES);
+  }
+
+  @Override
+  public JGenericType isGenericType() {
+    return null;
+  }
+
+  @Override
+  public JParameterizedType isParameterized() {
+    return null;
+  }
+
+  @Override
+  public JRawType isRawType() {
+    return null;
+  }
+
+  @Override
+  public JTypeParameter isTypeParameter() {
+    return this;
+  }
+
+  @Override
+  public JWildcardType isWildcard() {
+    return null;
+  }
+
+  public void setBounds(JClassType[] bounds) {
+    this.bounds = bounds;
+    super.setBaseType(bounds[0]);
+  }
+
+  @Override
+  public String toString() {
+    if (getBaseType().isInterface() != null) {
+      return "interface " + getQualifiedSourceName();
+    } else {
+      return "class " + getQualifiedSourceName();
+    }
+  }
+
+  @Override
+  JClassType getSubstitutedType(JParameterizedType parameterizedType) {
+    return parameterizedType.getTypeParameterSubstitution(this);
+  }
+
+  void setDeclaringClass(JGenericType declaringClass) {
+    this.declaringClass = declaringClass;
+  }
+
+  private String toString(boolean simpleName) {
+    StringBuffer sb = new StringBuffer();
+    sb.append(typeName);
+    sb.append(" extends ");
+    for (int i = 0; i < bounds.length; ++i) {
+      if (i != 0) {
+        sb.append(" & ");
+      }
+
+      String boundName;
+      if (simpleName) {
+        boundName = bounds[i].getSimpleSourceName();
+      } else {
+        boundName = bounds[i].getParameterizedQualifiedSourceName();
+      }
+      sb.append(boundName);
+    }
+
+    return sb.toString();
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/JWildcardType.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/JWildcardType.java
new file mode 100644
index 0000000..07dcd5f
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/JWildcardType.java
@@ -0,0 +1,224 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+
+/**
+ * Represents a wildcard type argument to a parameterized type.
+ */
+public class JWildcardType extends JDelegatingClassType implements
+    com.google.gwt.core.ext.typeinfo.JWildcardType {
+
+  private final BoundType boundType;
+  private JClassType[] lazyLowerBounds;
+  private JClassType[] lazyUpperBounds;
+
+  JWildcardType(BoundType boundType, JClassType typeBound) {
+    this.boundType = boundType;
+    super.setBaseType(typeBound);
+  }
+
+  @Override
+  public JField findField(String name) {
+    return getBaseType().findField(name);
+  }
+
+  @Override
+  public JMethod findMethod(String name, JType[] paramTypes) {
+    return getBaseType().findMethod(name, paramTypes);
+  }
+
+  public BoundType getBoundType() {
+    return boundType;
+  }
+
+  @Override
+  public JClassType getErasedType() {
+    return getUpperBound().getErasedType();
+  }
+
+  @Override
+  public JField getField(String name) {
+    return getBaseType().getField(name);
+  }
+
+  @Override
+  public JField[] getFields() {
+    return getBaseType().getFields();
+  }
+
+  public JClassType getFirstBound() {
+    return getBaseType();
+  }
+
+  /**
+   * Returns the lower bounds of this wildcard type. If no lower bounds were
+   * declared, an empty array is returned.
+   * 
+   * @return the lower bounds of this wildcard type
+   */
+  public JClassType[] getLowerBounds() {
+    if (lazyLowerBounds == null) {
+      if (isUpperBound()) {
+        lazyLowerBounds = TypeOracle.NO_JCLASSES;
+      } else {
+        lazyLowerBounds = new JClassType[]{getFirstBound()};
+      }
+    }
+    return lazyLowerBounds;
+  }
+
+  @Override
+  public JMethod getMethod(String name, JType[] paramTypes)
+      throws NotFoundException {
+    return getBaseType().getMethod(name, paramTypes);
+  }
+
+  @Override
+  public JMethod[] getMethods() {
+    return getBaseType().getMethods();
+  }
+
+  @Override
+  public String getQualifiedBinaryName() {
+    // TODO(jat): !! does a binary name have meaning for a wildcard?
+    return toString(true);
+  }
+
+  @Override
+  public String getQualifiedSourceName() {
+    return toString(false);
+  }
+
+  @Override
+  public String getSimpleSourceName() {
+    return toString(true);
+  }
+
+  @Override
+  public JClassType[] getSubtypes() {
+    if (isUpperBound()) {
+      return getFirstBound().getSubtypes();
+    }
+
+    // We are not sure what the correct behavior should be for lower bound
+    // wildcards. ? super Number contains ? super T for all T extends Number,
+    // but it also includes T for Number extends T. For example, Object is a
+    // subtype.
+    return TypeOracle.NO_JCLASSES;
+  }
+
+  @Override
+  public JClassType getSuperclass() {
+    if (isUpperBound()) {
+      // The superclass of an upper bound is the upper bound.
+      return getFirstBound();
+    }
+
+    // The only safe superclass for a ? super T is Object.
+    return getOracle().getJavaLangObject();
+  }
+
+  public JClassType getUpperBound() {
+    if (isUpperBound()) {
+      return getFirstBound();
+    }
+
+    return getOracle().getJavaLangObject();
+  }
+
+  /**
+   * Returns the upper bounds of this wildcard type. If no upper bounds were
+   * declared, an array containing {@link Object} is returned.
+   * 
+   * @return the upper bounds of this wildcard type
+   */
+  public JClassType[] getUpperBounds() {
+    if (lazyUpperBounds == null) {
+      if (isUpperBound()) {
+        lazyUpperBounds = new JClassType[]{getFirstBound()};
+      } else {
+        // Object is the default upper bound.
+        lazyUpperBounds = new JClassType[]{getOracle().getJavaLangObject()};
+      }
+    }
+
+    return lazyUpperBounds;
+  }
+
+  @Override
+  public JGenericType isGenericType() {
+    return null;
+  }
+
+  @Override
+  public JParameterizedType isParameterized() {
+    return null;
+  }
+
+  @Override
+  public JRawType isRawType() {
+    return null;
+  }
+
+  @Override
+  public JWildcardType isWildcard() {
+    return this;
+  }
+
+  /**
+   * Returns <code>true</code> if this instance has the same bounds that are
+   * requested.
+   * 
+   * @param otherWildcard
+   * @return <code>true</code> if this instance has the same bounds that are
+   *         requested
+   */
+  boolean boundsMatch(JWildcardType otherWildcard) {
+    return isUpperBound() == otherWildcard.isUpperBound()
+        && getFirstBound() == otherWildcard.getFirstBound();
+  }
+
+  @Override
+  JClassType getSubstitutedType(JParameterizedType parameterizedType) {
+    return getOracle().getWildcardType(boundType,
+        getFirstBound().getSubstitutedType(parameterizedType));
+  }
+
+  private boolean isUnbound() {
+    return boundType == BoundType.UNBOUND;
+  }
+
+  private boolean isUpperBound() {
+    return boundType != BoundType.SUPER;
+  }
+
+  private String toString(boolean simpleName) {
+    String str = "?";
+    if (isUnbound()) {
+      return str;
+    } else {
+      str += (isUpperBound() ? " extends " : " super ");
+      if (simpleName) {
+        return str + getFirstBound().getSimpleSourceName();
+      } else {
+        return str + getFirstBound().getParameterizedQualifiedSourceName();
+      }
+    }
+  }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/Members.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/Members.java
similarity index 98%
rename from dev/core/src/com/google/gwt/core/ext/typeinfo/Members.java
rename to dev/core/src/com/google/gwt/dev/javac/typemodel/Members.java
index 88de211..32d806d 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/Members.java
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/Members.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.dev.util.collect.Lists;
 import com.google.gwt.dev.util.collect.Maps;
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/Substitution.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/Substitution.java
similarity index 88%
rename from dev/core/src/com/google/gwt/core/ext/typeinfo/Substitution.java
rename to dev/core/src/com/google/gwt/dev/javac/typemodel/Substitution.java
index f9df504..c09de2f 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/Substitution.java
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/Substitution.java
@@ -13,13 +13,12 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 /**
  * Interface used to perform type parameter substitutions or raw type
  * substitutions.
  */
 interface Substitution {
-  JType getSubstitution(JType type);
+  JClassType getSubstitution(JClassType type);
 }
diff --git a/dev/core/src/com/google/gwt/dev/javac/typemodel/TypeOracle.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/TypeOracle.java
new file mode 100644
index 0000000..8bef1ad
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/TypeOracle.java
@@ -0,0 +1,963 @@
+/*
+ * 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.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.BadTypeArgsException;
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.core.ext.typeinfo.ParseException;
+import com.google.gwt.core.ext.typeinfo.TypeOracleException;
+import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
+import com.google.gwt.dev.javac.JavaSourceParser;
+import com.google.gwt.dev.jjs.InternalCompilerException;
+import com.google.gwt.dev.resource.Resource;
+import com.google.gwt.dev.util.Name;
+import com.google.gwt.dev.util.collect.HashMap;
+import com.google.gwt.dev.util.collect.IdentityHashMap;
+
+import org.apache.commons.collections.map.AbstractReferenceMap;
+import org.apache.commons.collections.map.ReferenceIdentityMap;
+import org.apache.commons.collections.map.ReferenceMap;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provides type-related information about a set of source files, including doc
+ * comment metadata.
+ * <p>
+ * All type objects exposed, such as
+ * {@link com.google.gwt.core.ext.typeinfo.JClassType} and others, have a stable
+ * identity relative to this type oracle instance. Consequently, you can
+ * reliably compare object identity of any objects this type oracle produces.
+ * For example, the following code relies on this stable identity guarantee:
+ * 
+ * <pre>
+ * JClassType o = typeOracle.getJavaLangObject();
+ * JClassType s1 = typeOracle.getType(&quot;java.lang.String&quot;);
+ * JClassType s2 = typeOracle.getType(&quot;java.lang.String&quot;);
+ * assert (s1 == s2);
+ * assert (o == s1.getSuperclass());
+ * JParameterizedType ls = typeOracle.parse(&quot;java.util.List&lt;java.lang.String&gt;&quot;);
+ * assert (ls.getTypeArgs()[0] == s1);
+ * </pre>
+ * 
+ * </p>
+ */
+public class TypeOracle extends com.google.gwt.core.ext.typeinfo.TypeOracle {
+
+  private static class ParameterizedTypeKey {
+    private final JClassType enclosingType;
+    private final JGenericType genericType;
+    private final com.google.gwt.core.ext.typeinfo.JClassType[] typeArgs;
+
+    public ParameterizedTypeKey(JGenericType genericType,
+        JClassType enclosingType,
+        com.google.gwt.core.ext.typeinfo.JClassType[] typeArgs) {
+      this.genericType = genericType;
+      this.enclosingType = enclosingType;
+      this.typeArgs = typeArgs;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (!(obj instanceof ParameterizedTypeKey)) {
+        return false;
+      }
+      ParameterizedTypeKey other = (ParameterizedTypeKey) obj;
+      return genericType == other.genericType
+          && enclosingType == other.enclosingType
+          && Arrays.equals(typeArgs, other.typeArgs);
+    }
+
+    @Override
+    public int hashCode() {
+      return 29 * genericType.hashCode() + 17
+          * ((enclosingType == null) ? 0 : enclosingType.hashCode())
+          + Arrays.hashCode(typeArgs);
+    }
+  }
+
+  private static class WildCardKey {
+    private final BoundType boundType;
+    private final JClassType typeBound;
+
+    public WildCardKey(BoundType boundType, JClassType typeBound) {
+      this.boundType = boundType;
+      this.typeBound = typeBound;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (!(obj instanceof WildCardKey)) {
+        return false;
+      }
+      WildCardKey other = (WildCardKey) obj;
+      return boundType == other.boundType && typeBound == other.typeBound;
+    }
+
+    @Override
+    public int hashCode() {
+      return 29 * typeBound.hashCode() + boundType.hashCode();
+    }
+  }
+
+  static final int MOD_ABSTRACT = 0x00000001;
+  static final int MOD_FINAL = 0x00000002;
+  static final int MOD_NATIVE = 0x00000004;
+  static final int MOD_PRIVATE = 0x00000008;
+  static final int MOD_PROTECTED = 0x00000010;
+  static final int MOD_PUBLIC = 0x00000020;
+  static final int MOD_STATIC = 0x00000040;
+  static final int MOD_TRANSIENT = 0x00000080;
+  static final int MOD_VOLATILE = 0x00000100;
+
+  static final Annotation[] NO_ANNOTATIONS = new Annotation[0];
+  static final JClassType[] NO_JCLASSES = new JClassType[0];
+  static final JConstructor[] NO_JCTORS = new JConstructor[0];
+  static final JField[] NO_JFIELDS = new JField[0];
+  static final JMethod[] NO_JMETHODS = new JMethod[0];
+  static final JPackage[] NO_JPACKAGES = new JPackage[0];
+  static final JParameter[] NO_JPARAMS = new JParameter[0];
+  static final JType[] NO_JTYPES = new JType[0];
+  static final String[][] NO_STRING_ARR_ARR = new String[0][];
+  static final String[] NO_STRINGS = new String[0];
+
+  private static final String JSO_CLASS = "com.google.gwt.core.client.JavaScriptObject";
+
+  /**
+   * Convenience method to sort class types in a consistent way. Note that the
+   * order is subject to change and is intended to generate an "aesthetically
+   * pleasing" order rather than a computationally reliable order.
+   */
+  public static void sort(JClassType[] types) {
+    Arrays.sort(types, new Comparator<JClassType>() {
+      public int compare(JClassType type1, JClassType type2) {
+        String name1 = type1.getQualifiedSourceName();
+        String name2 = type2.getQualifiedSourceName();
+        return name1.compareTo(name2);
+      }
+    });
+  }
+
+  /**
+   * Convenience method to sort constructors in a consistent way. Note that the
+   * order is subject to change and is intended to generate an "aesthetically
+   * pleasing" order rather than a computationally reliable order.
+   */
+  public static void sort(JConstructor[] ctors) {
+    Arrays.sort(ctors, new Comparator<JConstructor>() {
+      public int compare(JConstructor o1, JConstructor o2) {
+        // Nothing for now; could enhance to sort based on parameter list
+        return 0;
+      }
+    });
+  }
+
+  /**
+   * Convenience method to sort fields in a consistent way. Note that the order
+   * is subject to change and is intended to generate an "aesthetically
+   * pleasing" order rather than a computationally reliable order.
+   */
+  public static void sort(JField[] fields) {
+    Arrays.sort(fields, new Comparator<JField>() {
+      public int compare(JField f1, JField f2) {
+        String name1 = f1.getName();
+        String name2 = f2.getName();
+        return name1.compareTo(name2);
+      }
+    });
+  }
+
+  /**
+   * Convenience method to sort methods in a consistent way. Note that the order
+   * is subject to change and is intended to generate an "aesthetically
+   * pleasing" order rather than a computationally reliable order.
+   */
+  public static void sort(JMethod[] methods) {
+    Arrays.sort(methods, new Comparator<JMethod>() {
+      public int compare(JMethod m1, JMethod m2) {
+        String name1 = m1.getName();
+        String name2 = m2.getName();
+        return name1.compareTo(name2);
+      }
+    });
+  }
+
+  static JClassType[] cast(
+      com.google.gwt.core.ext.typeinfo.JClassType[] extTypeArgs) {
+    JClassType[] result = new JClassType[extTypeArgs.length];
+    System.arraycopy(extTypeArgs, 0, result, 0, extTypeArgs.length);
+    return result;
+  }
+
+  static String[] modifierBitsToNames(int bits) {
+    List<String> strings = new ArrayList<String>();
+
+    // The order is based on the order in which we want them to appear.
+    //
+    if (0 != (bits & MOD_PUBLIC)) {
+      strings.add("public");
+    }
+
+    if (0 != (bits & MOD_PRIVATE)) {
+      strings.add("private");
+    }
+
+    if (0 != (bits & MOD_PROTECTED)) {
+      strings.add("protected");
+    }
+
+    if (0 != (bits & MOD_STATIC)) {
+      strings.add("static");
+    }
+
+    if (0 != (bits & MOD_ABSTRACT)) {
+      strings.add("abstract");
+    }
+
+    if (0 != (bits & MOD_FINAL)) {
+      strings.add("final");
+    }
+
+    if (0 != (bits & MOD_NATIVE)) {
+      strings.add("native");
+    }
+
+    if (0 != (bits & MOD_TRANSIENT)) {
+      strings.add("transient");
+    }
+
+    if (0 != (bits & MOD_VOLATILE)) {
+      strings.add("volatile");
+    }
+
+    return strings.toArray(NO_STRINGS);
+  }
+
+  /**
+   * A map of fully-qualify source names (ie, use "." rather than "$" for nested
+   * classes) to JRealClassTypes.
+   */
+  private final Map<String, JRealClassType> allTypes = new HashMap<String, JRealClassType>();
+
+  @SuppressWarnings("unchecked")
+  private final Map<JType, JArrayType> arrayTypes = new ReferenceIdentityMap(
+      AbstractReferenceMap.WEAK, AbstractReferenceMap.WEAK, true);
+
+  private JClassType javaLangObject;
+
+  private final JavaSourceParser javaSourceParser = new JavaSourceParser();
+
+  /**
+   * Maps SingleJsoImpl interfaces to the implementing JSO subtype.
+   */
+  private final Map<JClassType, JClassType> jsoSingleImpls = new IdentityHashMap<JClassType, JClassType>();
+
+  private final Map<String, JPackage> packages = new HashMap<String, JPackage>();
+
+  @SuppressWarnings("unchecked")
+  private final Map<ParameterizedTypeKey, JParameterizedType> parameterizedTypes = new ReferenceMap(
+      AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK, true);
+
+  /**
+   * A list of recently-added types that will be fully initialized on the next
+   * call to {@link #finish}.
+   */
+  private final List<JRealClassType> recentTypes = new ArrayList<JRealClassType>();
+
+  private JWildcardType unboundWildCardType;
+
+  @SuppressWarnings("unchecked")
+  private final Map<WildCardKey, JWildcardType> wildcardTypes = new ReferenceMap(
+      AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK, true);
+
+  public TypeOracle() {
+    // Always create the default package.
+    //
+    getOrCreatePackage("");
+  }
+
+  /**
+   * Attempts to find a package by name. All requests for the same package
+   * return the same package object.
+   * 
+   * @return <code>null</code> if the package could not be found
+   */
+  @Override
+  public JPackage findPackage(String pkgName) {
+    return packages.get(pkgName);
+  }
+
+  /**
+   * Finds a class or interface given its fully-qualified name.
+   * 
+   * @param name fully-qualified class/interface name - for nested classes, use
+   *          its source name rather than its binary name (that is, use a "."
+   *          rather than a "$")
+   * 
+   * @return <code>null</code> if the type is not found
+   */
+  @Override
+  public JClassType findType(String name) {
+    assert Name.isSourceName(name);
+    return allTypes.get(name);
+  }
+
+  /**
+   * Finds a type given its package-relative name. For nested classes, use its
+   * source name rather than its binary name (that is, use a "." rather than a
+   * "$").
+   * 
+   * @return <code>null</code> if the type is not found
+   */
+  @Override
+  public JClassType findType(String pkgName, String typeName) {
+    assert Name.isSourceName(typeName);
+    JPackage pkg = findPackage(pkgName);
+    if (pkg != null) {
+      JClassType type = pkg.findType(typeName);
+      if (type != null) {
+        return type;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Gets the type object that represents an array of the specified type. The
+   * returned type always has a stable identity so as to guarantee that all
+   * calls to this method with the same argument return the same object.
+   * 
+   * @param componentType the component type of the array, which can itself be
+   *          an array type
+   * @return a type object representing an array of the component type
+   */
+  @Override
+  public JArrayType getArrayType(JType componentType) {
+    JArrayType arrayType = arrayTypes.get(componentType);
+    if (arrayType == null) {
+      arrayType = new JArrayType(componentType, this);
+      arrayTypes.put(componentType, arrayType);
+    }
+    return arrayType;
+  }
+
+  /**
+   * Gets a reference to the type object representing
+   * <code>java.lang.Object</code>.
+   */
+  @Override
+  public JClassType getJavaLangObject() {
+    if (javaLangObject == null) {
+      javaLangObject = findType("java.lang.Object");
+      assert javaLangObject != null;
+    }
+    return javaLangObject;
+  }
+
+  /**
+   * Ensure that a package with the specified name exists as well as its parent
+   * packages.
+   */
+  @Override
+  public JPackage getOrCreatePackage(String name) {
+    int i = name.lastIndexOf('.');
+    if (i != -1) {
+      // Ensure the parent package is also created.
+      //
+      getOrCreatePackage(name.substring(0, i));
+    }
+
+    JPackage pkg = packages.get(name);
+    if (pkg == null) {
+      pkg = new JPackage(name);
+      packages.put(name, pkg);
+    }
+    return pkg;
+  }
+
+  /**
+   * Gets a package by name. All requests for the same package return the same
+   * package object.
+   * 
+   * @return the package object associated with the specified name
+   */
+  @Override
+  public JPackage getPackage(String pkgName) throws NotFoundException {
+    JPackage result = findPackage(pkgName);
+    if (result == null) {
+      throw new NotFoundException(pkgName);
+    }
+    return result;
+  }
+
+  /**
+   * Gets an array of all packages known to this type oracle.
+   * 
+   * @return an array of packages, possibly of zero-length
+   */
+  @Override
+  public JPackage[] getPackages() {
+    return packages.values().toArray(NO_JPACKAGES);
+  }
+
+  /**
+   * Gets the parameterized type object that represents the combination of a
+   * specified raw type and a set of type arguments. The returned type always
+   * has a stable identity so as to guarantee that all calls to this method with
+   * the same arguments return the same object.
+   * 
+   * @param genericType a generic base class
+   * @param enclosingType
+   * @param typeArgs the type arguments bound to the specified generic type
+   * @return a type object representing this particular binding of type
+   *         arguments to the specified generic
+   * @throws IllegalArgumentException if the parameterization of a non-static
+   *           member type does not specify an enclosing type or if not enough
+   *           arguments were specified to parameterize the generic type
+   * @throws NullPointerException if genericType is <code>null</code>
+   */
+  @Override
+  public JParameterizedType getParameterizedType(
+      com.google.gwt.core.ext.typeinfo.JGenericType extGenericType,
+      com.google.gwt.core.ext.typeinfo.JClassType extEnclosingType,
+      com.google.gwt.core.ext.typeinfo.JClassType[] extTypeArgs) {
+    JGenericType genericType = (JGenericType) extGenericType;
+    JClassType enclosingType = (JClassType) extEnclosingType;
+    JClassType[] typeArgs = cast(extTypeArgs);
+    ParameterizedTypeKey key = new ParameterizedTypeKey(genericType,
+        enclosingType, typeArgs);
+    JParameterizedType result = parameterizedTypes.get(key);
+    if (result != null) {
+      return result;
+    }
+
+    if (genericType.isMemberType() && !genericType.isStatic()) {
+      if (genericType.getEnclosingType().isGenericType() != null
+          && enclosingType.isParameterized() == null
+          && enclosingType.isRawType() == null) {
+        /*
+         * If the generic type is a non-static member type enclosed by a generic
+         * type then the enclosing type for this parameterized type should be
+         * raw or parameterized.
+         */
+        throw new IllegalArgumentException("Generic type '"
+            + genericType.getParameterizedQualifiedSourceName()
+            + "' is a non-static member type, but the enclosing type '"
+            + enclosingType.getQualifiedSourceName()
+            + "' is not a parameterized or raw type");
+      }
+    }
+
+    JTypeParameter[] typeParameters = genericType.getTypeParameters();
+    if (typeArgs.length < typeParameters.length) {
+      throw new IllegalArgumentException(
+          "Not enough type arguments were specified to parameterize '"
+              + genericType.getParameterizedQualifiedSourceName() + "'");
+    } else {
+      /*
+       * TODO: Should WARN if we specify too many type arguments but we have no
+       * logger.
+       */
+    }
+
+    // TODO: validate that the type arguments satisfy the generic type parameter
+    // bounds if any were specified
+
+    result = new JParameterizedType(genericType, enclosingType, typeArgs);
+    parameterizedTypes.put(key, result);
+    return result;
+  }
+
+  /**
+   * Gets the parameterized type object that represents the combination of a
+   * specified raw type and a set of type arguments. The returned type always
+   * has a stable identity so as to guarantee that all calls to this method with
+   * the same arguments return the same object.
+   * 
+   * @param genericType a generic base class
+   * @param typeArgs the type arguments bound to the specified generic type
+   * @return a type object representing this particular binding of type
+   *         arguments to the specified generic
+   * @throws IllegalArgumentException if the generic type is a non-static member
+   *           type or if not enough arguments were specified to parameterize
+   *           the generic type
+   * @throws NullPointerException if genericType is <code>null</code>
+   */
+  @Override
+  public JParameterizedType getParameterizedType(
+      com.google.gwt.core.ext.typeinfo.JGenericType genericType,
+      com.google.gwt.core.ext.typeinfo.JClassType[] typeArgs) {
+    return getParameterizedType(genericType, null, typeArgs);
+  }
+
+  /**
+   * @deprecated This method will always return 0 because a TypeOracle never
+   *             gets reloaded anymore. Callers should not rely on this value to
+   *             manage static state.
+   */
+  @Deprecated
+  @Override
+  public long getReloadCount() {
+    return 0;
+  }
+
+  /**
+   * Returns the single implementation type for an interface returned via
+   * {@link #getSingleJsoImplInterfaces()} or <code>null</code> if no JSO
+   * implementation is defined.
+   */
+  @Override
+  public JClassType getSingleJsoImpl(
+      com.google.gwt.core.ext.typeinfo.JClassType intf) {
+    assert intf.isInterface() == intf;
+    return jsoSingleImpls.get(intf);
+  }
+
+  /**
+   * Returns an unmodifiable, live view of all interface types that are
+   * implemented by exactly one JSO subtype.
+   */
+  @Override
+  public Set<? extends com.google.gwt.core.ext.typeinfo.JClassType> getSingleJsoImplInterfaces() {
+    return Collections.unmodifiableSet(jsoSingleImpls.keySet());
+  }
+
+  /**
+   * Finds a type given its fully qualified name. For nested classes, use its
+   * source name rather than its binary name (that is, use a "." rather than a
+   * "$").
+   * 
+   * @return the specified type
+   */
+  @Override
+  public JClassType getType(String name) throws NotFoundException {
+    assert Name.isSourceName(name);
+    JClassType type = findType(name);
+    if (type == null) {
+      throw new NotFoundException(name);
+    }
+    return type;
+  }
+
+  /**
+   * Finds a type given its package-relative name. For nested classes, use its
+   * source name rather than its binary name (that is, use a "." rather than a
+   * "$").
+   * 
+   * @return the specified type
+   */
+  @Override
+  public JClassType getType(String pkgName, String topLevelTypeSimpleName)
+      throws NotFoundException {
+    assert Name.isSourceName(topLevelTypeSimpleName);
+    JClassType type = findType(pkgName, topLevelTypeSimpleName);
+    if (type == null) {
+      throw new NotFoundException(pkgName + "." + topLevelTypeSimpleName);
+    }
+    return type;
+  }
+
+  /**
+   * Gets all types, both top-level and nested.
+   * 
+   * @return an array of types, possibly of zero length
+   */
+  @Override
+  public JClassType[] getTypes() {
+    Collection<JRealClassType> values = allTypes.values();
+    JClassType[] result = values.toArray(new JClassType[values.size()]);
+    Arrays.sort(result, new Comparator<JClassType>() {
+      public int compare(JClassType o1, JClassType o2) {
+        return o1.getQualifiedSourceName().compareTo(
+            o2.getQualifiedSourceName());
+      }
+    });
+    return result;
+  }
+
+  @Override
+  public JWildcardType getWildcardType(
+      com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType boundType,
+      com.google.gwt.core.ext.typeinfo.JClassType extTypeBound) {
+    // Special fast case for <? extends Object>
+    // TODO(amitmanjhi): make sure this actually does speed things up!
+    JClassType typeBound = (JClassType) extTypeBound;
+    if (typeBound == getJavaLangObject() && boundType == BoundType.UNBOUND) {
+      if (unboundWildCardType == null) {
+        unboundWildCardType = new JWildcardType(boundType, typeBound);
+      }
+      return unboundWildCardType;
+    }
+    // End special case / todo.
+
+    WildCardKey key = new WildCardKey(boundType, typeBound);
+    JWildcardType result = wildcardTypes.get(key);
+    if (result != null) {
+      return result;
+    }
+
+    result = new JWildcardType(boundType, typeBound);
+    wildcardTypes.put(key, result);
+    return result;
+  }
+
+  /**
+   * Parses the string form of a type to produce the corresponding type object.
+   * The types that can be parsed include primitives, class and interface names,
+   * simple parameterized types (those without wildcards or bounds), and arrays
+   * of the preceding.
+   * <p>
+   * Examples of types that can be parsed by this method.
+   * <ul>
+   * <li><code>int</code></li>
+   * <li><code>java.lang.Object</code></li>
+   * <li><code>java.lang.String[]</code></li>
+   * <li><code>char[][]</code></li>
+   * <li><code>void</code></li>
+   * <li><code>List&lt;Shape&gt;</code></li>
+   * <li><code>List&lt;List&lt;Shape&gt;&gt;</code></li>
+   * </ul>
+   * </p>
+   * 
+   * @param type a type signature to be parsed
+   * @return the type object corresponding to the parse type
+   */
+  @Override
+  public JType parse(String type) throws TypeOracleException {
+    // Remove all internal and external whitespace.
+    //
+    type = type.replaceAll("\\\\s", "");
+
+    // Recursively parse.
+    //
+    return parseImpl(type);
+  }
+
+  void addNewType(JRealClassType newType) {
+    String fqcn = newType.getQualifiedSourceName();
+    allTypes.put(fqcn, newType);
+    recentTypes.add(newType);
+  }
+
+  /**
+   * Called to add a source reference for a top-level class type.
+   */
+  void addSourceReference(JRealClassType type, Resource sourceFile) {
+    javaSourceParser.addSourceForType(type, sourceFile);
+  }
+
+  /**
+   * Called after a block of new types are added.
+   */
+  void finish() {
+    JClassType[] newTypes = recentTypes.toArray(new JClassType[recentTypes.size()]);
+    computeHierarchyRelationships(newTypes);
+    computeSingleJsoImplData(newTypes);
+    recentTypes.clear();
+  }
+
+  JavaSourceParser getJavaSourceParser() {
+    return javaSourceParser;
+  }
+
+  private List<JClassType> classChain(JClassType cls) {
+    LinkedList<JClassType> chain = new LinkedList<JClassType>();
+    while (cls != null) {
+      chain.push(cls);
+      cls = cls.getSuperclass();
+    }
+    return chain;
+  }
+
+  /**
+   * Determines whether the given class fully implements an interface (either
+   * directly or via inherited methods).
+   */
+  private boolean classFullyImplements(JClassType cls, JClassType intf) {
+    // The class must at least nominally implement the interface.
+    if (!intf.isAssignableFrom(cls)) {
+      return false;
+    }
+
+    // Check to see whether it implements all the interfaces methods.
+    for (JMethod meth : intf.getInheritableMethods()) {
+      if (!classImplementsMethod(cls, meth)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private boolean classImplementsMethod(JClassType cls, JMethod meth) {
+    while (cls != null) {
+      JMethod found = cls.findMethod(meth.getName(), meth.getParameterTypes());
+      if ((found != null) && !found.isAbstract()) {
+        return true;
+      }
+      cls = cls.getSuperclass();
+    }
+    return false;
+  }
+
+  private void computeHierarchyRelationships(JClassType[] types) {
+    // For each type, walk up its hierarchy chain and tell each supertype
+    // about its subtype.
+    for (JClassType type : types) {
+      type.notifySuperTypes();
+    }
+  }
+
+  /**
+   * Updates the list of jsoSingleImpl types from recently-added types.
+   */
+  private void computeSingleJsoImplData(JClassType... newTypes) {
+    JClassType jsoType = findType(JSO_CLASS);
+    if (jsoType == null) {
+      return;
+    }
+
+    for (JClassType type : newTypes) {
+      if (!jsoType.isAssignableFrom(type)) {
+        continue;
+      }
+
+      for (JClassType intf : JClassType.getFlattenedSuperTypeHierarchy(type)) {
+        // If intf refers to a JParameterizedType, we need to use its generic
+        // base type instead.
+        if (intf instanceof JParameterizedType) {
+          intf = ((JParameterizedType) intf).getBaseType();
+        }
+
+        if (intf.isInterface() == null) {
+          // Not an interface
+          continue;
+        }
+
+        if (intf.getOverridableMethods().length == 0) {
+          /*
+           * Record a tag interface as being implemented by JSO, since they
+           * don't actually have any methods and we want to avoid spurious
+           * messages about multiple JSO types implementing a common interface.
+           */
+          jsoSingleImpls.put(intf, jsoType);
+          continue;
+        }
+
+        /*
+         * If the previously-registered implementation type for a SingleJsoImpl
+         * interface is a subtype of the type we're currently looking at, we
+         * want to choose the least-derived class.
+         */
+        JClassType previousType = jsoSingleImpls.get(intf);
+        if (previousType == null) {
+          jsoSingleImpls.put(intf, type);
+        } else if (type.isAssignableFrom(previousType)) {
+          jsoSingleImpls.put(intf, type);
+        } else if (type.isAssignableTo(previousType)) {
+          // Do nothing
+        } else {
+          // Special case: If two JSOs implement the same interface, but they
+          // share a common base class that fully implements that interface,
+          // then choose that base class.
+          JClassType impl = findFullyImplementingBase(intf, type, previousType);
+          if (impl != null) {
+            jsoSingleImpls.put(intf, impl);
+          } else {
+            throw new InternalCompilerException(
+                "Already seen an implementing JSO subtype ("
+                    + previousType.getName() + ") for interface ("
+                    + intf.getName() + ") while examining newly-added type ("
+                    + type.getName() + "). This is a bug in "
+                    + "JSORestrictionsChecker.");
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Determines whether both classes A and B share a common superclass which
+   * fully implements the given interface.
+   */
+  private JClassType findFullyImplementingBase(JClassType intf, JClassType a,
+      JClassType b) {
+    JClassType common = findNearestCommonBase(a, b);
+    if (classFullyImplements(common, intf)) {
+      return common;
+    }
+    return null;
+  }
+
+  /**
+   * Finds the nearest common base class of the given classes.
+   */
+  private JClassType findNearestCommonBase(JClassType a, JClassType b) {
+    List<JClassType> as = classChain(a);
+    List<JClassType> bs = classChain(b);
+
+    JClassType match = null;
+    Iterator<JClassType> ait = as.iterator();
+    Iterator<JClassType> bit = bs.iterator();
+    while (ait.hasNext() && bit.hasNext()) {
+      a = ait.next();
+      b = bit.next();
+      if (a.equals(b)) {
+        match = a;
+      } else {
+        break;
+      }
+    }
+    return match;
+  }
+
+  private JType parseImpl(String type) throws NotFoundException,
+      ParseException, BadTypeArgsException {
+    if (type.endsWith("[]")) {
+      String remainder = type.substring(0, type.length() - 2);
+      JType componentType = parseImpl(remainder);
+      return getArrayType(componentType);
+    }
+
+    if (type.endsWith(">")) {
+      int bracket = type.indexOf('<');
+      if (bracket == -1) {
+        throw new ParseException(
+            "Mismatched brackets; expected '<' to match subsequent '>'");
+      }
+
+      // Resolve the raw type.
+      //
+      String rawTypeName = type.substring(0, bracket);
+      JType rawType = parseImpl(rawTypeName);
+      if (rawType.isParameterized() != null) {
+        // The raw type cannot itself be parameterized.
+        //
+        throw new BadTypeArgsException(
+            "Only non-parameterized classes and interface can be parameterized");
+      } else if (rawType.isClassOrInterface() == null) {
+        // The raw type must be a class or interface
+        // (not an array or primitive).
+        //
+        throw new BadTypeArgsException(
+            "Only classes and interface can be parameterized, so "
+                + rawType.getQualifiedSourceName()
+                + " cannot be used in this context");
+      } else if (rawType.isGenericType() == null) {
+        throw new BadTypeArgsException(
+            "'"
+                + rawType.getQualifiedSourceName()
+                + "' is not a generic type; only generic types can be parameterized");
+      }
+
+      // Resolve each type argument.
+      //
+      String typeArgContents = type.substring(bracket + 1, type.length() - 1);
+      JClassType[] typeArgs = parseTypeArgContents(typeArgContents);
+
+      // Intern this type.
+      //
+      return getParameterizedType(rawType.isGenericType(), typeArgs);
+    }
+
+    JType result = JPrimitiveType.parse(type);
+    if (result != null) {
+      return result;
+    }
+
+    result = findType(type);
+    if (result != null) {
+      return result;
+    }
+
+    throw new NotFoundException("Unable to recognize '" + type
+        + "' as a type name (is it fully qualified?)");
+  }
+
+  private void parseTypeArgComponent(List<JClassType> typeArgList,
+      String typeArgComponent) throws NotFoundException, ParseException,
+      BadTypeArgsException {
+    JType typeArg = parseImpl(typeArgComponent);
+    if (typeArg.isPrimitive() != null) {
+      // Cannot be primitive.
+      //
+      throw new BadTypeArgsException(
+          "Type arguments cannot be primitives, so '"
+              + typeArg.getQualifiedSourceName()
+              + "' cannot be used in this context");
+    }
+
+    typeArgList.add((JClassType) typeArg);
+  }
+
+  /**
+   * Returns an array of types specified inside of a gwt.typeArgs javadoc
+   * annotation.
+   */
+  private JClassType[] parseTypeArgContents(String typeArgContents)
+      throws ParseException, NotFoundException, BadTypeArgsException {
+    List<JClassType> typeArgList = new ArrayList<JClassType>();
+
+    int start = 0;
+    for (int offset = 0, length = typeArgContents.length(); offset < length; ++offset) {
+      char ch = typeArgContents.charAt(offset);
+      switch (ch) {
+        case '<':
+          // scan for closing '>' while ignoring commas
+          for (int depth = 1; depth > 0;) {
+            if (++offset == length) {
+              throw new ParseException(
+                  "Mismatched brackets; expected '<' to match subsequent '>'");
+            }
+
+            char ich = typeArgContents.charAt(offset);
+            if (ich == '<') {
+              ++depth;
+            } else if (ich == '>') {
+              --depth;
+            }
+          }
+          break;
+        case '>':
+          throw new ParseException("No matching '<' for '>'");
+        case ',':
+          String typeArgComponent = typeArgContents.substring(start, offset);
+          parseTypeArgComponent(typeArgList, typeArgComponent);
+          start = offset + 1;
+          break;
+        default:
+          break;
+      }
+    }
+
+    String typeArgComponent = typeArgContents.substring(start);
+    parseTypeArgComponent(typeArgList, typeArgComponent);
+
+    JClassType[] typeArgs = typeArgList.toArray(new JClassType[typeArgList.size()]);
+    return typeArgs;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracleBuilder.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/TypeOracleBuilder.java
similarity index 96%
rename from dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracleBuilder.java
rename to dev/core/src/com/google/gwt/dev/javac/typemodel/TypeOracleBuilder.java
index 4ec8f8c..52ef2eb 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracleBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/TypeOracleBuilder.java
@@ -13,7 +13,9 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
 
 import java.lang.annotation.Annotation;
 import java.util.Map;
@@ -54,7 +56,7 @@
     jfield.addModifierBits(modifierBits);
   }
 
-  protected void addThrows(JAbstractMethod method, JType exception) {
+  protected void addThrows(JAbstractMethod method, JClassType exception) {
     method.addThrows(exception);
   }
 
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/NestedAnnotation.java b/dev/core/src/com/google/gwt/dev/javac/typemodel/package-info.java
similarity index 61%
copy from dev/core/test/com/google/gwt/core/ext/typeinfo/test/NestedAnnotation.java
copy to dev/core/src/com/google/gwt/dev/javac/typemodel/package-info.java
index a4ceaf4..9fc6501 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/NestedAnnotation.java
+++ b/dev/core/src/com/google/gwt/dev/javac/typemodel/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * 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
@@ -13,15 +13,14 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
-
-import java.lang.annotation.Target;
 
 /**
- * Declare an annotation that cannot be applied to anything.  This is used to
- * test nested annotations (annotations used when applying an annotation).
+ * Type-introspection support classes used by generators.
+ * 
+ * Developers implementing custom {@link com.google.gwt.core.ext.Generator
+ * generators} will use the classes in this package for introspection of the
+ * code being compiled.
  */
-@Target({})
-public @interface NestedAnnotation {
-  String value();
-}
+@com.google.gwt.util.PreventSpuriousRebuilds
+package com.google.gwt.dev.javac.typemodel;
+
diff --git a/dev/core/src/com/google/gwt/dev/jdt/BasicWebModeCompiler.java b/dev/core/src/com/google/gwt/dev/jdt/BasicWebModeCompiler.java
index 2174d0e..575d60a 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/BasicWebModeCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/BasicWebModeCompiler.java
@@ -69,7 +69,7 @@
       ICompilationUnit... additionalUnits) throws UnableToCompleteException {
 
     TypeOracle oracle = compilationState.getTypeOracle();
-    Set<JClassType> intfTypes = oracle.getSingleJsoImplInterfaces();
+    Set<? extends JClassType> intfTypes = oracle.getSingleJsoImplInterfaces();
     Map<String, CompiledClass> classMapBySource = compilationState.getClassFileMapBySource();
 
     /*
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CC.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CC.java
deleted file mode 100644
index 62ca353..0000000
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CC.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.google.gwt.core.ext.typeinfo.test;
-
-public abstract class CC extends CB implements IC {
-
-}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/IA.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/IA.java
deleted file mode 100644
index cfc4a56..0000000
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/IA.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.google.gwt.core.ext.typeinfo.test;
-
-public interface IA {
-
-  void foo(); 
-  
-  void ia();
-
-  void ia(int x, Object y);
-}
diff --git a/dev/core/test/com/google/gwt/dev/javac/JavaSourceParserTest.java b/dev/core/test/com/google/gwt/dev/javac/JavaSourceParserTest.java
index db82f33..2b7b4e8 100644
--- a/dev/core/test/com/google/gwt/dev/javac/JavaSourceParserTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/JavaSourceParserTest.java
@@ -15,12 +15,12 @@
  */
 package com.google.gwt.dev.javac;
 
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JMethod;
 import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
 import com.google.gwt.core.ext.typeinfo.JType;
 import com.google.gwt.core.ext.typeinfo.NotFoundException;
 import com.google.gwt.dev.javac.impl.MockJavaResource;
+import com.google.gwt.dev.javac.typemodel.JClassType;
+import com.google.gwt.dev.javac.typemodel.JMethod;
 
 import java.util.Arrays;
 import java.util.List;
diff --git a/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java b/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java
index 3d5198c..ba096e9 100644
--- a/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java
@@ -15,8 +15,8 @@
  */
 package com.google.gwt.dev.javac.asm;
 
-import com.google.gwt.core.ext.typeinfo.test.PrimitiveValuesAnnotation;
-import com.google.gwt.core.ext.typeinfo.test.TestAnnotation;
+import com.google.gwt.dev.javac.typemodel.test.PrimitiveValuesAnnotation;
+import com.google.gwt.dev.javac.typemodel.test.TestAnnotation;
 import com.google.gwt.dev.asm.AnnotationVisitor;
 import com.google.gwt.dev.asm.ClassReader;
 import com.google.gwt.dev.asm.Opcodes;
@@ -183,7 +183,7 @@
     annotations = field.getAnnotations();
     assertEquals(1, annotations.size());
     AnnotationData annotation = annotations.get(0).getAnnotation();
-    assertEquals("Lcom/google/gwt/core/ext/typeinfo/test/TestAnnotation;",
+    assertEquals("Lcom/google/gwt/dev/javac/typemodel/test/TestAnnotation;",
         annotation.getDesc());
     assertEquals("field", annotation.getValues().get("value"));
     assertEquals(0, cd.getInterfaces().length);
@@ -191,7 +191,7 @@
     assertEquals(1, annotations.size());
     annotation = annotations.get(0).getAnnotation();
     assertEquals(
-        "Lcom/google/gwt/core/ext/typeinfo/test/PrimitiveValuesAnnotation;",
+        "Lcom/google/gwt/dev/javac/typemodel/test/PrimitiveValuesAnnotation;",
         annotation.getDesc());
     assertEquals(Byte.valueOf((byte) 42), annotation.getValues().get("b"));
     assertEquals(42, annotation.getValues().get("i"));
diff --git a/dev/core/test/com/google/gwt/dev/javac/asm/CollectReferencesVisitorTest.java b/dev/core/test/com/google/gwt/dev/javac/asm/CollectReferencesVisitorTest.java
index 86b9318..42bb6f8 100644
--- a/dev/core/test/com/google/gwt/dev/javac/asm/CollectReferencesVisitorTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/asm/CollectReferencesVisitorTest.java
@@ -15,7 +15,7 @@
  */
 package com.google.gwt.dev.javac.asm;
 
-import com.google.gwt.core.ext.typeinfo.test.TestAnnotation;
+import com.google.gwt.dev.javac.typemodel.test.TestAnnotation;
 import com.google.gwt.dev.asm.ClassReader;
 import com.google.gwt.dev.util.Name.BinaryName;
 
diff --git a/dev/core/test/com/google/gwt/dev/javac/asm/ResolveGenericsTest.java b/dev/core/test/com/google/gwt/dev/javac/asm/ResolveGenericsTest.java
index 88fc195..1191ec4 100644
--- a/dev/core/test/com/google/gwt/dev/javac/asm/ResolveGenericsTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/asm/ResolveGenericsTest.java
@@ -16,15 +16,7 @@
 package com.google.gwt.dev.javac.asm;
 
 import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JGenericType;
-import com.google.gwt.core.ext.typeinfo.JMethod;
-import com.google.gwt.core.ext.typeinfo.JPackage;
-import com.google.gwt.core.ext.typeinfo.JRealClassType;
 import com.google.gwt.core.ext.typeinfo.JType;
-import com.google.gwt.core.ext.typeinfo.JTypeParameter;
-import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.dev.asm.Opcodes;
 import com.google.gwt.dev.asm.Type;
 import com.google.gwt.dev.asm.signature.SignatureReader;
@@ -34,6 +26,14 @@
 import com.google.gwt.dev.javac.TypeOracleTestingUtils;
 import com.google.gwt.dev.javac.TypeParameterLookup;
 import com.google.gwt.dev.javac.asm.CollectClassData.ClassType;
+import com.google.gwt.dev.javac.typemodel.JAbstractMethod;
+import com.google.gwt.dev.javac.typemodel.JClassType;
+import com.google.gwt.dev.javac.typemodel.JGenericType;
+import com.google.gwt.dev.javac.typemodel.JMethod;
+import com.google.gwt.dev.javac.typemodel.JPackage;
+import com.google.gwt.dev.javac.typemodel.JRealClassType;
+import com.google.gwt.dev.javac.typemodel.JTypeParameter;
+import com.google.gwt.dev.javac.typemodel.TypeOracle;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
@@ -83,7 +83,7 @@
       delegate.addImplementedInterface(type, intf);
     }
 
-    public void addThrows(JAbstractMethod method, JType exception) {
+    public void addThrows(JAbstractMethod method, JClassType exception) {
       delegate.addThrows(method, exception);
     }
 
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/AnnotationsTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/AnnotationsTest.java
similarity index 98%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/AnnotationsTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/AnnotationsTest.java
index ac59e99..2c2fc65 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/AnnotationsTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/AnnotationsTest.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.dev.util.collect.IdentityHashMap;
 
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/BinaryOnlyAnnotation.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/BinaryOnlyAnnotation.java
similarity index 95%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/BinaryOnlyAnnotation.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/BinaryOnlyAnnotation.java
index 02e25aa..c4db3d4 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/BinaryOnlyAnnotation.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/BinaryOnlyAnnotation.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import java.io.File;
 
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/BinaryOnlyClass.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/BinaryOnlyClass.java
similarity index 94%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/BinaryOnlyClass.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/BinaryOnlyClass.java
index 38c880e..2491908 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/BinaryOnlyClass.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/BinaryOnlyClass.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 /**
  * This class is defined outside of a GWT module, therefore it should only be
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JAbstractMethodTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/JAbstractMethodTest.java
similarity index 93%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/JAbstractMethodTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/JAbstractMethodTest.java
index d59d336..ee76727 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JAbstractMethodTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/JAbstractMethodTest.java
@@ -13,12 +13,13 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.typeinfo.test.GenericClassWithDependentTypeBounds;
-import com.google.gwt.core.ext.typeinfo.test.GenericClassWithTypeBound;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.javac.typemodel.test.GenericClassWithDependentTypeBounds;
+import com.google.gwt.dev.javac.typemodel.test.GenericClassWithTypeBound;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 
 import junit.framework.TestCase;
@@ -32,7 +33,7 @@
   private final boolean logToConsole = false;
   private final ModuleContext moduleContext = new ModuleContext(logToConsole
       ? new PrintWriterTreeLogger() : TreeLogger.NULL,
-      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+      "com.google.gwt.dev.javac.typemodel.TypeOracleTest");
 
   public JAbstractMethodTest() throws UnableToCompleteException {
   }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JArrayTypeTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/JArrayTypeTest.java
similarity index 93%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/JArrayTypeTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/JArrayTypeTest.java
index e3b33aa..ab21a45 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JArrayTypeTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/JArrayTypeTest.java
@@ -13,13 +13,15 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.typeinfo.test.CB;
-import com.google.gwt.core.ext.typeinfo.test.MyCustomList;
-import com.google.gwt.core.ext.typeinfo.test.MyList;
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.javac.typemodel.test.CB;
+import com.google.gwt.dev.javac.typemodel.test.MyCustomList;
+import com.google.gwt.dev.javac.typemodel.test.MyList;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 
 import junit.framework.TestCase;
@@ -60,7 +62,7 @@
 
   private final ModuleContext moduleContext = new ModuleContext(logToConsole
       ? new PrintWriterTreeLogger() : TreeLogger.NULL,
-      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+      "com.google.gwt.dev.javac.typemodel.TypeOracleTest");
 
   public JArrayTypeTest() throws UnableToCompleteException {
   }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/JClassTypeTest.java
similarity index 60%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/JClassTypeTest.java
index 8b58710..8ba7d90 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/JClassTypeTest.java
@@ -13,10 +13,12 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.TypeOracleException;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 
 import junit.framework.TestCase;
@@ -28,7 +30,7 @@
   private final boolean logToConsole = false;
   private final ModuleContext moduleContext = new ModuleContext(logToConsole
       ? new PrintWriterTreeLogger() : TreeLogger.NULL,
-      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+      "com.google.gwt.dev.javac.typemodel.TypeOracleTest");
 
   public JClassTypeTest() throws UnableToCompleteException {
   }
@@ -43,111 +45,111 @@
 
     // Verify IA.
     {
-      JClassType type = typeOracle.getType("com.google.gwt.core.ext.typeinfo.test.IA");
+      JClassType type = typeOracle.getType("com.google.gwt.dev.javac.typemodel.test.IA");
       JMethod[] leafMethods = type.getOverridableMethods();
       assertEquals(3, leafMethods.length);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.IA", "ia", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.IA", "ia", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.IA", "ia", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.IA", "ia", intObjectParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.IA", "foo", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.IA", "foo", noParams);
     }
 
     // Verify IB.
     {
-      JClassType type = typeOracle.getType("com.google.gwt.core.ext.typeinfo.test.IB");
+      JClassType type = typeOracle.getType("com.google.gwt.dev.javac.typemodel.test.IB");
       JMethod[] leafMethods = type.getOverridableMethods();
       assertEquals(5, leafMethods.length);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.IB", "ia", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.IB", "ia", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.IB", "ia", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.IB", "ia", intObjectParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IB",
-          "com.google.gwt.core.ext.typeinfo.test.IB", "ib", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IB",
+          "com.google.gwt.dev.javac.typemodel.test.IB", "ib", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IB",
-          "com.google.gwt.core.ext.typeinfo.test.IB", "ib", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IB",
+          "com.google.gwt.dev.javac.typemodel.test.IB", "ib", intObjectParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IB",
-          "com.google.gwt.core.ext.typeinfo.test.IB", "foo", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IB",
+          "com.google.gwt.dev.javac.typemodel.test.IB", "foo", noParams);
     }
 
     // Verify IC.
     {
-      JClassType type = typeOracle.getType("com.google.gwt.core.ext.typeinfo.test.IC");
+      JClassType type = typeOracle.getType("com.google.gwt.dev.javac.typemodel.test.IC");
       JMethod[] leafMethods = type.getOverridableMethods();
       assertEquals(7, leafMethods.length);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.IC", "ia", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.IC", "ia", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.IC", "ia", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.IC", "ia", intObjectParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IC",
-          "com.google.gwt.core.ext.typeinfo.test.IC", "ib", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IC",
+          "com.google.gwt.dev.javac.typemodel.test.IC", "ib", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IC",
-          "com.google.gwt.core.ext.typeinfo.test.IC", "ib", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IC",
+          "com.google.gwt.dev.javac.typemodel.test.IC", "ib", intObjectParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IC",
-          "com.google.gwt.core.ext.typeinfo.test.IC", "ic", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IC",
+          "com.google.gwt.dev.javac.typemodel.test.IC", "ic", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IC",
-          "com.google.gwt.core.ext.typeinfo.test.IC", "ic", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IC",
+          "com.google.gwt.dev.javac.typemodel.test.IC", "ic", intObjectParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IB",
-          "com.google.gwt.core.ext.typeinfo.test.IC", "foo", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IB",
+          "com.google.gwt.dev.javac.typemodel.test.IC", "foo", noParams);
     }
 
     // Both overloads of ia are only declared in IA, so all searches should find
     // them there.
     {
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.CA", "ia", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.CA", "ia", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.CB", "ia", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.CB", "ia", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.CC", "ia", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.CC", "ia", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.CA", "ia", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.CA", "ia", intObjectParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.CB", "ia", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.CB", "ia", intObjectParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.CC", "ia", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.CC", "ia", intObjectParams);
     }
 
     // Both overloads of ib are declared in both IB and IC, so
@@ -155,20 +157,20 @@
     // - searching for ib in CC will return IC
     {
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IB",
-          "com.google.gwt.core.ext.typeinfo.test.CB", "ib", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IB",
+          "com.google.gwt.dev.javac.typemodel.test.CB", "ib", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IC",
-          "com.google.gwt.core.ext.typeinfo.test.CC", "ib", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IC",
+          "com.google.gwt.dev.javac.typemodel.test.CC", "ib", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IB",
-          "com.google.gwt.core.ext.typeinfo.test.CB", "ib", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IB",
+          "com.google.gwt.dev.javac.typemodel.test.CB", "ib", intObjectParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IC",
-          "com.google.gwt.core.ext.typeinfo.test.CC", "ib", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IC",
+          "com.google.gwt.dev.javac.typemodel.test.CC", "ib", intObjectParams);
     }
 
     // Both overloads of ic are declared only in IC, but ic() is also declared
@@ -178,16 +180,16 @@
     // - searching for ic(int, Object) in CC will return IC
     {
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.CB",
-          "com.google.gwt.core.ext.typeinfo.test.CB", "ic", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.CB",
+          "com.google.gwt.dev.javac.typemodel.test.CB", "ic", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.CB",
-          "com.google.gwt.core.ext.typeinfo.test.CC", "ic", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.CB",
+          "com.google.gwt.dev.javac.typemodel.test.CC", "ic", noParams);
 
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IC",
-          "com.google.gwt.core.ext.typeinfo.test.CC", "ic", intObjectParams);
+          "com.google.gwt.dev.javac.typemodel.test.IC",
+          "com.google.gwt.dev.javac.typemodel.test.CC", "ic", intObjectParams);
     }
 
     // Both IA and IB define foo(), and searching for foo() on IC should return
@@ -195,8 +197,8 @@
     // for getLeafMethods() might prefer IA.foo() to IB.foo().
     {
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IB",
-          "com.google.gwt.core.ext.typeinfo.test.IC", "foo", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IB",
+          "com.google.gwt.dev.javac.typemodel.test.IC", "foo", noParams);
     }
 
     // Both IA and CB define foo(), foo() being final in CB, so searching for
@@ -205,29 +207,29 @@
     // overridable.
     {
       assertMethodOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.IA",
-          "com.google.gwt.core.ext.typeinfo.test.CA", "foo", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.IA",
+          "com.google.gwt.dev.javac.typemodel.test.CA", "foo", noParams);
 
       assertMethodInheritableNotOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.CB",
-          "com.google.gwt.core.ext.typeinfo.test.CB", "foo", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.CB",
+          "com.google.gwt.dev.javac.typemodel.test.CB", "foo", noParams);
 
       assertMethodInheritableNotOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.CB",
-          "com.google.gwt.core.ext.typeinfo.test.CC", "foo", noParams);
+          "com.google.gwt.dev.javac.typemodel.test.CB",
+          "com.google.gwt.dev.javac.typemodel.test.CC", "foo", noParams);
 
       // Check that we aren't including methods that aren't actually overridable
       // (but are inheritable) because they are final (but non-private).
       assertMethodInheritableNotOverridable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.CA",
-          "com.google.gwt.core.ext.typeinfo.test.CA", "caNotOverridableFinal",
-          noParams);
+          "com.google.gwt.dev.javac.typemodel.test.CA",
+          "com.google.gwt.dev.javac.typemodel.test.CA",
+          "caNotOverridableFinal", noParams);
 
       // Check that we aren't including methods that aren't actually inheritable
       // because they are private.
       assertMethodNotInheritable(typeOracle,
-          "com.google.gwt.core.ext.typeinfo.test.CA",
-          "com.google.gwt.core.ext.typeinfo.test.CA",
+          "com.google.gwt.dev.javac.typemodel.test.CA",
+          "com.google.gwt.dev.javac.typemodel.test.CA",
           "caNotOverridablePrivate", noParams);
     }
   }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JDelegatingClassTypeTestBase.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/JDelegatingClassTypeTestBase.java
similarity index 94%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/JDelegatingClassTypeTestBase.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/JDelegatingClassTypeTestBase.java
index 498fcc4..aa7406d 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JDelegatingClassTypeTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/JDelegatingClassTypeTestBase.java
@@ -13,7 +13,10 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
+
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
 
 import junit.framework.TestCase;
 
@@ -62,15 +65,24 @@
       validateAnnotations(preSubParam.getAnnotations(),
           postSubParam.getAnnotations());
 
-      assertEquals(substitution.getSubstitution(preSubParam.getType()),
+      assertEquals(substitute(substitution, preSubParam.getType()),
           postSubParam.getType());
     }
 
-    JType[] preSubThrows = preSubMethod.getThrows();
-    JType[] postSubThrows = postSubMethod.getThrows();
+    JClassType[] preSubThrows = preSubMethod.getThrows();
+    JClassType[] postSubThrows = postSubMethod.getThrows();
     assertArraysEqual(preSubThrows, postSubThrows);
   }
 
+  private static JType substitute(Substitution substitution, JType type) {
+    if (!(type instanceof JClassType)) {
+      return type;
+    }
+    JClassType t2 = (JClassType) type;
+    JType substitution2 = substitution.getSubstitution(t2);
+    return substitution2;
+  }
+
   protected static void validateAnnotations(Annotation[] expected,
       Annotation[] actual) {
     Arrays.sort(expected, ANNOTATION_COMPARATOR);
@@ -115,7 +127,7 @@
     for (int i = 0; i < preSubfields.length; ++i) {
       JField postSubField = postSubstituion.getField(preSubfields[i].getName());
       assertNotNull(postSubField);
-      assertEquals(substitution.getSubstitution(preSubfields[i].getType()),
+      assertEquals(substitute(substitution, preSubfields[i].getType()),
           postSubField.getType());
     }
   }
@@ -129,7 +141,7 @@
       JType[] paramTypes = new JType[params.length];
 
       for (int i = 0; i < params.length; ++i) {
-        paramTypes[i] = substitution.getSubstitution(params[i].getType());
+        paramTypes[i] = substitute(substitution, params[i].getType());
       }
 
       assertNotNull(postSubstitution.findConstructor(paramTypes));
@@ -156,7 +168,7 @@
       JType[] paramTypes = new JType[params.length];
 
       for (int i = 0; i < params.length; ++i) {
-        paramTypes[i] = substitution.getSubstitution(params[i].getType());
+        paramTypes[i] = substitute(substitution, params[i].getType());
       }
 
       assertNotNull(postSubstitution.findMethod(method.getName(), paramTypes));
@@ -173,7 +185,7 @@
       JType[] paramTypes = new JType[params.length];
 
       for (int i = 0; i < params.length; ++i) {
-        paramTypes[i] = substitution.getSubstitution(params[i].getType());
+        paramTypes[i] = substitute(substitution, params[i].getType());
       }
 
       assertNotNull(postSubstitution.getConstructor(paramTypes));
@@ -201,7 +213,7 @@
       JType[] paramTypes = new JType[params.length];
 
       for (int i = 0; i < params.length; ++i) {
-        paramTypes[i] = substitution.getSubstitution(params[i].getType());
+        paramTypes[i] = substitute(substitution, params[i].getType());
       }
 
       assertNotNull(postSubstitution.getMethod(method.getName(), paramTypes));
@@ -234,7 +246,7 @@
   protected static void validateMethodSubstitution(JMethod preSubMethod,
       JMethod postSubMethod, Substitution substitution) {
 
-    assertEquals(substitution.getSubstitution(preSubMethod.getReturnType()),
+    assertEquals(substitute(substitution, preSubMethod.getReturnType()),
         postSubMethod.getReturnType());
 
     validateAbstractMethodSubstitution(preSubMethod, postSubMethod,
@@ -255,7 +267,8 @@
       JParameter[] preSubParams = preSubMethod.getParameters();
       JType[] postSubParamTypes = new JType[preSubParams.length];
       for (int j = 0; j < preSubParams.length; ++j) {
-        postSubParamTypes[j] = substitution.getSubstitution(preSubParams[j].getType());
+        postSubParamTypes[j] = substitute(substitution,
+            preSubParams[j].getType());
       }
       JMethod postSubMethod = postSubstituion.getMethod(preSubMethod.getName(),
           postSubParamTypes);
@@ -302,7 +315,7 @@
 
   /**
    * Test method for
-   * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#findConstructor(com.google.gwt.core.ext.typeinfo.JType[])}
+   * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#findConstructor(JType[])}
    * .
    */
   public void testFindConstructor() throws NotFoundException {
@@ -326,7 +339,7 @@
 
   /**
    * Test method for
-   * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#findMethod(java.lang.String, com.google.gwt.core.ext.typeinfo.JType[])}
+   * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#findMethod(java.lang.String, JType[])}
    * .
    */
   public void testFindMethod() throws NotFoundException {
@@ -382,7 +395,7 @@
 
   /**
    * Test method for
-   * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getConstructor(com.google.gwt.core.ext.typeinfo.JType[])}
+   * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getConstructor(JType[])}
    * .
    */
   public void testGetConstructor() throws NotFoundException {
@@ -488,7 +501,7 @@
 
   /**
    * Test method for
-   * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getMethod(java.lang.String, com.google.gwt.core.ext.typeinfo.JType[])}
+   * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getMethod(java.lang.String, JType[])}
    * .
    */
   public void testGetMethod() throws NotFoundException {
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JEnumTypeTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/JEnumTypeTest.java
similarity index 91%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/JEnumTypeTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/JEnumTypeTest.java
index 06d959b..89cb694 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JEnumTypeTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/JEnumTypeTest.java
@@ -13,14 +13,15 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.typeinfo.test.EnumInterface;
-import com.google.gwt.core.ext.typeinfo.test.EnumOfInterface;
-import com.google.gwt.core.ext.typeinfo.test.MyEnum;
-import com.google.gwt.core.ext.typeinfo.test.TestAnnotation;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.javac.typemodel.test.EnumInterface;
+import com.google.gwt.dev.javac.typemodel.test.EnumOfInterface;
+import com.google.gwt.dev.javac.typemodel.test.MyEnum;
+import com.google.gwt.dev.javac.typemodel.test.TestAnnotation;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 
 import junit.framework.TestCase;
@@ -34,7 +35,7 @@
 
   private final ModuleContext moduleContext = new ModuleContext(logToConsole
       ? new PrintWriterTreeLogger() : TreeLogger.NULL,
-      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+      "com.google.gwt.dev.javac.typemodel.TypeOracleTest");
 
   public JEnumTypeTest() throws UnableToCompleteException {
   }
@@ -136,7 +137,7 @@
     assertEquals(1, intf.length);
     assertEquals(EnumInterface.class.getName(),
         intf[0].getQualifiedSourceName());
-    JMethod getExtra = intf[0].getMethod("getExtra", new JType[0]);
+    JMethod getExtra = intf[0].getMethod("getExtra", TypeOracle.NO_JTYPES);
     TestAnnotation annotation = getExtra.getAnnotation(TestAnnotation.class);
     assertNotNull(annotation);
     assertEquals("EnumInterface getExtra", annotation.value());
@@ -146,7 +147,7 @@
     annotation = constants[0].getAnnotation(TestAnnotation.class);
     assertNotNull(annotation);
     assertEquals("A", annotation.value());
-    JClassType aClass = constants[0].getType().isClass();
+    JClassType aClass = (JClassType) constants[0].getType().isClass();
     {
       JMethod[] methods = aClass.getInheritableMethods();
       assertEquals(11, methods.length);
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JGenericTypeTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/JGenericTypeTest.java
similarity index 94%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/JGenericTypeTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/JGenericTypeTest.java
index ce42ca3..13f114c 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JGenericTypeTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/JGenericTypeTest.java
@@ -13,13 +13,14 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.typeinfo.test.GenericClass;
-import com.google.gwt.core.ext.typeinfo.test.GenericClassWithDependentTypeBounds;
-import com.google.gwt.core.ext.typeinfo.test.GenericClassWithTypeBound;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.javac.typemodel.test.GenericClass;
+import com.google.gwt.dev.javac.typemodel.test.GenericClassWithDependentTypeBounds;
+import com.google.gwt.dev.javac.typemodel.test.GenericClassWithTypeBound;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 
 import junit.framework.TestCase;
@@ -33,7 +34,7 @@
   private final boolean logToConsole = false;
   private final ModuleContext moduleContext = new ModuleContext(logToConsole
       ? new PrintWriterTreeLogger() : TreeLogger.NULL,
-      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+      "com.google.gwt.dev.javac.typemodel.TypeOracleTest");
 
   public JGenericTypeTest() throws UnableToCompleteException {
   }
@@ -153,7 +154,7 @@
 
     JDelegatingClassTypeTestBase.validateTypeSubstitution(genericClass,
         genericClass.getRawType(), new Substitution() {
-          public JType getSubstitution(JType type) {
+          public JClassType getSubstitution(JClassType type) {
             return type.getErasedType();
           }
         });
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JParameterizedTypeTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/JParameterizedTypeTest.java
similarity index 95%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/JParameterizedTypeTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/JParameterizedTypeTest.java
index 793249f..cf0e2e1 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JParameterizedTypeTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/JParameterizedTypeTest.java
@@ -13,19 +13,21 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
 import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
-import com.google.gwt.core.ext.typeinfo.test.Base;
-import com.google.gwt.core.ext.typeinfo.test.Derived;
-import com.google.gwt.core.ext.typeinfo.test.ExtendsRawGenericClass;
-import com.google.gwt.core.ext.typeinfo.test.GenericClass;
-import com.google.gwt.core.ext.typeinfo.test.MyCustomList;
-import com.google.gwt.core.ext.typeinfo.test.MyIntegerList;
-import com.google.gwt.core.ext.typeinfo.test.MyList;
-import com.google.gwt.core.ext.typeinfo.test.GenericClass.GenericInnerClass;
+import com.google.gwt.dev.javac.typemodel.test.Base;
+import com.google.gwt.dev.javac.typemodel.test.Derived;
+import com.google.gwt.dev.javac.typemodel.test.ExtendsRawGenericClass;
+import com.google.gwt.dev.javac.typemodel.test.GenericClass;
+import com.google.gwt.dev.javac.typemodel.test.MyCustomList;
+import com.google.gwt.dev.javac.typemodel.test.MyIntegerList;
+import com.google.gwt.dev.javac.typemodel.test.MyList;
+import com.google.gwt.dev.javac.typemodel.test.GenericClass.GenericInnerClass;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 
 import java.io.Serializable;
@@ -50,7 +52,7 @@
       this.parameterizedType = parameterizedType;
     }
 
-    public JType getSubstitution(JType type) {
+    public JClassType getSubstitution(JClassType type) {
       return type.getSubstitutedType(parameterizedType);
     }
   }
@@ -59,7 +61,7 @@
   private final boolean logToConsole = false;
   private final ModuleContext moduleContext = new ModuleContext(logToConsole
       ? new PrintWriterTreeLogger() : TreeLogger.NULL,
-      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+      "com.google.gwt.dev.javac.typemodel.TypeOracleTest");
 
   public JParameterizedTypeTest() throws UnableToCompleteException,
       NotFoundException {
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JRawTypeTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/JRawTypeTest.java
similarity index 88%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/JRawTypeTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/JRawTypeTest.java
index fa05528..919ee08 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JRawTypeTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/JRawTypeTest.java
@@ -13,13 +13,14 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.typeinfo.test.MyCustomList;
-import com.google.gwt.core.ext.typeinfo.test.MyIntegerList;
-import com.google.gwt.core.ext.typeinfo.test.MyList;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.javac.typemodel.test.MyCustomList;
+import com.google.gwt.dev.javac.typemodel.test.MyIntegerList;
+import com.google.gwt.dev.javac.typemodel.test.MyList;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 
 import java.util.ArrayList;
@@ -32,7 +33,7 @@
 
   private final ModuleContext moduleContext = new ModuleContext(logToConsole
       ? new PrintWriterTreeLogger() : TreeLogger.NULL,
-      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+      "com.google.gwt.dev.javac.typemodel.TypeOracleTest");
 
   public JRawTypeTest() throws UnableToCompleteException {
   }
@@ -98,7 +99,7 @@
   @Override
   protected Substitution getSubstitution() throws NotFoundException {
     return new Substitution() {
-      public JType getSubstitution(JType type) {
+      public JClassType getSubstitution(JClassType type) {
         return type.getErasedType();
       }
     };
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JTypeParameterTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/JTypeParameterTest.java
similarity index 94%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/JTypeParameterTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/JTypeParameterTest.java
index 583c2ac..147acac 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JTypeParameterTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/JTypeParameterTest.java
@@ -13,12 +13,13 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.typeinfo.test.GenericClass;
-import com.google.gwt.core.ext.typeinfo.test.MyCustomList;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.javac.typemodel.test.GenericClass;
+import com.google.gwt.dev.javac.typemodel.test.MyCustomList;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 
 import java.io.Serializable;
@@ -46,7 +47,7 @@
   private final boolean logToConsole = false;
   private final ModuleContext moduleContext = new ModuleContext(logToConsole
       ? new PrintWriterTreeLogger() : TreeLogger.NULL,
-      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+      "com.google.gwt.dev.javac.typemodel.TypeOracleTest");
 
   public JTypeParameterTest() throws UnableToCompleteException {
   }
@@ -162,7 +163,7 @@
   @Override
   protected Substitution getSubstitution() {
     return new Substitution() {
-      public JType getSubstitution(JType type) {
+      public JClassType getSubstitution(JClassType type) {
         return type;
       }
     };
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JWildcardTypeTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/JWildcardTypeTest.java
similarity index 96%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/JWildcardTypeTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/JWildcardTypeTest.java
index d5ecc0b..32c6d12 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JWildcardTypeTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/JWildcardTypeTest.java
@@ -13,14 +13,15 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
 import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
-import com.google.gwt.core.ext.typeinfo.test.CA;
-import com.google.gwt.core.ext.typeinfo.test.CB;
-import com.google.gwt.core.ext.typeinfo.test.CC;
+import com.google.gwt.dev.javac.typemodel.test.CA;
+import com.google.gwt.dev.javac.typemodel.test.CB;
+import com.google.gwt.dev.javac.typemodel.test.CC;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 
 import java.util.Arrays;
@@ -34,7 +35,7 @@
   private final boolean logToConsole = false;
   private final ModuleContext moduleContext = new ModuleContext(logToConsole
       ? new PrintWriterTreeLogger() : TreeLogger.NULL,
-      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+      "com.google.gwt.dev.javac.typemodel.TypeOracleTest");
 
   public JWildcardTypeTest() throws UnableToCompleteException {
   }
@@ -330,7 +331,7 @@
   @Override
   protected Substitution getSubstitution() {
     return new Substitution() {
-      public JType getSubstitution(JType type) {
+      public JClassType getSubstitution(JClassType type) {
         return type;
       }
     };
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/ModuleContext.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/ModuleContext.java
similarity index 97%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/ModuleContext.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/ModuleContext.java
index 23d9c57..ad2ea2f 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/ModuleContext.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/ModuleContext.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleAnnotationSupportTest.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/TypeOracleAnnotationSupportTest.java
similarity index 89%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleAnnotationSupportTest.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/TypeOracleAnnotationSupportTest.java
index 2a27830..cacf00c 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleAnnotationSupportTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/TypeOracleAnnotationSupportTest.java
@@ -13,17 +13,21 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.typeinfo.test.AnnotatedClass;
-import com.google.gwt.core.ext.typeinfo.test.ClassAnnotatedWithBinaryOnlyAnnotation;
-import com.google.gwt.core.ext.typeinfo.test.ClassLiteralReferenceAnnotation;
-import com.google.gwt.core.ext.typeinfo.test.PrimitiveValuesAnnotation;
-import com.google.gwt.core.ext.typeinfo.test.PrimitivesAnnotatedClass;
-import com.google.gwt.core.ext.typeinfo.test.SourceRetentionAnnotation;
-import com.google.gwt.core.ext.typeinfo.test.TestAnnotation;
+import com.google.gwt.core.ext.typeinfo.HasAnnotations;
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.dev.javac.typemodel.test.AnnotatedClass;
+import com.google.gwt.dev.javac.typemodel.test.ClassAnnotatedWithBinaryOnlyAnnotation;
+import com.google.gwt.dev.javac.typemodel.test.ClassLiteralReferenceAnnotation;
+import com.google.gwt.dev.javac.typemodel.test.PrimitiveValuesAnnotation;
+import com.google.gwt.dev.javac.typemodel.test.PrimitivesAnnotatedClass;
+import com.google.gwt.dev.javac.typemodel.test.SourceRetentionAnnotation;
+import com.google.gwt.dev.javac.typemodel.test.TestAnnotation;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 
 import junit.framework.TestCase;
@@ -91,7 +95,7 @@
   private final boolean logToConsole = false;
   private final ModuleContext moduleContext = new ModuleContext(logToConsole
       ? new PrintWriterTreeLogger() : TreeLogger.NULL,
-      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+      "com.google.gwt.dev.javac.typemodel.TypeOracleTest");
 
   private final TypeOracle typeOracle = moduleContext.getOracle();
 
@@ -120,7 +124,7 @@
   public void testAnnotatedConstructor() throws NotFoundException,
       SecurityException, NoSuchMethodException {
     JClassType annotatedClass = typeOracle.getType(AnnotatedClass.class.getName());
-    JConstructor ctor = annotatedClass.getConstructor(new JType[0]);
+    JConstructor ctor = annotatedClass.getConstructor(TypeOracle.NO_JTYPES);
 
     Constructor<AnnotatedClass> constructor = AnnotatedClass.class.getConstructor();
     TestAnnotation realAnnotation = constructor.getAnnotation(TestAnnotation.class);
@@ -149,7 +153,7 @@
       SecurityException, NoSuchMethodException {
     JClassType annotatedClass = typeOracle.getType(AnnotatedClass.class.getName());
     JMethod annotatedMethod = annotatedClass.getMethod("annotatedMethod",
-        new JType[0]);
+        TypeOracle.NO_JTYPES);
 
     Method method = AnnotatedClass.class.getDeclaredMethod("annotatedMethod");
     TestAnnotation realAnnotation = method.getAnnotation(TestAnnotation.class);
@@ -164,11 +168,11 @@
    */
   public void testAnnotatedPackage() throws NotFoundException,
       ClassNotFoundException {
-    JPackage annotatedPackage = typeOracle.getPackage("com.google.gwt.core.ext.typeinfo.test");
+    JPackage annotatedPackage = typeOracle.getPackage("com.google.gwt.dev.javac.typemodel.test");
     assertNotNull(annotatedPackage);
 
     TestAnnotation realAnnotation = Class.forName(
-        "com.google.gwt.core.ext.typeinfo.test.package-info", false,
+        "com.google.gwt.dev.javac.typemodel.test.package-info", false,
         TypeOracleAnnotationSupportTest.class.getClassLoader()).getAnnotation(
         TestAnnotation.class);
 
@@ -198,7 +202,7 @@
       SecurityException, NoSuchMethodException {
     JClassType annotatedClass = typeOracle.getType(AnnotatedClass.class.getName());
     JMethod annotatedMethod = annotatedClass.getMethod(
-        "annotatedWithArrayOfClasses", new JType[0]);
+        "annotatedWithArrayOfClasses", TypeOracle.NO_JTYPES);
 
     Method method = AnnotatedClass.class.getDeclaredMethod("annotatedWithArrayOfClasses");
     TestAnnotation realAnnotation = method.getAnnotation(TestAnnotation.class);
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleSuite.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/TypeOracleSuite.java
similarity index 96%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleSuite.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/TypeOracleSuite.java
index 54dadb2..96b730a 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleSuite.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/TypeOracleSuite.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo;
+package com.google.gwt.dev.javac.typemodel;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleTest.gwt.xml b/dev/core/test/com/google/gwt/dev/javac/typemodel/TypeOracleTest.gwt.xml
similarity index 100%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleTest.gwt.xml
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/TypeOracleTest.gwt.xml
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/AnnotatedAnnotation.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/AnnotatedAnnotation.java
similarity index 93%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/AnnotatedAnnotation.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/AnnotatedAnnotation.java
index 77e666c..eb52600 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/AnnotatedAnnotation.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/AnnotatedAnnotation.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 /**
  * Tests that an annotation can be annotated.
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/AnnotatedClass.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/AnnotatedClass.java
similarity index 70%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/AnnotatedClass.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/AnnotatedClass.java
index 5057b5a..53a468b 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/AnnotatedClass.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/AnnotatedClass.java
@@ -13,14 +13,14 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
-import com.google.gwt.core.ext.typeinfo.test.ClassLiteralReferenceAnnotation.Foo;
+import com.google.gwt.dev.javac.typemodel.test.ClassLiteralReferenceAnnotation.Foo;
 
 /**
- * Used to test that a
- * {@link com.google.gwt.core.ext.typeinfo.TypeOracle TypeOracle} will correctly
- * report the presence of annotations on the different annotatable elements.
+ * Used to test that a {@link com.google.gwt.core.ext.typeinfo.TypeOracle
+ * TypeOracle} will correctly report the presence of annotations on the
+ * different annotatable elements.
  */
 @SourceRetentionAnnotation
 @ClassLiteralReferenceAnnotation(Foo.class)
@@ -40,12 +40,12 @@
   public void annotatedMethod() {
   }
 
-  public void methodWithAnnotatedParameter(@SourceRetentionAnnotation
-  @TestAnnotation("Parameter")
-  int annotatedParameter) {
+  public void methodWithAnnotatedParameter(
+      @SourceRetentionAnnotation @TestAnnotation("Parameter") int annotatedParameter) {
   }
-  
-  @TestAnnotation(value = "Method", arrayWithImplicitArrayInitializer = {String.class, Foo.class})
+
+  @TestAnnotation(value = "Method", arrayWithImplicitArrayInitializer = {
+      String.class, Foo.class})
   void annotatedWithArrayOfClasses() {
   }
 }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/Base.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/Base.java
similarity index 95%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/Base.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/Base.java
index 8300078..a5b5830 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/Base.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/Base.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.io.Serializable;
 
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CA.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/CA.java
similarity index 72%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/CA.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/CA.java
index 605285a..104b96f 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CA.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/CA.java
@@ -1,11 +1,11 @@
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 public abstract class CA implements IA {
-  
+
   public final void caNotOverridableFinal() {
   }
-  
+
   private final void caNotOverridablePrivate() {
   }
-  
+
 }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CB.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/CB.java
similarity index 70%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/CB.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/CB.java
index 3e41990..c6cc31e 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CB.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/CB.java
@@ -1,4 +1,4 @@
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 public abstract class CB extends CA implements IB {
 
diff --git a/dev/core/test/com/google/gwt/dev/javac/typemodel/test/CC.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/CC.java
new file mode 100644
index 0000000..668a524
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/CC.java
@@ -0,0 +1,5 @@
+package com.google.gwt.dev.javac.typemodel.test;
+
+public abstract class CC extends CB implements IC {
+
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/ClassAnnotatedWithBinaryOnlyAnnotation.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/ClassAnnotatedWithBinaryOnlyAnnotation.java
similarity index 81%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/ClassAnnotatedWithBinaryOnlyAnnotation.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/ClassAnnotatedWithBinaryOnlyAnnotation.java
index 9b84ab6..ca49bdc 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/ClassAnnotatedWithBinaryOnlyAnnotation.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/ClassAnnotatedWithBinaryOnlyAnnotation.java
@@ -13,16 +13,16 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
-import com.google.gwt.core.ext.typeinfo.BinaryOnlyAnnotation;
+import com.google.gwt.dev.javac.typemodel.BinaryOnlyAnnotation;
 
 import java.io.File;
 
 /**
- * This class is used to test translatable types that are annotated with 
+ * This class is used to test translatable types that are annotated with
  * annotation for which we have no source.
  */
-@BinaryOnlyAnnotation(jreClassLiteralReference=File.class)
+@BinaryOnlyAnnotation(jreClassLiteralReference = File.class)
 public class ClassAnnotatedWithBinaryOnlyAnnotation {
 }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/ClassLiteralReferenceAnnotation.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/ClassLiteralReferenceAnnotation.java
similarity index 91%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/ClassLiteralReferenceAnnotation.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/ClassLiteralReferenceAnnotation.java
index 1a4d9db..989f241 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/ClassLiteralReferenceAnnotation.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/ClassLiteralReferenceAnnotation.java
@@ -1,7 +1,7 @@
 /**
  * 
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -12,7 +12,7 @@
  * Annotation which references class literals.
  */
 @Retention(RetentionPolicy.RUNTIME)
-@Target( {
+@Target({
     ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD,
     ElementType.METHOD, ElementType.PACKAGE, ElementType.PARAMETER,
     ElementType.TYPE})
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/Derived.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/Derived.java
similarity index 86%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/Derived.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/Derived.java
index 1cf20c7..f030886 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/Derived.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/Derived.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.io.Serializable;
 
@@ -22,9 +22,7 @@
  * {@link com.google.gwt.core.ext.typeinfo.JClassType#getOverridableMethods()}.
  * 
  * Derived<T> Overridable Methods (methods from java.lang.Object not shown):
- * Derived<T>.m(Integer)
- * Derived<T>.m(Number)
- * Derived<T>.m(Integer)
+ * Derived<T>.m(Integer) Derived<T>.m(Number) Derived<T>.m(Integer)
  * Derived<T>.<T extends Serializable> void m(T t)
  */
 public class Derived<T> extends Base<T> {
@@ -38,10 +36,10 @@
    * NOTE: this is commented out because JDT 3.1 will report it as an error,
    * even though javac 1.5 allows this.
    */
-//  @Override
-//  public void m(Object t) {
-//    System.out.println("Derived<T>.m(Object)");
-//  } // 
+  // @Override
+  // public void m(Object t) {
+  // System.out.println("Derived<T>.m(Object)");
+  // } //
 
   /**
    * Overrides Base<T>.<N extends Number>.m(N)
@@ -53,6 +51,7 @@
 
   /**
    * Overloads m
+   * 
    * @param <T>
    * @param t
    */
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/EnumInterface.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/EnumInterface.java
similarity index 94%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/EnumInterface.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/EnumInterface.java
index c1d3db9..34bf370 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/EnumInterface.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/EnumInterface.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 /**
  * Interface used to test enums that implement interfaces.
@@ -26,7 +26,7 @@
    * @return the name of the enum
    */
   String name();
-  
+
   /**
    * Totally new method.
    * 
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/EnumOfInterface.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/EnumOfInterface.java
similarity index 94%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/EnumOfInterface.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/EnumOfInterface.java
index ea69447..c99a083 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/EnumOfInterface.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/EnumOfInterface.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 /**
  * Enumerated type used in the
@@ -28,7 +28,7 @@
       return "A extra";
     }
   },
-  
+
   B;
 
   // Default just returns null
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/ExtendsRawGenericClass.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/ExtendsRawGenericClass.java
similarity index 89%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/ExtendsRawGenericClass.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/ExtendsRawGenericClass.java
index f6a6bd9..cfa32d0 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/ExtendsRawGenericClass.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/ExtendsRawGenericClass.java
@@ -13,11 +13,11 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 /**
- * Class used to test assignment between a parameterized type and a subclass
- * of the raw version.
+ * Class used to test assignment between a parameterized type and a subclass of
+ * the raw version.
  */
 public class ExtendsRawGenericClass extends GenericClass {
 }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericClass.java
similarity index 88%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericClass.java
index cc6b439..ad54c3e 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericClass.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -25,9 +25,10 @@
  * 
  * @param <T>
  * 
- * NOTE: It seems that the JDT 3.1 will not allow: GenericClass<Integer> if the
- * definition of GenericClass is as follows: class GenericClass<T extends
- * Serializable & Comparable<T>> implements Comparable<T> { ... }
+ *          NOTE: It seems that the JDT 3.1 will not allow:
+ *          GenericClass<Integer> if the definition of GenericClass is as
+ *          follows: class GenericClass<T extends Serializable & Comparable<T>>
+ *          implements Comparable<T> { ... }
  */
 public class GenericClass<T extends Serializable> implements Comparable<T>,
     Serializable {
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClassWithDependentTypeBounds.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericClassWithDependentTypeBounds.java
similarity index 79%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClassWithDependentTypeBounds.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericClassWithDependentTypeBounds.java
index 6930c6f..4cdc8b0 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClassWithDependentTypeBounds.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericClassWithDependentTypeBounds.java
@@ -1,32 +1,32 @@
 /*
  * 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.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.io.Serializable;
 
 /**
  * Tests a generic class that has type parameters that depend on each other.
  * Also tests a generic method with type parameters that depend on each other.
- *
+ * 
  * @param <C>
  * @param <M>
  */
-public class GenericClassWithDependentTypeBounds
-    <C extends GenericClassWithTypeBound<M>, M extends Serializable> {
+public class GenericClassWithDependentTypeBounds<C extends GenericClassWithTypeBound<M>, M extends Serializable> {
 
-  public <Q extends GenericClassWithTypeBound<P>, P extends Serializable> void genericMethod(Q param) {
+  public <Q extends GenericClassWithTypeBound<P>, P extends Serializable> void genericMethod(
+      Q param) {
   }
 }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClassWithTypeBound.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericClassWithTypeBound.java
similarity index 82%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClassWithTypeBound.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericClassWithTypeBound.java
index 058807d..a7a592f 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClassWithTypeBound.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericClassWithTypeBound.java
@@ -1,26 +1,25 @@
 /*
  * 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.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.io.Serializable;
 
 /**
- * Auxillary test class used by
- * {@link GenericClassWithDependentTypeBounds}.
- *
+ * Auxillary test class used by {@link GenericClassWithDependentTypeBounds}.
+ * 
  * @param <M>
  */
 public class GenericClassWithTypeBound<M extends Serializable> {
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericSubclass.java
similarity index 95%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericSubclass.java
index 5935087..999c8aa 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/GenericSubclass.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.io.Serializable;
 
diff --git a/dev/core/test/com/google/gwt/dev/javac/typemodel/test/IA.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/IA.java
new file mode 100644
index 0000000..18f76ce
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/IA.java
@@ -0,0 +1,10 @@
+package com.google.gwt.dev.javac.typemodel.test;
+
+public interface IA {
+
+  void foo();
+
+  void ia();
+
+  void ia(int x, Object y);
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/IB.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/IB.java
similarity index 65%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/IB.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/IB.java
index fad1da6..81e8835 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/IB.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/IB.java
@@ -1,4 +1,4 @@
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 public interface IB extends IA {
 
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/IC.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/IC.java
similarity index 72%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/IC.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/IC.java
index c9b543b..59ad176 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/IC.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/IC.java
@@ -1,4 +1,4 @@
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 public interface IC extends IB, IA {
 
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyCustomList.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyCustomList.java
similarity index 91%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyCustomList.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyCustomList.java
index 53ce7ed..77ceb3a 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyCustomList.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyCustomList.java
@@ -13,13 +13,12 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.io.Serializable;
 
 /**
- * Used to test wildcard card expansion when looking for List<Integer>
- * subtypes.
+ * Used to test wildcard card expansion when looking for List<Integer> subtypes.
  */
 public class MyCustomList<T extends Serializable & Comparable<T>, U> extends
     MyList<U> {
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyEnum.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyEnum.java
similarity index 95%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyEnum.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyEnum.java
index 9ee5a1b..a832a03 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyEnum.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyEnum.java
@@ -13,14 +13,14 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 /**
  * Enumerated type used in the
  * {@link com.google.gwt.core.ext.typeinfo.JEnumTypeTest}.
  */
 public enum MyEnum {
-  
+
   VAL2(-3) {
     @Override
     public int getId() {
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyIntegerList.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyIntegerList.java
similarity index 93%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyIntegerList.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyIntegerList.java
index 0d1e559..03a1715 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyIntegerList.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyIntegerList.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 /**
  * Used to test that this type gets picked up as a subtype of List<Integer>.
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyList.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyList.java
similarity index 92%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyList.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyList.java
index 94fa2f1..749dbab 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyList.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/MyList.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 /**
  * Used for testing parameterized subtypes.
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/NestedAnnotation.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/NestedAnnotation.java
similarity index 85%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/NestedAnnotation.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/NestedAnnotation.java
index a4ceaf4..0e05887 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/NestedAnnotation.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/NestedAnnotation.java
@@ -13,12 +13,12 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.lang.annotation.Target;
 
 /**
- * Declare an annotation that cannot be applied to anything.  This is used to
+ * Declare an annotation that cannot be applied to anything. This is used to
  * test nested annotations (annotations used when applying an annotation).
  */
 @Target({})
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/NonGenericSubclass.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/NonGenericSubclass.java
similarity index 88%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/NonGenericSubclass.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/NonGenericSubclass.java
index 03f98fb..f9f5c6e 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/NonGenericSubclass.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/NonGenericSubclass.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 /**
  * Test a non-generic class that extends a parameterized type.
@@ -25,11 +25,11 @@
   public NonGenericSubclass(Integer t) {
     super(t);
   }
-  
-  
+
   /**
-   * Tests overloading of generic methods. 
+   * Tests overloading of generic methods.
    */
+  @Override
   public void setT(Integer t) {
   }
 }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/PrimitiveValuesAnnotation.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/PrimitiveValuesAnnotation.java
similarity index 93%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/PrimitiveValuesAnnotation.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/PrimitiveValuesAnnotation.java
index c140997..706e52f 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/PrimitiveValuesAnnotation.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/PrimitiveValuesAnnotation.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -22,13 +22,13 @@
 
 /**
  * Test annotation containing primitive values.
- *
+ * 
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 public @interface PrimitiveValuesAnnotation {
   boolean bool() default true;
-  
+
   byte b() default 0;
 
   char c() default '\0';
@@ -43,5 +43,5 @@
 
   double d() default 0;
 
-  int[] ia() default {}; 
+  int[] ia() default {};
 }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/PrimitivesAnnotatedClass.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/PrimitivesAnnotatedClass.java
similarity index 84%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/PrimitivesAnnotatedClass.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/PrimitivesAnnotatedClass.java
index 74e9237..45de0d9 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/PrimitivesAnnotatedClass.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/PrimitivesAnnotatedClass.java
@@ -13,17 +13,14 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 /**
  * Test class for annotations with primitive values.
  * 
  */
-@PrimitiveValuesAnnotation(b = PrimitivesAnnotatedClass.byteAsInt,
-    c = (byte) 12, s = 'a', i = (short) 1452,
-    l = 12345, f = (byte) 15, d = 123412312L, ia = {
+@PrimitiveValuesAnnotation(b = PrimitivesAnnotatedClass.byteAsInt, c = (byte) 12, s = 'a', i = (short) 1452, l = 12345, f = (byte) 15, d = 123412312L, ia = {
     0, 1, 2})
 public class PrimitivesAnnotatedClass {
   static final int byteAsInt = 123;
 }
-
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/SourceRetentionAnnotation.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/SourceRetentionAnnotation.java
similarity index 94%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/SourceRetentionAnnotation.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/SourceRetentionAnnotation.java
index 2885a62..7aeb954 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/SourceRetentionAnnotation.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/SourceRetentionAnnotation.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -25,7 +25,7 @@
  * TypeOracle model.
  */
 @Retention(RetentionPolicy.SOURCE)
-@Target( {
+@Target({
     ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD,
     ElementType.METHOD, ElementType.PACKAGE, ElementType.PARAMETER,
     ElementType.TYPE})
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/TestAnnotation.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/TestAnnotation.java
similarity index 91%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/TestAnnotation.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/TestAnnotation.java
index e776051..0a3bf7c 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/TestAnnotation.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/TestAnnotation.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -25,9 +25,9 @@
  * {@link com.google.gwt.core.ext.typeinfo.TypeOracle TypeOracle} deals with
  * annotations.
  */
-//tests depend on this being available
+// tests depend on this being available
 @Retention(RetentionPolicy.RUNTIME)
-@Target( {
+@Target({
     ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD,
     ElementType.METHOD, ElementType.PACKAGE, ElementType.PARAMETER,
     ElementType.TYPE})
@@ -48,10 +48,10 @@
   Class<?>[] arrayWithImplicitArrayInitializer() default Object.class;
 
   /**
-   * Tests default value initialization of class literals. 
+   * Tests default value initialization of class literals.
    */
   Class<?> classLiteral() default Object.class;
-  
+
   /**
    * Tests that an empty array initializer is handled correctly.
    */
@@ -60,18 +60,18 @@
   /**
    * Tests array default values.
    */
-  int[] intArrayValue() default {1,2,3};
+  int[] intArrayValue() default {1, 2, 3};
 
   /**
    * Tests default values using conditional statements.
    */
   long longValue() default useMinLong ? Long.MIN_VALUE : Long.MAX_VALUE;
-  
+
   /**
    * Tests element default values that are themselves annotations.
    */
   NestedAnnotation nestedAnnotation() default @NestedAnnotation("Not assigned");
-  
+
   /**
    * Tests default value initialization via a QualifiedNameReference.
    */
@@ -82,4 +82,3 @@
    */
   String value();
 }
-
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/package-info.java b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/package-info.java
similarity index 86%
rename from dev/core/test/com/google/gwt/core/ext/typeinfo/test/package-info.java
rename to dev/core/test/com/google/gwt/dev/javac/typemodel/test/package-info.java
index ce64c8d..54bdb84 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/package-info.java
+++ b/dev/core/test/com/google/gwt/dev/javac/typemodel/test/package-info.java
@@ -15,8 +15,8 @@
  */
 
 /**
- * Used to test the annotation of packages. 
+ * Used to test the annotation of packages.
  */
 @TestAnnotation("Package")
-package com.google.gwt.core.ext.typeinfo.test;
+package com.google.gwt.dev.javac.typemodel.test;
 
diff --git a/user/src/com/google/gwt/user/rebind/rpc/TypeConstrainer.java b/user/src/com/google/gwt/user/rebind/rpc/TypeConstrainer.java
index 2f44123..efdb324 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/TypeConstrainer.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/TypeConstrainer.java
@@ -330,9 +330,10 @@
     JModTypeVisitor replacer = new JModTypeVisitor() {
       @Override
       public void endVisit(JWildcardType wildcardType) {
-        JTypeParameter newParam = new JTypeParameter("TP$"
-            + freshTypeVariableCounter++, -1);
-        newParam.setBounds(makeArray(typeOracle.getJavaLangObject()));
+        // TODO: fix this to not assume the typemodel types.
+        com.google.gwt.dev.javac.typemodel.JTypeParameter newParam = new com.google.gwt.dev.javac.typemodel.JTypeParameter(
+            "TP$" + freshTypeVariableCounter++, -1);
+        newParam.setBounds(new com.google.gwt.dev.javac.typemodel.JClassType[]{(com.google.gwt.dev.javac.typemodel.JClassType) typeOracle.getJavaLangObject()});
         constraints.put(newParam, wildcardType.getUpperBound());
         replacement = newParam;
       }
diff --git a/user/test/com/google/gwt/uibinder/rebind/JClassTypeAdapter.java b/user/test/com/google/gwt/uibinder/rebind/JClassTypeAdapter.java
index 82d7e11..df8df8a 100644
--- a/user/test/com/google/gwt/uibinder/rebind/JClassTypeAdapter.java
+++ b/user/test/com/google/gwt/uibinder/rebind/JClassTypeAdapter.java
@@ -254,12 +254,12 @@
 
     // Thrown exceptions
     expect(constructor.getThrows()).andStubAnswer(
-        new IAnswer<JType[]>() {
-          public JType[] answer() throws Throwable {
+        new IAnswer<JClassType[]>() {
+          public JClassType[] answer() throws Throwable {
             Class<?>[] realThrows = realConstructor.getExceptionTypes();
-            JType[] gwtThrows = new JType[realThrows.length];
+            JClassType[] gwtThrows = new JClassType[realThrows.length];
             for (int i = 0; i < realThrows.length; i++) {
-              gwtThrows[i] = adaptType(realThrows[i]);
+              gwtThrows[i] = (JClassType) adaptType(realThrows[i]);
             }
             return gwtThrows;
           }
@@ -304,12 +304,12 @@
     });
 
     // Thrown exceptions
-    expect(method.getThrows()).andStubAnswer(new IAnswer<JType[]>() {
-      public JType[] answer() throws Throwable {
+    expect(method.getThrows()).andStubAnswer(new IAnswer<JClassType[]>() {
+      public JClassType[] answer() throws Throwable {
         Class<?>[] realThrows = realMethod.getExceptionTypes();
-        JType[] gwtThrows = new JType[realThrows.length];
+        JClassType[] gwtThrows = new JClassType[realThrows.length];
         for (int i = 0; i < realThrows.length; i++) {
-          gwtThrows[i] = adaptType(realThrows[i]);
+          gwtThrows[i] = (JClassType) adaptType(realThrows[i]);
         }
         return gwtThrows;
       }
diff --git a/user/test/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilderTest.java b/user/test/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilderTest.java
index 45b0069..efd381d 100644
--- a/user/test/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilderTest.java
+++ b/user/test/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilderTest.java
@@ -2348,20 +2348,26 @@
       resources.add(new StaticJavaResource("B", code));
     }
 
+    {
+      StringBuilder code = new StringBuilder();
+      code.append("import java.io.Serializable;\n");
+      code.append("public class C<U extends B> {\n");
+      code.append("}\n");
+      resources.add(new StaticJavaResource("C", code));
+    }
+
     TreeLogger logger = createLogger();
     TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);
 
     JGenericType a = to.getType("A").isGenericType();
     JRawType rawA = a.getRawType();
     JClassType b = to.getType("B");
-
-    JTypeParameter syntheticTypeParam = new JTypeParameter("U", 0);
-    // Force the type parameter to have a declaring class
-    new JGenericType(to, a.getPackage(), null, "C", false, new JTypeParameter[] {syntheticTypeParam});
-    syntheticTypeParam.setBounds(makeArray(b));
+    JGenericType c = to.getType("C").isGenericType();
+    
+    JTypeParameter typeParam = c.getTypeParameters()[0];
 
     JParameterizedType parameterizedType = to.getParameterizedType(a,
-        new JClassType[] {syntheticTypeParam});
+        new JClassType[] {typeParam});
     SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
         logger, to);
     sob.addRootType(logger, parameterizedType);