/*
 * 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.user.rebind.rpc;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JArrayType;
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.JRawType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.JTypeParameter;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
import com.google.gwt.dev.cfg.BindingProperty;
import com.google.gwt.dev.cfg.ConfigurationProperty;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.cfg.ModuleDefLoader;
import com.google.gwt.dev.cfg.StaticPropertyOracle;
import com.google.gwt.dev.javac.TypeOracleTestingUtils;
import com.google.gwt.dev.javac.impl.JavaResourceBase;
import com.google.gwt.dev.javac.impl.MockJavaResource;
import com.google.gwt.dev.javac.impl.StaticJavaResource;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import com.google.gwt.user.rebind.rpc.testcases.client.AbstractSerializableTypes;
import com.google.gwt.user.rebind.rpc.testcases.client.ClassWithTypeParameterThatErasesToObject;
import com.google.gwt.user.rebind.rpc.testcases.client.ManualSerialization;
import com.google.gwt.user.rebind.rpc.testcases.client.NoSerializableTypes;
import com.google.gwt.user.rebind.rpc.testcases.client.NotAllSubtypesAreSerializable;

import junit.framework.TestCase;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
 * Used to test the {@link SerializableTypeOracleBuilder}.
 */
public class SerializableTypeOracleBuilderTest extends TestCase {

  /**
   * Used to test the results produced by the {@link SerializableTypeOracle}.
   */
  static class TypeInfo {
    boolean maybeInstantiated;
    final String sourceName;

    TypeInfo(String binaryName, boolean maybeInstantiated) {
      this.sourceName = makeSourceName(binaryName);
      this.maybeInstantiated = maybeInstantiated;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }

      if (!(obj instanceof TypeInfo)) {
        return false;
      }

      TypeInfo other = (TypeInfo) obj;
      return sourceName.equals(other.sourceName)
          && maybeInstantiated == other.maybeInstantiated;
    }

    @Override
    public int hashCode() {
      return sourceName.hashCode() * (maybeInstantiated ? 17 : 43);
    }

    @Override
    public String toString() {
      return "{ " + sourceName + ", " + Boolean.toString(maybeInstantiated)
          + " }";
    }
  }

  private static final int EXPOSURE_DIRECT = TypeParameterExposureComputer.EXPOSURE_DIRECT;

  private static final int EXPOSURE_NONE = TypeParameterExposureComputer.EXPOSURE_NONE;

  private static TypeOracle sTypeOracle;

  private static void addGwtTransient(Set<Resource> resources) {
    StringBuffer code = new StringBuffer();
    code.append("package com.google.gwt.user.client.rpc;\n");
    code.append("public @interface GwtTransient { }\n");
    resources.add(new StaticJavaResource(
        "com.google.gwt.user.client.rpc.GwtTransient", code));
  }

  private static void addICRSE(Set<Resource> resources) {
    StringBuffer code = new StringBuffer();
    code.append("package com.google.gwt.user.client.rpc;\n");
    code.append("public class IncompatibleRemoteServiceException extends Throwable {\n");
    code.append("}\n");
    resources.add(new StaticJavaResource(
        "com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException",
        code));
  }

  private static void addStandardClasses(Set<Resource> resources) {
    for (MockJavaResource resource : JavaResourceBase.getStandardResources()) {
      resources.add(resource);
    }
    addGwtTransient(resources);
    addICRSE(resources);
  }

  private static void assertFieldSerializable(SerializableTypeOracle so,
      JClassType type) {
    assertTrue(so.isSerializable(type));
  }

  private static void assertInstantiable(SerializableTypeOracle so,
      JClassType type) {
    assertTrue(so.maybeInstantiated(type));
    assertFieldSerializable(so, type);
  }

  private static void assertNotFieldSerializable(SerializableTypeOracle so,
      JClassType type) {
    assertFalse(so.isSerializable(type));
  }

  private static void assertNotInstantiable(SerializableTypeOracle so,
      JClassType type) {
    assertFalse(so.maybeInstantiated(type));
  }

  private static void assertNotInstantiableOrFieldSerializable(
      SerializableTypeOracle so, JClassType type) {
    assertNotInstantiable(so, type);
    assertNotFieldSerializable(so, type);
  }

  private static void assertSerializableTypes(SerializableTypeOracle so,
      JClassType... expectedTypes) {
    Set<JType> expectedSet = new TreeSet<JType>(
        SerializableTypeOracleBuilder.JTYPE_COMPARATOR);
    expectedSet.addAll(Arrays.asList(expectedTypes));

    Set<JType> actualSet = new TreeSet<JType>(
        SerializableTypeOracleBuilder.JTYPE_COMPARATOR);
    JType[] actualTypes = so.getSerializableTypes();
    actualSet.addAll(Arrays.asList(actualTypes));

    assertTrue("Sets not equal.  Expected=\n" + expectedSet + ", \nactual=\n"
        + actualSet, expectedSet.containsAll(actualSet)
        && actualSet.containsAll(expectedSet));
  }

  private static TreeLogger createLogger() {
    PrintWriterTreeLogger logger = new PrintWriterTreeLogger(new PrintWriter(
        System.err, true));
    logger.setMaxDetail(TreeLogger.ERROR);
    return logger;
  }

  private static SerializableTypeOracleBuilder createSerializableTypeOracleBuilder(
      TreeLogger logger, TypeOracle to) throws UnableToCompleteException {
    // Make an empty property oracle.
    StaticPropertyOracle propertyOracle = new StaticPropertyOracle(
        new BindingProperty[0], new String[0], new ConfigurationProperty[0]);
    return new SerializableTypeOracleBuilder(logger, propertyOracle, to);
  }

  private static TypeInfo[] getActualTypeInfo(SerializableTypeOracle sto) {
    JType[] types = sto.getSerializableTypes();
    TypeInfo[] actual = new TypeInfo[types.length];
    for (int i = 0; i < types.length; ++i) {
      JType type = types[i];
      actual[i] = new TypeInfo(type.getParameterizedQualifiedSourceName(),
          sto.maybeInstantiated(type));
    }
    sort(actual);
    return actual;
  }

  private static TypeOracle getTestTypeOracle()
      throws UnableToCompleteException {
    if (sTypeOracle == null) {
      TreeLogger logger = createLogger();
      ModuleDef moduleDef = ModuleDefLoader.createSyntheticModule(logger,
          "com.google.gwt.user.rebind.rpc.testcases.RebindRPCTestCases.JUnit",
          new String[] {
              "com.google.gwt.user.rebind.rpc.testcases.RebindRPCTestCases",
              "com.google.gwt.junit.JUnit"}, true);
      sTypeOracle = moduleDef.getCompilationState(logger).getTypeOracle();
    }
    return sTypeOracle;
  }

  private static String makeSourceName(String binaryName) {
    return binaryName.replace('$', '.');
  }

  private static void sort(TypeInfo[] typeInfos) {
    Arrays.sort(typeInfos, new Comparator<TypeInfo>() {
      public int compare(TypeInfo ti1, TypeInfo ti2) {
        if (ti1 == ti2) {
          return 0;
        }

        return ti1.sourceName.compareTo(ti2.sourceName);
      }
    });
  }

  private static String toString(TypeInfo[] typeInfos) {
    StringBuffer sb = new StringBuffer();
    sb.append("[");
    for (int i = 0; i < typeInfos.length; ++i) {
      if (i != 0) {
        sb.append(",");
      }
      sb.append(typeInfos[i].toString());
      sb.append("\n");
    }

    sb.append("]");
    return sb.toString();
  }

  private static void validateSTO(SerializableTypeOracle sto,
      TypeInfo[] expected) {
    sort(expected);
    TypeInfo[] actual = getActualTypeInfo(sto);

    assertTrue("Expected: \n" + toString(expected) + ",\n Actual: \n"
        + toString(actual), Arrays.equals(expected, actual));
  }

  /**
   * Test with a generic class whose type parameter is exposed only in certain
   * subclasses.
   * 
   * NOTE: This test has been disabled because it requires a better pruner in
   * STOB. See SerializableTypeOracleBuilder.pruneUnreachableTypes().
   */
  public void disabledTestMaybeExposedParameter()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public abstract class List<T> implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("List", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("public class EmptyList<T> extends List<T> {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("EmptyList", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("public class LinkedList<T> extends List<T> {\n");
      code.append("  T head;\n");
      code.append("  LinkedList<T> next;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("LinkedList", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("public class CantSerialize {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("CantSerialize", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType list = to.getType("List").isGenericType();
    JGenericType emptyList = to.getType("EmptyList").isGenericType();
    JClassType cantSerialize = to.getType("CantSerialize");

    JParameterizedType listOfCantSerialize = to.getParameterizedType(list,
        makeArray(cantSerialize));

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, listOfCantSerialize);
    SerializableTypeOracle so = sob.build(logger);

    assertFieldSerializable(so, listOfCantSerialize);
    assertSerializableTypes(so, list.getRawType(), emptyList.getRawType());
  }

  /**
   * Tests abstract root types that are field serializable.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testAbstractFieldSerializableRootType()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public abstract class A implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public abstract class B extends A {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class C extends B {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("C", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JClassType a = to.getType("A");
    JClassType b = to.getType("B");
    JClassType c = to.getType("C");

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, b);
    SerializableTypeOracle so = sob.build(logger);

    assertInstantiable(so, c);
    assertFieldSerializable(so, a);
    assertFieldSerializable(so, b);
    assertSerializableTypes(so, a, b, c);
  }

  /**
   * Tests that we do not violate java package restrictions when computing
   * serializable types.
   */
  public void testAccessLevelsInJavaPackage() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("package java;\n");
      code.append("import java.io.Serializable;\n");
      code.append("public class A implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("java.A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("package java;\n");
      code.append("import java.io.Serializable;\n");
      code.append("class B extends A {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("java.B", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("package java;\n");
      code.append("import java.io.Serializable;\n");
      code.append("public class C extends A {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("java.C", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JClassType a = to.getType("java.A");
    JArrayType arrayOfA = to.getArrayType(a);

    JClassType c = to.getType("java.C");
    JArrayType arrayOfC = to.getArrayType(c);

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, arrayOfA);
    SerializableTypeOracle so = sob.build(logger);

    assertSerializableTypes(so, arrayOfA, arrayOfC, a, c);
  }

  /*
   * Tests arrays of parameterized types.
   */
  public void testArrayOfParameterizedTypes() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      // A<T> exposes its param
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A<T> implements Serializable {\n");
      code.append("  T t;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class AList<T> implements Serializable {\n");
      code.append("  A<T>[] as;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("AList", code));
    }

    {
      // B<T> does not expose its param
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B<T> implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class BList<T> implements Serializable {\n");
      code.append("  B<T>[] bs;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("BList", code));
    }

    {
      // A random serializable class
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Ser1 implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Ser1", code));
    }

    {
      // A random serializable class
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Ser2 implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Ser2", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Root implements Serializable {\n");
      code.append("  AList<Ser1> alist;\n");
      code.append("  BList<Ser2> blist;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Root", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType a = to.getType("A").isGenericType();
    JGenericType b = to.getType("B").isGenericType();
    JGenericType alist = to.getType("AList").isGenericType();
    JGenericType blist = to.getType("BList").isGenericType();
    JClassType ser1 = to.getType("Ser1");
    JClassType ser2 = to.getType("Ser2");
    JClassType root = to.getType("Root");

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, root);

    assertEquals(EXPOSURE_DIRECT, sob.getTypeParameterExposure(a, 0));
    assertEquals(EXPOSURE_NONE, sob.getTypeParameterExposure(b, 0));
    assertEquals(EXPOSURE_DIRECT, sob.getTypeParameterExposure(alist, 0));
    assertEquals(EXPOSURE_NONE, sob.getTypeParameterExposure(blist, 0));

    SerializableTypeOracle so = sob.build(logger);

    JArrayType aArray = to.getArrayType(a.getRawType());
    JArrayType bArray = to.getArrayType(b.getRawType());

    assertSerializableTypes(so, root, alist.getRawType(), blist.getRawType(),
        aArray, bArray, a.getRawType(), b.getRawType(), ser1);

    assertInstantiable(so, alist.getRawType());
    assertInstantiable(so, blist.getRawType());
    assertInstantiable(so, a.getRawType());
    assertInstantiable(so, b.getRawType());
    assertInstantiable(so, aArray);
    assertInstantiable(so, bArray);
    assertInstantiable(so, ser1);
    assertNotInstantiableOrFieldSerializable(so, ser2);
  }

  /*
   * Tests arrays of type variables that do not cause infinite expansion.
   */
  public void testArrayOfTypeParameter() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A<T> implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B<T> extends A<T> implements Serializable {\n");
      code.append("  T[][] t;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class C<T> implements Serializable {\n");
      code.append("  A<T[]> a1;\n");
      code.append("  A<Ser> a2;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("C", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Ser implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Ser", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType a = to.getType("A").isGenericType();
    JGenericType b = to.getType("B").isGenericType();
    JGenericType c = to.getType("C").isGenericType();
    JClassType ser = to.getType("Ser");

    JClassType javaLangString = to.getType(String.class.getName());
    JParameterizedType cOfString = to.getParameterizedType(c,
        makeArray(javaLangString));
    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, cOfString);

    assertEquals(2, sob.getTypeParameterExposure(a, 0));
    assertEquals(2, sob.getTypeParameterExposure(b, 0));
    assertEquals(3, sob.getTypeParameterExposure(c, 0));

    SerializableTypeOracle so = sob.build(logger);

    JArrayType stringArray = to.getArrayType(javaLangString);
    JArrayType stringArrayArray = to.getArrayType(stringArray);
    JArrayType stringArrayArrayArray = to.getArrayType(stringArrayArray);
    JArrayType serArray = to.getArrayType(ser);
    JArrayType serArrayArray = to.getArrayType(serArray);

    assertSerializableTypes(so, a.getRawType(), b.getRawType(), c,
        javaLangString, stringArray, stringArrayArray, stringArrayArrayArray,
        ser, serArray, serArrayArray);

    assertInstantiable(so, a.getRawType());
    assertInstantiable(so, b.getRawType());
    assertInstantiable(so, c);
    assertInstantiable(so, stringArray);
    assertInstantiable(so, stringArrayArray);
    assertInstantiable(so, stringArrayArrayArray);
    assertInstantiable(so, serArray);
    assertInstantiable(so, serArrayArray);
  }

  /**
   * Tests the rules that govern whether a type qualifies for serialization.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testClassQualifiesForSerialization()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("public class NotSerializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("NotSerializable", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class OuterClass {\n");
      code.append("  static class StaticNested implements Serializable {};\n");
      code.append("  class NonStaticNested implements Serializable {};\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("OuterClass", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public abstract class AbstractSerializableClass implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("AbstractSerializableClass", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class NonDefaultInstantiableSerializable implements Serializable {\n");
      code.append("  NonDefaultInstantiableSerializable(int i) {}\n");
      code.append("}\n");
      resources.add(new StaticJavaResource(
          "NonDefaultInstantiableSerializable", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class PublicOuterClass {\n");
      code.append("  private static class PrivateStaticInner {\n");
      code.append("    public static class PublicStaticInnerInner implements Serializable {\n");
      code.append("    }\n");
      code.append("  }\n");
      code.append("  static class DefaultStaticInner {\n");
      code.append("    static class DefaultStaticInnerInner implements Serializable {\n");
      code.append("    }\n");
      code.append("  }\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("PublicOuterClass", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("public enum EnumWithSubclasses {\n");
      code.append("  A {\n");
      code.append("    @Override\n");
      code.append("    public String value() {\n");
      code.append("      return \"X\";\n");
      code.append("    }\n");
      code.append("  },\n");
      code.append("  B {\n");
      code.append("    @Override\n");
      code.append("    public String value() {\n");
      code.append("      return \"Y\";\n");
      code.append("    };\n");
      code.append("  };\n");
      code.append("  public abstract String value();\n");
      code.append("};\n");
      resources.add(new StaticJavaResource("EnumWithSubclasses", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("public enum EnumWithNonDefaultCtors {\n");
      code.append("  A(\"X\"), B(\"Y\");\n");
      code.append("  String value;");
      code.append("  private EnumWithNonDefaultCtors(String value) {\n");
      code.append("    this.value = value;\n");
      code.append("  }\n");
      code.append("};\n");
      resources.add(new StaticJavaResource("EnumWithNonDefaultCtors", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);
    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);

    // Does not qualify because it is not declared to be auto or manually
    // serializable
    JClassType notSerializable = to.getType("NotSerializable");
    ProblemReport problems = new ProblemReport();
    assertFalse(sob.shouldConsiderFieldsForSerialization(notSerializable,
        problems));

    // Static nested types qualify for serialization
    JClassType staticNested = to.getType("OuterClass.StaticNested");
    problems = new ProblemReport();
    assertTrue(sob.shouldConsiderFieldsForSerialization(staticNested, problems));

    // Non-static nested types do not qualify for serialization
    JClassType nonStaticNested = to.getType("OuterClass.NonStaticNested");
    problems = new ProblemReport();
    assertFalse(sob.shouldConsiderFieldsForSerialization(nonStaticNested,
        problems));

    // Abstract classes that implement Serializable should not qualify
    JClassType abstractSerializableClass = to.getType("AbstractSerializableClass");
    problems = new ProblemReport();
    assertTrue(sob.shouldConsiderFieldsForSerialization(
        abstractSerializableClass, problems));

    problems = new ProblemReport();
    assertFalse(SerializableTypeOracleBuilder.canBeInstantiated(
        abstractSerializableClass, problems));

    // Non-default instantiable types should not qualify
    JClassType nonDefaultInstantiableSerializable = to.getType("NonDefaultInstantiableSerializable");
    problems = new ProblemReport();
    assertTrue(sob.shouldConsiderFieldsForSerialization(
        nonDefaultInstantiableSerializable, problems));

    problems = new ProblemReport();
    assertFalse(SerializableTypeOracleBuilder.canBeInstantiated(
        nonDefaultInstantiableSerializable, problems));

    // SPublicStaticInnerInner is not accessible to classes in its package
    JClassType publicStaticInnerInner = to.getType("PublicOuterClass.PrivateStaticInner.PublicStaticInnerInner");
    problems = new ProblemReport();
    assertFalse(sob.shouldConsiderFieldsForSerialization(
        publicStaticInnerInner, problems));

    // DefaultStaticInnerInner is visible to classes in its package
    JClassType defaultStaticInnerInner = to.getType("PublicOuterClass.DefaultStaticInner.DefaultStaticInnerInner");
    problems = new ProblemReport();
    assertTrue(sob.shouldConsiderFieldsForSerialization(
        defaultStaticInnerInner, problems));

    // Enum with subclasses should qualify, but their subtypes should not
    JClassType enumWithSubclasses = to.getType("EnumWithSubclasses");
    problems = new ProblemReport();
    assertTrue(sob.shouldConsiderFieldsForSerialization(enumWithSubclasses,
        problems));

    // There are no longer any enum subclasses in TypeOracle
    assertEquals(0, enumWithSubclasses.getSubtypes().length);

    // Enum that are not default instantiable should qualify
    JClassType enumWithNonDefaultCtors = to.getType("EnumWithNonDefaultCtors");
    problems = new ProblemReport();
    assertTrue(sob.shouldConsiderFieldsForSerialization(
        enumWithNonDefaultCtors, problems));
  }

  /**
   * Tests that both the generic and raw forms of type that has a type parameter
   * that erases to object are not serializable.
   * 
   * @throws NotFoundException
   */
  public void testClassWithTypeParameterThatErasesToObject()
      throws NotFoundException, UnableToCompleteException {
    TreeLogger logger = createLogger();

    TypeOracle typeOracle = getTestTypeOracle();
    JRawType rawType = typeOracle.getType(
        ClassWithTypeParameterThatErasesToObject.class.getCanonicalName()).isGenericType().getRawType();

    // The raw form of the type should not be serializable.
    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, typeOracle);
    stob.addRootType(logger, rawType);
    try {
      stob.build(logger);
      fail("Expected an " + UnableToCompleteException.class.getSimpleName());
    } catch (UnableToCompleteException ex) {
      // Expected to reach here
    }
  }

  /**
   * Test the situation where an abstract class has an unconstrained type
   * parameter but all of its concrete subclasses add helpful constraints to it.
   * 
   * @throws NotFoundException
   * @throws UnableToCompleteException
   */
  public void testConcreteClassesConstrainATypeParameter()
      throws NotFoundException, UnableToCompleteException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public abstract class Holder<T extends Serializable> implements Serializable {\n");
      code.append("  T x;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Holder", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class StringHolder extends Holder<String> implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("StringHolder", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class DateHolder extends Holder<Date> implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("DateHolder", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Date implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Date", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class UnrelatedClass implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("UnrelatedClass", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType holder = to.getType("Holder").isGenericType();
    JClassType stringHolder = to.getType("StringHolder");
    JClassType dateHolder = to.getType("DateHolder");
    JClassType unrelatedClass = to.getType("UnrelatedClass");

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, holder.getRawType());
    SerializableTypeOracle so = sob.build(logger);

    JClassType string = to.getType(String.class.getCanonicalName());
    JClassType date = to.getType("Date");

    assertSerializableTypes(so, holder.getRawType(), stringHolder, dateHolder,
        string, date);
    assertFieldSerializable(so, holder.getRawType());
    assertInstantiable(so, stringHolder);
    assertInstantiable(so, dateHolder);
    assertInstantiable(so, string);
    assertInstantiable(so, date);
    assertNotInstantiableOrFieldSerializable(so, unrelatedClass);
  }

  /**
   * Tests that a method signature which returns an Array type also includes the
   * possible covariant array types which could contain a serializable type.
   */
  public void testCovariantArrays() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Sup implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Sup", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Sub extends Sup {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Sub", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JClassType sup = to.getType("Sup");
    JClassType sub = to.getType("Sub");
    JPrimitiveType primFloat = JPrimitiveType.FLOAT;

    JArrayType subArray = to.getArrayType(sub);
    JArrayType subArrayArray = to.getArrayType(subArray);
    JArrayType supArray = to.getArrayType(sup);
    JArrayType supArrayArray = to.getArrayType(supArray);
    JArrayType primFloatArray = to.getArrayType(primFloat);
    JArrayType primFloatArrayArray = to.getArrayType(primFloatArray);

    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, to);
    // adding Sub first exercises an extra code path in STOB
    stob.addRootType(logger, sub);
    stob.addRootType(logger, supArrayArray);
    stob.addRootType(logger, primFloatArrayArray);
    SerializableTypeOracle sto = stob.build(logger);

    assertSerializableTypes(sto, sup, sub, supArray, subArray, primFloatArray,
        supArrayArray, subArrayArray, primFloatArrayArray);
    assertInstantiable(sto, primFloatArrayArray);
    assertInstantiable(sto, primFloatArray);
    assertInstantiable(sto, subArrayArray);
    assertInstantiable(sto, subArray);
    assertInstantiable(sto, supArrayArray);
    assertInstantiable(sto, supArray);
  }

  /**
   * If the query type extends a raw type, be sure to pick up the parameters of
   * the raw subertype.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testExtensionFromRaw1() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class HashSet<T extends SerClass> implements Serializable {\n");
      code.append("  T[] x;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("HashSet", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class NameSet extends HashSet implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("NameSet", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class SerClass implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("SerClass", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class SerClassSub extends SerClass {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("SerClassSub", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType hashSet = to.getType("HashSet").isGenericType();
    JClassType nameSet = to.getType("NameSet");
    JClassType serClass = to.getType("SerClass");
    JClassType serClassSub = to.getType("SerClassSub");

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, nameSet);
    SerializableTypeOracle so = sob.build(logger);

    JArrayType arrayOfSerClass = to.getArrayType(serClass);
    JArrayType arrayOfSerClassSub = to.getArrayType(serClassSub);

    assertSerializableTypes(so, hashSet.getRawType(), nameSet, serClass,
        serClassSub, arrayOfSerClass, arrayOfSerClassSub);
    assertFieldSerializable(so, hashSet.getRawType());
    assertNotInstantiable(so, hashSet.getRawType());
    assertInstantiable(so, nameSet);
    assertInstantiable(so, serClass);
    assertInstantiable(so, serClassSub);
    assertInstantiable(so, arrayOfSerClass);
    assertInstantiable(so, arrayOfSerClassSub);
  }

  /**
   * If a subtype of a root type extends from the raw version of that root type,
   * then when visiting the fields of the raw version, take advantage of
   * information from the original root type.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testExtensionFromRaw2() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class HashSet<T extends Serializable> implements Serializable {\n");
      code.append("  T[] x;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("HashSet", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class NameSet<T extends SerClass> extends HashSet implements Serializable {\n");
      code.append("  T exposed;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("NameSet", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class SerClass implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("SerClass", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class SerClassSub extends SerClass {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("SerClassSub", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class UnrelatedClass implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("UnrelatedClass", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JClassType string = to.getType(String.class.getCanonicalName());
    JGenericType hashSet = to.getType("HashSet").isGenericType();
    JGenericType nameSet = to.getType("NameSet").isGenericType();
    JClassType unrelatedClass = to.getType("UnrelatedClass");
    JClassType serClass = to.getType("SerClass");
    JClassType serClassSub = to.getType("SerClassSub");
    JParameterizedType hashSetOfString = to.getParameterizedType(hashSet,
        makeArray(string));

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, hashSetOfString);
    SerializableTypeOracle so = sob.build(logger);

    JArrayType arrayOfString = to.getArrayType(string);

    assertSerializableTypes(so, hashSet.getRawType(), nameSet.getRawType(),
        string, arrayOfString, serClass, serClassSub);
    assertInstantiable(so, hashSet.getRawType());
    assertInstantiable(so, nameSet.getRawType());
    assertInstantiable(so, string);
    assertInstantiable(so, serClass);
    assertInstantiable(so, serClassSub);
    assertNotInstantiable(so, unrelatedClass);
  }

  /**
   * Expansion via parameterized types, where the type is exposed.
   */
  public void testInfiniteParameterizedTypeExpansionCase1()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A<T> implements Serializable {\n");
      code.append("  B<T> b;\n");
      code.append("  T x;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B<T> extends A<T> implements Serializable {\n");
      code.append("  A<B<T>> ab;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class SerializableArgument implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("SerializableArgument", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType a = to.getType("A").isGenericType();
    JGenericType b = to.getType("B").isGenericType();
    JClassType serializableArgument = to.getType("SerializableArgument");

    JParameterizedType aOfString = to.getParameterizedType(a,
        makeArray(serializableArgument));
    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, aOfString);
    SerializableTypeOracle so = sob.build(logger);

    assertInstantiable(so, a.getRawType());
    assertInstantiable(so, b.getRawType());
    assertInstantiable(so, serializableArgument);
    assertSerializableTypes(so, a.getRawType(), b.getRawType(),
        serializableArgument);
  }

  /**
   * Expansion via parameterized types, where the type is not actually exposed.
   */
  public void testInfiniteParameterizedTypeExpansionCase2()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A<T> implements Serializable {\n");
      code.append("  B<T> b;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B<T> extends A<T> implements Serializable {\n");
      code.append("  A<B<T>> ab;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class UnusedSerializableArgument implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("UnusedSerializableArgument", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType a = to.getType("A").isGenericType();
    JGenericType b = to.getType("B").isGenericType();
    JClassType unusedSerializableArgument = to.getType("UnusedSerializableArgument");

    JParameterizedType aOfString = to.getParameterizedType(a,
        makeArray(unusedSerializableArgument));
    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, aOfString);
    SerializableTypeOracle so = sob.build(logger);

    assertInstantiable(so, a.getRawType());
    assertInstantiable(so, b.getRawType());

    assertNotInstantiableOrFieldSerializable(so, unusedSerializableArgument);
    assertSerializableTypes(so, a.getRawType(), b.getRawType());
  }

  /*
   * Case 3: Expansion via array dimensions, but the type arguments are not
   * exposed so this case will succeed.
   */
  public void testInfiniteParameterizedTypeExpansionCase3()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A<T> implements Serializable {\n");
      code.append("  B<T> b;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B<T> extends A<T> implements Serializable {\n");
      code.append("  A<T[]> ab;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType a = to.getType("A").isGenericType();
    JGenericType b = to.getType("B").isGenericType();

    JClassType javaLangString = to.getType(String.class.getName());
    JParameterizedType aOfString = to.getParameterizedType(a,
        makeArray(javaLangString));
    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, aOfString);
    SerializableTypeOracle so = sob.build(logger);

    assertInstantiable(so, a.getRawType());
    assertInstantiable(so, b.getRawType());

    assertNotInstantiableOrFieldSerializable(so, javaLangString);
    assertSerializableTypes(so, a.getRawType(), b.getRawType());
  }

  /*
   * Case 4: Expansion via array dimensions, but the type arguments are exposed
   * so this case will fail.
   */
  public void testInfiniteParameterizedTypeExpansionCase4()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A<T> implements Serializable {\n");
      code.append("  T t;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B<T> extends A<T> implements Serializable {\n");
      code.append("  A<T[]> ab;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType a = to.getType("A").isGenericType();
    JGenericType b = to.getType("B").isGenericType();

    JClassType javaLangString = to.getType(String.class.getName());
    JParameterizedType aOfString = to.getParameterizedType(a,
        makeArray(javaLangString));
    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);

    assertEquals(EXPOSURE_DIRECT, sob.getTypeParameterExposure(a, 0));
    assertEquals(EXPOSURE_DIRECT, sob.getTypeParameterExposure(b, 0));

    sob.addRootType(logger, aOfString);
    SerializableTypeOracle so = sob.build(logger);

    assertNotFieldSerializable(so, b.getRawType());
    assertNotInstantiable(so, b.getRawType());

    assertSerializableTypes(so, a.getRawType(), javaLangString);
    assertInstantiable(so, a.getRawType());
    assertNotInstantiable(so, b.getRawType());
    assertInstantiable(so, javaLangString);
  }

  /**
   * Tests that a manually serialized type with a field that is not serializable
   * does not cause the generator to fail.
   */
  public void testManualSerialization() throws NotFoundException,
      UnableToCompleteException {
    TreeLogger logger = createLogger();

    TypeOracle typeOracle = getTestTypeOracle();
    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, typeOracle);
    JClassType a = typeOracle.getType(ManualSerialization.A.class.getCanonicalName());
    JClassType b = typeOracle.getType(ManualSerialization.B.class.getCanonicalName());
    stob.addRootType(logger, a);
    SerializableTypeOracle sto = stob.build(logger);
    assertInstantiable(sto, a);
    assertNotInstantiableOrFieldSerializable(sto, b);
  }

  /**
   * Tests that a raw List (missing gwt.typeArgs) will not result in a failure.
   * The set of types is not currently being checked.
   */
  public void testMissingGwtTypeArgs() throws NotFoundException,
      UnableToCompleteException {
    TreeLogger logger = createLogger();

    TypeOracle typeOracle = getTestTypeOracle();
    JClassType rawList = typeOracle.getType(List.class.getName());
    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, typeOracle);
    stob.addRootType(logger, rawList);
    SerializableTypeOracle sto = stob.build(logger);

    // TODO: This test should should be updated to use a controlled type oracle
    // then we can check the types.
    assertNotInstantiable(sto, rawList);
  }

  /**
   * Tests that the type constrainer can accurately detect when an interface
   * matches another type.
   */
  public void testNonOverlappingInterfaces() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public interface Intf1 extends Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Intf1", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public interface Intf2 extends Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Intf2", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public interface Intf3 extends Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Intf3", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Implements12 implements Intf1, Intf2 {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Implements12", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class ImplementsNeither implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ImplementsNeither", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public interface List<T> extends Serializable  {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("List", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class ListOfIntf1 implements List<Intf1>  {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ListOfIntf1", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class ListOfIntf2 implements List<Intf2>  {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ListOfIntf2", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class ListOfIntf3 implements List<Intf3>  {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ListOfIntf3", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class ListOfImplements12 implements List<Implements12>  {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ListOfImplements12", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class ListOfImplementsNeither implements List<ImplementsNeither>  {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ListOfImplementsNeither", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JClassType intf1 = to.getType("Intf1");
    JClassType intf2 = to.getType("Intf2");
    JClassType intf3 = to.getType("Intf3");
    JClassType implements12 = to.getType("Implements12");
    JClassType implementsNeither = to.getType("ImplementsNeither");
    JGenericType list = to.getType("List").isGenericType();
    JClassType listOfIntf1 = to.getType("ListOfIntf1");
    JClassType listOfIntf2 = to.getType("ListOfIntf2");
    JClassType listOfIntf3 = to.getType("ListOfIntf3");
    JClassType listOfImplements12 = to.getType("ListOfImplements12");
    JClassType listOfImplementsNeither = to.getType("ListOfImplementsNeither");

    TypeConstrainer typeConstrainer = new TypeConstrainer(to);
    Map<JTypeParameter, JClassType> emptyConstraints = new HashMap<JTypeParameter, JClassType>();
    assertTrue(typeConstrainer.typesMatch(intf1, intf2, emptyConstraints));
    assertFalse(typeConstrainer.typesMatch(intf1, intf3, emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(implements12, intf1, emptyConstraints));
    assertFalse(typeConstrainer.typesMatch(implements12, intf3,
        emptyConstraints));
    assertFalse(typeConstrainer.typesMatch(implementsNeither, intf1,
        emptyConstraints));

    JParameterizedType parameterizedListOfIntf1 = to.getParameterizedType(list,
        makeArray(intf1));

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, parameterizedListOfIntf1);
    SerializableTypeOracle so = sob.build(logger);

    assertSerializableTypes(so, listOfIntf1, listOfIntf2, listOfImplements12);
    assertNotFieldSerializable(so, listOfIntf3);
    assertNotFieldSerializable(so, listOfImplementsNeither);
  }

  /**
   * Tests that a method signature which has no serializable types will result
   * in a failure.
   */
  public void testNoSerializableTypes() throws NotFoundException,
      UnableToCompleteException {
    TreeLogger logger = createLogger();

    TypeOracle typeOracle = getTestTypeOracle();
    JClassType a = typeOracle.getType(NoSerializableTypes.A.class.getCanonicalName());
    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, typeOracle);
    stob.addRootType(logger, a);
    try {
      stob.build(logger);
      fail("Should have thrown an UnableToCompleteException");
    } catch (UnableToCompleteException ex) {
      // expected to get here
    }
  }

  /**
   * Tests that a method signature which only has type whose inheritance
   * hiearchy has a mix of serializable and unserializable types will not cause
   * the generator fail. It also checks for the set of serializable types.
   */
  public void testNotAllSubtypesAreSerializable()
      throws UnableToCompleteException, NotFoundException {
    TreeLogger logger = createLogger();

    TypeOracle typeOracle = getTestTypeOracle();
    JClassType a = typeOracle.getType(NotAllSubtypesAreSerializable.A.class.getCanonicalName());
    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, typeOracle);
    stob.addRootType(logger, a);
    SerializableTypeOracle sto = stob.build(logger);

    TypeInfo[] expected = new TypeInfo[] {
        new TypeInfo(
            makeSourceName(NotAllSubtypesAreSerializable.B.class.getName()),
            true),
        new TypeInfo(
            makeSourceName(NotAllSubtypesAreSerializable.D.class.getName()),
            true)};
    validateSTO(sto, expected);
  }

  /**
   * Tests that Object[] is not instantiable.
   */
  public void testObjectArrayNotInstantiable() throws UnableToCompleteException {
    TreeLogger logger = createLogger();

    TypeOracle typeOracle = getTestTypeOracle();
    JArrayType objectArray = typeOracle.getArrayType(typeOracle.getJavaLangObject());
    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, typeOracle);
    stob.addRootType(logger, objectArray);
    try {
      stob.build(logger);
      fail("Expected UnableToCompleteException");
    } catch (UnableToCompleteException e) {
      // Should get here
    }
  }

  /**
   * Tests that Object is not considered instantiable.
   */
  public void testObjectNotInstantiable() throws UnableToCompleteException {
    TreeLogger logger = createLogger();

    TypeOracle typeOracle = getTestTypeOracle();
    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, typeOracle);
    stob.addRootType(logger, typeOracle.getJavaLangObject());
    try {
      stob.build(logger);
      fail("Expected UnableToCompleteException");
    } catch (UnableToCompleteException e) {
      // Should get here
    }
  }

  /**
   * Tests that a method signature which only has abstract serializable types
   * fails.
   */
  public void testOnlyAbstractSerializableTypes()
      throws UnableToCompleteException, NotFoundException {
    TreeLogger logger = createLogger();

    TypeOracle typeOracle = getTestTypeOracle();
    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, typeOracle);
    stob.addRootType(
        logger,
        typeOracle.getType(AbstractSerializableTypes.IFoo.class.getCanonicalName()));
    stob.addRootType(
        logger,
        typeOracle.getType(AbstractSerializableTypes.AbstractClass.class.getCanonicalName()));

    try {
      stob.build(logger);
      fail("Expected UnableToCompleteException");
    } catch (UnableToCompleteException e) {
      // Should get here
    }
  }

  /**
   * Tests a hierarchy blending various serializable and non-serializable types.
   */
  public void testProblemReporting() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("public interface TopInterface {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("TopInterface", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public abstract class AbstractSerializable implements\n");
      code.append("    Serializable, TopInterface {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("AbstractSerializable", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public interface PureAbstractSerializable extends \n");
      code.append("    Serializable, TopInterface {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("PureAbstractSerializable", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public abstract class PureAbstractClass implements \n");
      code.append("    PureAbstractSerializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("PureAbstractClass", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public abstract class PureAbstractClassTwo extends \n");
      code.append("    PureAbstractClass {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("PureAbstractClassTwo", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public class ConcreteNonSerializable implements\n");
      code.append("    TopInterface {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ConcreteNonSerializable", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class ConcreteSerializable implements\n");
      code.append("    Serializable, TopInterface {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ConcreteSerializable", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class SubSerializable extends\n");
      code.append("    ConcreteNonSerializable implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("SubSerializable", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public class ConcreteBadCtor extends\n");
      code.append("    AbstractSerializable {\n");
      code.append("  public ConcreteBadCtor(int i) {\n");
      code.append("  }\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ConcreteBadCtor", code));
    }
    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, to);
    JClassType topInterface = to.getType("TopInterface");
    stob.addRootType(logger, topInterface);

    ProblemReport problems = new ProblemReport();
    assertTrue(
        "TopInterface should be (partially) serializable",
        stob.computeTypeInstantiability(logger, topInterface, null, problems).hasInstantiableSubtypes());
    assertTrue("TopInterface should be a serializable type",
        problems.getProblemsForType(topInterface).isEmpty());
    assertTrue(
        "AbstractSerializable should not be reported on",
        problems.getProblemsForType(to.getType("AbstractSerializable")).isEmpty());
    assertTrue(
        "PureAbstractSerializable should not be reported on",
        problems.getProblemsForType(to.getType("PureAbstractSerializable")).isEmpty());
    assertTrue("PureAbstractClass should not be reported on",
        problems.getProblemsForType(to.getType("PureAbstractClass")).isEmpty());
    assertFalse("ConcreteBadCtor should not be a serializable type",
        problems.getProblemsForType(to.getType("ConcreteBadCtor")).isEmpty());
    assertFalse(
        "ConcreteNonSerializable should not be a serializable type",
        problems.getProblemsForType(to.getType("ConcreteNonSerializable")).isEmpty());
    assertTrue(
        "ConcreteSerializable should be a serializable type",
        problems.getProblemsForType(to.getType("ConcreteSerializable")).isEmpty());
    assertTrue("SubSerializable should be a serializable type",
        problems.getProblemsForType(to.getType("SubSerializable")).isEmpty());

    problems = new ProblemReport();
    assertFalse(
        "PureAbstractClass should have no possible concrete implementation",
        stob.computeTypeInstantiability(logger,
            to.getType("PureAbstractClass"), null, problems).hasInstantiableSubtypes());
    assertTrue(
        "PureAbstractClass should have a problem entry as the tested class",
        null != problems.getProblemsForType(to.getType("PureAbstractClass")));

    problems = new ProblemReport();
    assertFalse(
        "PureAbstractSerializable should have no possible concrete implementation",
        stob.computeTypeInstantiability(logger,
            to.getType("PureAbstractSerializable"), null, problems).hasInstantiableSubtypes());
    assertFalse(
        "PureAbstractSerializable should have a problem entry",
        problems.getProblemsForType(to.getType("PureAbstractSerializable")).isEmpty());
    assertTrue(
        "PureAbstractClassTwo should not have a problem entry as the middle class",
        problems.getProblemsForType(to.getType("PureAbstractClassTwo")).isEmpty());
    assertTrue(
        "PureAbstractClassTwo should not have an auxiliary entry as the middle class",
        problems.getAuxiliaryMessagesForType(to.getType("PureAbstractClassTwo")).isEmpty());
    assertTrue(
        "PureAbstractClass should not have a problem entry as the child class",
        problems.getProblemsForType(to.getType("PureAbstractClass")).isEmpty());
    assertTrue(
        "PureAbstractClass should not have an auxiliary entry as the child class",
        problems.getAuxiliaryMessagesForType(to.getType("PureAbstractClass")).isEmpty());
  }

  /**
   * Tests that adding a raw collection as a root type pulls in the world.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testRawCollection() throws UnableToCompleteException,
      NotFoundException {

    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("import java.util.Collection;\n");
      code.append("public interface List<T> extends Serializable, Collection<T> {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("List", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("import java.util.Collection;\n");
      code.append("public class LinkedList<T> implements List<T> {\n");
      code.append("  T head;");
      code.append("}\n");
      resources.add(new StaticJavaResource("LinkedList", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("import java.util.Collection;\n");
      code.append("public class RandomClass implements Serializable {\n");
      // TODO(mmendez): Lex, this should fail, but your fix will allow it if
      // we get here from a raw collection.
      // code.append(" Object obj;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("RandomClass", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType list = to.getType("List").isGenericType();
    JGenericType linkedList = to.getType("LinkedList").isGenericType();
    JClassType randomClass = to.getType("RandomClass");

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, list.getRawType());
    SerializableTypeOracle so = sob.build(logger);

    assertInstantiable(so, linkedList.getRawType());
    assertInstantiable(so, randomClass);
  }

  /**
   * Tests that raw type with type parameters that are instantiable are
   * themselves instantiable.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testRawTypes() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A<T extends SerializableClass> implements Serializable {\n");
      code.append("  T x;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class SerializableClass implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("SerializableClass", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType a = to.getType("A").isGenericType();
    JRawType rawA = a.getRawType();

    JClassType serializableClass = to.getType("SerializableClass");

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, rawA);
    SerializableTypeOracle so = sob.build(logger);

    assertInstantiable(so, a.getRawType());
    assertSerializableTypes(so, rawA, serializableClass);
  }

  /**
   * Tests that a type paramter that occurs within its bounds will not result in
   * infinite recursion.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testRootTypeParameterWithSelfInBounds()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A<Ta extends A<Ta>> implements Serializable {\n");
      code.append("  Ta ta;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType a = to.getType("A").isGenericType();
    JClassType rawA = a.getRawType();
    JTypeParameter ta = a.getTypeParameters()[0];

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, ta);
    SerializableTypeOracle so = sob.build(logger);

    assertSerializableTypes(so, rawA);
  }

  /**
   * Tests that type String[][] also pulls in String[].
   */
  public void testStringArrayArray() throws NotFoundException,
      UnableToCompleteException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Data implements Serializable {\n");
      code.append("  String justOneString;");
      code.append("  String[][] stringsGalore;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Data", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JClassType data = to.getType("Data");
    JClassType string = to.getType(String.class.getCanonicalName());
    JArrayType stringArray = to.getArrayType(string);
    JArrayType stringArrayArray = to.getArrayType(stringArray);

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, data);

    SerializableTypeOracle so = sob.build(logger);

    assertSerializableTypes(so, data, string, stringArray, stringArrayArray);
    assertInstantiable(so, data);
    assertInstantiable(so, stringArrayArray);
    assertInstantiable(so, stringArray);
  }

  /*
   * Tests the isAssignable test for deciding whether a subclass should be
   * pulled in.
   */
  public void testSubclassIsAssignable() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A<T> implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B extends A<String> implements Serializable {\n");
      code.append("  Object o;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class C extends A<Ser> implements Serializable {\n");
      // TODO: rejecting Ser requires a better pruner in STOB
      // code.append(" Ser ser;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("C", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Ser implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Ser", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType a = to.getType("A").isGenericType();
    JClassType b = to.getType("B");
    JClassType c = to.getType("C");
    JClassType ser = to.getType("Ser");

    JClassType javaLangString = to.getType(String.class.getName());
    JParameterizedType aOfString = to.getParameterizedType(a,
        makeArray(javaLangString));
    SerializableTypeOracleBuilder stob = createSerializableTypeOracleBuilder(
        logger, to);
    stob.addRootType(logger, aOfString);

    assertEquals(EXPOSURE_NONE, stob.getTypeParameterExposure(a, 0));

    SerializableTypeOracle so = stob.build(logger);

    assertSerializableTypes(so, a.getRawType());

    assertInstantiable(so, a.getRawType());
    assertNotInstantiableOrFieldSerializable(so, b);
    assertNotInstantiableOrFieldSerializable(so, c);
    assertNotInstantiableOrFieldSerializable(so, javaLangString);
    assertNotInstantiableOrFieldSerializable(so, ser);
  }

  /**
   * Tests subtypes that introduce new instantiable type parameters.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testSubclassWithNewInstantiableTypeParameters()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B<T extends C> extends A {\n");
      code.append("  T c;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class C implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("C", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JClassType a = to.getType("A");
    JRawType rawB = to.getType("B").isGenericType().getRawType();
    JClassType c = to.getType("C");

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, a);
    SerializableTypeOracle so = sob.build(logger);

    assertInstantiable(so, a);
    assertSerializableTypes(so, a, rawB, c);
  }

  /**
   * Tests subtypes that introduce new uninstantiable type parameters as
   * compared to an implemented interface, where the root type is the interface.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testSubclassWithNewTypeParameterComparedToAnImplementedInterface()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public interface Intf<T> extends Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Intf", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Bar<T> implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Bar", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Foo<T extends Ser> extends Bar<T> implements Intf<String> {\n");
      code.append("  T x;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Foo", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class Ser implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Ser", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JGenericType intf = to.getType("Intf").isGenericType();
    JClassType foo = to.getType("Foo");
    JClassType bar = to.getType("Bar");
    JClassType intfOfString = to.getParameterizedType(intf,
        new JClassType[] {to.getType(String.class.getName())});
    JClassType ser = to.getType("Ser");

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, intfOfString);
    SerializableTypeOracle so = sob.build(logger);

    /*
     * TODO(spoon): should also check that Intf<String> has instantiable
     * subclasses; currently the APIs for STOB and STO do not make this possible
     * to test
     */
    assertInstantiable(so, ser);
    assertSerializableTypes(so, foo.getErasedType(), bar.getErasedType(),
        ser.getErasedType());
  }

  /**
   * Tests subtypes that introduce new uninstantiable type parameters.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testSubclassWithNewUninstantiableTypeParameters()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B<T> extends A {\n");
      code.append("  T x;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JClassType a = to.getType("A");

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, a);
    SerializableTypeOracle so = sob.build(logger);

    assertInstantiable(so, a);
    assertSerializableTypes(so, a);
  }

  /**
   * Tests that STOB skips transient fields.
   */
  public void testTransient() throws UnableToCompleteException,
      NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import com.google.gwt.user.client.rpc.GwtTransient;\n");
      code.append("import java.io.Serializable;\n");
      code.append("public class A implements Serializable {\n");
      code.append("  transient ServerOnly1 serverOnly1;\n");
      code.append("  @GwtTransient ServerOnly2 serverOnly2;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("class ServerOnly1 implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ServerOnly1", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("class ServerOnly2 implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ServerOnly2", code));
    }

    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JClassType a = to.getType("A");
    JClassType serverOnly1 = to.getType("ServerOnly1");
    JClassType serverOnly2 = to.getType("ServerOnly2");

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, a);
    SerializableTypeOracle so = sob.build(logger);

    assertSerializableTypes(so, a);
    assertInstantiable(so, a);
    assertNotFieldSerializable(so, serverOnly1);
    assertNotFieldSerializable(so, serverOnly2);
  }

  /**
   * Miscellaneous direct tests of {@link TypeConstrainer}.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testTypeConstrainer() throws NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("public interface Intf1 {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Intf1", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public interface Intf2 {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Intf2", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public interface Intf3 {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Intf3", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public class Implements12 implements Intf1, Intf2 {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Implements12", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public class ImplementsNeither {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("ImplementsNeither", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public class Sup {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Sup", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public class Sub extends Sup {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Sub", code));
    }
    {
      StringBuilder code = new StringBuilder();
      code.append("public class Holder<T> {\n");
      code.append("  T x;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("Holder", code));
    }
    TreeLogger logger = createLogger();
    TypeOracle to = TypeOracleTestingUtils.buildTypeOracle(logger, resources);

    JClassType intf1 = to.getType("Intf1");
    JClassType intf2 = to.getType("Intf2");
    JClassType intf3 = to.getType("Intf3");
    JClassType implements12 = to.getType("Implements12");
    JClassType implementsNeither = to.getType("ImplementsNeither");
    JClassType string = to.getType(String.class.getCanonicalName());
    JClassType sub = to.getType("Sub");
    JClassType sup = to.getType("Sup");
    JGenericType holder = to.getType("Holder").isGenericType();

    JClassType arrayOfInt = to.getArrayType(JPrimitiveType.INT);
    JClassType arrayOfFloat = to.getArrayType(JPrimitiveType.FLOAT);
    JClassType arrayOfString = to.getArrayType(string);
    JClassType arrayOfWildExtString = to.getArrayType(to.getWildcardType(
        BoundType.EXTENDS, string));
    JClassType holderOfString = to.getParameterizedType(holder,
        makeArray(to.getWildcardType(BoundType.EXTENDS, string)));
    JClassType holderOfSub = to.getParameterizedType(holder,
        makeArray(to.getWildcardType(BoundType.EXTENDS, sub)));
    JClassType holderOfSup = to.getParameterizedType(holder,
        makeArray(to.getWildcardType(BoundType.EXTENDS, sup)));

    TypeConstrainer typeConstrainer = new TypeConstrainer(to);
    Map<JTypeParameter, JClassType> emptyConstraints = new HashMap<JTypeParameter, JClassType>();

    assertTrue(typeConstrainer.typesMatch(intf1, intf2, emptyConstraints));
    assertFalse(typeConstrainer.typesMatch(intf1, intf3, emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(implements12, intf1, emptyConstraints));
    assertFalse(typeConstrainer.typesMatch(implements12, intf3,
        emptyConstraints));
    assertFalse(typeConstrainer.typesMatch(implementsNeither, intf1,
        emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(to.getJavaLangObject(),
        arrayOfString, emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(arrayOfString,
        to.getJavaLangObject(), emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(sub, sup, emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(sub, sub, emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(arrayOfFloat, arrayOfFloat,
        emptyConstraints));
    assertFalse(typeConstrainer.typesMatch(arrayOfFloat, arrayOfInt,
        emptyConstraints));
    assertFalse(typeConstrainer.typesMatch(arrayOfFloat, arrayOfString,
        emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(arrayOfString, arrayOfString,
        emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(arrayOfString, arrayOfWildExtString,
        emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(holderOfSub, holderOfSup,
        emptyConstraints));
    assertFalse(typeConstrainer.typesMatch(holderOfSub, holderOfString,
        emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(holder.getRawType(), holderOfSub,
        emptyConstraints));
    assertTrue(typeConstrainer.typesMatch(holderOfSub, holder.getRawType(),
        emptyConstraints));
    assertFalse(typeConstrainer.typesMatch(holder.getRawType(), intf1,
        emptyConstraints));

    assertTrue(emptyConstraints.isEmpty());
  }

  /**
   * Tests root types that have type parameters.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testTypeParametersInRootTypes1()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class A<T> implements Serializable {\n");
      code.append("  T t;\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", 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));

    JParameterizedType parameterizedType = to.getParameterizedType(a,
        new JClassType[] {syntheticTypeParam});
    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, parameterizedType);
    SerializableTypeOracle so = sob.build(logger);

    assertInstantiable(so, rawA);
    assertInstantiable(so, b);
    assertSerializableTypes(so, rawA, b);
  }

  /**
   * Tests root types that <em>are</em> type parameters.
   * 
   * @throws UnableToCompleteException
   * @throws NotFoundException
   */
  public void testTypeParametersInRootTypes2()
      throws UnableToCompleteException, NotFoundException {
    Set<Resource> resources = new HashSet<Resource>();
    addStandardClasses(resources);

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public abstract class A<U extends B> implements Serializable {\n");
      code.append("  <V extends C>  V getFoo() { return null; }\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("A", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class B implements Serializable {\n");
      code.append("}\n");
      resources.add(new StaticJavaResource("B", code));
    }

    {
      StringBuilder code = new StringBuilder();
      code.append("import java.io.Serializable;\n");
      code.append("public class C implements Serializable {\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();
    JClassType b = to.getType("B");
    JClassType c = to.getType("C");
    JTypeParameter u = a.getTypeParameters()[0];
    JTypeParameter v = a.getMethod("getFoo", makeArray()).getReturnType().isTypeParameter();

    SerializableTypeOracleBuilder sob = createSerializableTypeOracleBuilder(
        logger, to);
    sob.addRootType(logger, u);
    sob.addRootType(logger, v);
    SerializableTypeOracle so = sob.build(logger);

    assertSerializableTypes(so, b, c);
    assertInstantiable(so, b);
    assertInstantiable(so, c);
    assertNotInstantiableOrFieldSerializable(so, a.getRawType());
  }

  private JClassType[] makeArray(JClassType... elements) {
    return elements;
  }
}
