/*
 * Copyright 2011 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.server.rpc;

import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.IsSerializable;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializedTypeViolationException;
import com.google.gwt.user.client.rpc.TestSetFactory.ReverseSorter;
import com.google.gwt.user.server.rpc.RPCTypeCheckCollectionsTest.TestHashSet;
import com.google.gwt.user.server.rpc.testcases.TypeVariableCycle;

import junit.framework.TestCase;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;

/**
 * Test cases for the type checking code found in server-side RPC
 * deserialization.
 */
public class RPCTypeCheckTest extends TestCase {

  /*
   * Test that collection classes correctly report when they are not the
   * expected type, when the other type is a class.
   *   - ArrayList<Integer>: testArrayListSpoofingClass
   *   - ArraysAsList<Integer>: testArraysAsListSpoofingClass
   *   - EmptyList<Integer>: testEmptyListSpoofingClass
   *   - EmptyMap<String, Integer>: testEmptyMapSpoofingClass
   *   - EmptySet<Integer>: testEmptySetSpoofingClass
   *   - HashMap<String, Integer>: testHashMapSpoofingClass
   *   - HashSet<Integer>: testHashSetSpoofingClass
   *   - IdentityHashMap<AClass, Integer>: testIdentityHashMapSpoofingClass
   *   - LinkedHashMap<String, Integer>: testLinkedHashMapSpoofingClass
   *   - LinkedHashSet<Integer>: testHashSetSpoofingClass
   *   - LinkedList<Integer>: testLinkedListSpoofingClass
   *   - SingletonList<Integer>: testSingletonListSpoofingClass
   *   - TreeMap<String, Integer>: testTreeMapSpoofingClass
   *   - TreeSet<Integer>: testTreeSetSpoofingClass
   *   - Vector<Integer>: testVectorSpoofingClass
   * 
   * Test that primitive classes cannot be interchanged, or can safely. In
   * general, these do not pose much danger as the serialization for basic types
   * all perform a strictly finite amount of work and catch invalid 
   * representations.
   *   - Integer for String, and vice versa: testPrimitiveSpoofing
   *   - int for String, and String for int: testValueSpoofing
   *   
   * Test collections in fields of classes:
   *   - BClass contains a List<Integer>: testClassField
   *   - CClass contains a BClass: testClassField
   *   - KClass<X> contains a DClass<X, Integer> and List<X>: testGenericFields
   *   
   * Test generic classes that use their generic types in various ways
   *   - DClass<X, Y> extends LinkedList<X>: testGenericClasses
   *   - EClass<X, Y> { HashMap<X, Y> ... }: testGenericClasses
   *   - FClass<X, Y> { List<X> ... List<Y> ... }: testGenericClasses
   *   - GClass<X, Y> { DClass<X, Y>, ... }: testNestedGenericClasses
   *   - JClass<X, Y> { fields of HashMap }: testGenericFields
   *      
   * 
   * Wildcard types
   *   - (IClass<? extends T> arg1) with
   *      <T extends Set<? super GEClass<Integer, String>>>: testComplexGenerics
   *   - LClass<T implements List<X> & MClass<Y>>: testMethodClassGenerics 
   */  
  
  /**
   * Test custom class.
   */
  public static class AClass extends Object implements IsSerializable {
    int a = 9876;

    AClass() {
    }

    AClass(int aVal) {
      a = aVal;
    }

    int getA() {
      return a;
    }

    void setA(int newA) {
      a = newA;
    }
  }

  /**
   * Test custom class containing a parameterized collection.
   */
  public static class BClass extends Object implements IsSerializable {
    List<Integer> aList = new LinkedList<Integer>();

    BClass() {
    }

    BClass(int aVal) {
      aList.add(aVal);
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    public void setList(List newValue) {
      aList = newValue;
    }
  }

  /**
   * Test custom class containing a raw collection.
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  public static class BClassRaw extends Object implements IsSerializable {
    List aList = new LinkedList();

    BClassRaw() {
    }

    BClassRaw(int aVal) {
      aList.add(aVal);
    }

    public void setList(List newValue) {
      aList = newValue;
    }
  }

  /**
   * Test custom class containing a subclass containing a parameterized
   * collection.
   */
  public static class CClass extends Object implements IsSerializable {
    BClass b = new BClass(12345);

    CClass() {
    }

    public void setBClass(BClass newValue) {
      b = newValue;
    }
  }

  /**
   * Test custom class containing a subclass containing a raw
   * collection.
   */
  public static class CClassRaw extends Object implements IsSerializable {
    BClassRaw b = new BClassRaw(12345);

    CClassRaw() {
    }

    public void setBClass(BClassRaw newValue) {
      b = newValue;
    }
  }

  /**
   * A class containing a method used to check type spoofing attacks on RPC
   * messages containing novel classes.
   */
  public static class ClassesParamTestClass<T extends List<Integer> & MInterface<String>>
      implements RemoteService {
    @SuppressWarnings("unused")
    public static void testAClass(AClass arg1) {
    }

    @SuppressWarnings("unused")
    public static void testAClassArray(AClass[] arg1) {
    }

    @SuppressWarnings("unused")
    public static void testBClass(BClass arg1) {
    }

    @SuppressWarnings("unused")
    public static void testBClassRaw(BClassRaw arg1) {
    }

    @SuppressWarnings("unused")
    public static void testCClass(CClass arg1) {
    }

    @SuppressWarnings("unused")
    public static void testCClassRaw(CClassRaw arg1) {
    }

    @SuppressWarnings("unused")
    public static <T extends Set<? super GEClass<Integer, String>>> void testComplexGenerics(
        IClass<? extends T> arg1) {
    }

    @SuppressWarnings({"unused", "rawtypes"})
    public static <T extends Set<? super GEClass>> void testComplexGenericsRaw(
        IClass<? extends T> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testDClass(DClass<Integer, String> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testDClassRaw(DClassRaw<String> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testEClass(EClass<String, Integer> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testFClass(FClass<Integer, String> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testFClassRaw(FClassRaw<Integer> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testGDClass(GDClass<Integer, String> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testGDClassRaw1(GDClassRaw arg1) {
    }

    @SuppressWarnings({"unused", "rawtypes"})
    public static void testGDClassRaw2(GDClass arg1) {
    }

    @SuppressWarnings("unused")
    public static void testGEClass(GEClass<Integer, String> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testHDClass(HDClass<Integer, String> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testHEClass(HEClass<Integer, String> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testJClass(JClass<Integer, String> arg1) {
    }

    @SuppressWarnings("unused")
    public static void testJClassRaw1(JClassRaw<Integer, String> arg1) {
    }

    @SuppressWarnings({"unused", "rawtypes"})
    public static void testJClassRaw2(JClass arg1) {
    }

    @SuppressWarnings({"unused"})
    public static void testKClass(KClass<String> arg1) {
    }

    @SuppressWarnings({"unused", "rawtypes"})
    public static void testKClassRaw(KClass arg1) {
    }

    @SuppressWarnings("unused")
    public void testWildcardBounds(T arg1) {
    }
  }

  /**
   * Test custom parameterized class that extends a parameterized class and
   * includes a field of a parameterized type.
   */
  public static class DClass<X, Y> extends LinkedList<X> implements IsSerializable {
    Y y;

    DClass() {
      y = null;
    }

    void setY(Y value) {
      y = value;
    }
  }

  /**
   * Test custom parameterized class that extends a parameterized class and
   * includes a field of a parameterized type, with no actual parameters (raw).
   */
  @SuppressWarnings("rawtypes")
  public static class DClassRaw<Y> extends LinkedList implements IsSerializable {
    Y y;

    DClassRaw() {
      y = null;
    }

    void setY(Y value) {
      y = value;
    }
  }

  /**
   * Test custom parameterized class that includes a field of a parameterized
   * type, with two types.
   */
  public static class EClass<X, Y> extends Object implements IsSerializable {
    HashMap<X, Y> map;

    EClass() {
      map = null;
    }

    void setMap(HashMap<X, Y> value) {
      map = value;
    }
  }

  /**
   * Test custom parameterized class that includes two fields, each using one of
   * the parameterized types.
   */
  public static class FClass<X, Y> extends Object implements IsSerializable {
    List<X> listX;
    List<Y> listY;

    FClass() {
      listX = null;
      listY = null;
    }

    void setX(List<X> value) {
      listX = value;
    }

    void setY(List<Y> value) {
      listY = value;
    }
  }

  /**
   * Test custom parameterized class that includes two fields, one using the
   * parameter type and the other raw. We wish to ensure that the raw type
   * does not feel the need to be the parameter type.
   */
  @SuppressWarnings("rawtypes")
  public static class FClassRaw<X> extends Object implements IsSerializable {
    List<X> listX;
    List listY;

    FClassRaw() {
      listX = null;
      listY = null;
    }

    void setX(List<X> value) {
      listX = value;
    }

    void setY(List value) {
      listY = value;
    }
  }

  /**
   * Test custom parameterized class that extends another custom parameterized
   * class that extends another parameterized collection.
   */
  public static class GDClass<A, B> extends DClass<A, B> {
  }

  /**
   * Test custom parameterized class that extends another custom parameterized
   * class that extends another parameterized collection, raw version.
   */
  @SuppressWarnings("rawtypes")
  public static class GDClassRaw extends DClass {
  }

  /**
   * Test custom parameterized class that extends another custom parameterized
   * class that has a parameterized collection for a field.
   */
  public static class GEClass<A, B> extends EClass<B, A> {
  }

  /**
   * Test custom parameterized class that uses another custom parameterized
   * class that extends another parameterized collection.
   */
  public static class HDClass<A, B> extends Object implements IsSerializable {
    public DClass<A, B> dClass = null;
  }

  /**
   * Test custom parameterized class that uses another custom parameterized
   * class that has a parameterized collection for a field.
   */
  public static class HEClass<A, B> extends Object implements IsSerializable {
    public EClass<B, A> eClass = null;
  }

  /**
   * Test class that just holds a single field of a generic type.
   */
  public static class IClass<T> extends Object implements IsSerializable {
    T a;

    IClass() {
      a = null;
    }

    IClass(T aVal) {
      a = aVal;
    }

    T getA() {
      return a;
    }

    void setA(T newA) {
      a = newA;
    }
  }

  /**
   * Test class that has fields of the same underlying type but different actual
   * parameters for each type.
   */
  public static class JClass<K, V> extends EClass<K, V> {
    public HashMap<Long, Double> field1 = null;
    public EClass<Short, Float> field2 = null;
    public HashMap<K, V> field3 = null;
    public HashMap<String, Integer> field4 = null;
  }

  /**
   * Test class that has fields of the same underlying type but different actual
   * parameters for each type, including raw types.
   */
  @SuppressWarnings("rawtypes")
  public static class JClassRaw<K, V> extends EClass {
    public HashMap<Long, Double> field1 = null;
    public EClass<Short, Float> field2 = null;
    public HashMap<K, V> field3 = null;
    public HashMap field4 = null;
  }

  /**
   * Test case for a generic type that extends a generic type with fewer
   * parameters, used as a field and as an array.
   * 
   * During testing, instances of DClass are used for all of the fields.
   */
  public static class KClass<X> implements IsSerializable {
    public DClass<X, Integer> field1 = null;
    public List<X> field2 = null;
    public DClass<X, Integer>[] field3 = null;
    public List<X>[] field4 = null;
  }

  /**
   * Test case for multiple wildcard bounds.
   */
  public static class LClass<X, Y> extends LinkedList<X>
      implements MInterface<Y>, IsSerializable {
    public Y field1 = null;
    public List<Y> field2 = null;
    
    @Override
    public Y echo(Y arg) {
      return arg;
    }
  }

  /**
   * An invalid test case for multiple wildcard bounds.
   * 
   * It does not implement List.
   */
  public static class LClassInvalid1<X, Y> extends IClass<X>
      implements MInterface<Y> {
    public Y field1 = null;
    public List<Y> field2 = null;
    
    @Override
    public Y echo(Y arg) {
      return arg;
    }
  }

  /**
   * An invalid test case for multiple wildcard bounds.
   * 
   * It does not implement MInterface.
   */
  public static class LClassInvalid2<X, Y> extends LinkedList<X> implements IsSerializable {
    public Y field1 = null;
    public List<Y> field2 = null;
  }

  /**
   * Test interface for multiple wildcard bounds.
   */
  public interface MInterface<X> {
    X echo(X arg);
  }

  /**
   * A class containing a method used to check type spoofing attacks on RPC
   * messages containing primitive types.
   */
  public static class PrimitiveParamTestClass implements RemoteService {
    @SuppressWarnings("unused")
    public static void testIntegerString(Integer arg1, String arg2) {
    }

    @SuppressWarnings("unused")
    public static void testIntString(int arg1, String arg2) {
    }
  }

  private static String generateArrayListSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      ArrayList<Integer> arrayList = new ArrayList<Integer>();
      arrayList.add(12345);
      arrayList.add(67890);
      strFactory.write(arrayList);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateArraysAsListSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      List<Integer> arrayAsList = Arrays.asList(12345, 67890);
      strFactory.write(arrayAsList);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateBClassSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testBClass");

      BClass arg1 = new BClass();
      LinkedList<HashSet> list = new LinkedList<HashSet>();
      list.add(RPCTypeCheckFactory.generateTestHashSet());
      arg1.setList(list);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateBClassRaw() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testBClassRaw");

      BClassRaw arg1 = new BClassRaw();
      LinkedList<String> list = new LinkedList<String>();
      list.add("foo");
      arg1.setList(list);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateCClassSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testCClass");

      CClass arg1 = new CClass();
      BClass b = new BClass();
      LinkedList<HashSet> list = new LinkedList<HashSet>();
      list.add(RPCTypeCheckFactory.generateTestHashSet());
      b.setList(list);
      arg1.setBClass(b);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateCClassRaw() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testCClassRaw");

      CClassRaw arg1 = new CClassRaw();
      BClassRaw b = new BClassRaw();
      LinkedList<Integer> list = new LinkedList<Integer>();
      list.add(9876);
      b.setList(list);
      arg1.setBClass(b);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings("unchecked")
  private static String generateDClassRaw() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testDClassRaw");

      DClassRaw<String> arg1 = new DClassRaw<String>();
      arg1.setY("foo");
      arg1.add(12345);
      strFactory.write((Object) arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateDClassXSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testDClass");

      DClass<HashSet, String> arg1 = new DClass<HashSet, String>();
      arg1.setY("foo");
      arg1.add(RPCTypeCheckFactory.generateTestHashSet());
      strFactory.write((Object) arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateDClassYSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testDClass");

      DClass<Integer, HashSet> arg1 = new DClass<Integer, HashSet>();
      arg1.setY(RPCTypeCheckFactory.generateTestHashSet());
      arg1.add(12345);
      strFactory.write((Object) arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateEClassXSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testEClass");

      EClass<HashSet, Integer> arg1 = new EClass<HashSet, Integer>();
      arg1.setMap(RPCTypeCheckFactory.generateTestHashMap());
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateEClassYSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testEClass");

      EClass<String, HashSet> arg1 = new EClass<String, HashSet>();
      HashMap<String, HashSet> map = new HashMap<String, HashSet>();
      map.put("foo", RPCTypeCheckFactory.generateTestHashSet());
      arg1.setMap(map);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateEmptyListSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      strFactory.writeEmptyList();

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateEmptyMapSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      strFactory.writeEmptyMap();

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateEmptySetSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      strFactory.writeEmptySet();

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateFClassRaw() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testFClassRaw");

      FClassRaw<Integer> arg1 = new FClassRaw<Integer>();
      LinkedList<Integer> fieldX = new LinkedList<Integer>();
      fieldX.add(12345);
      LinkedList<String> fieldY = new LinkedList<String>();
      fieldY.add("foo");
      arg1.setX(fieldX);
      arg1.setY(fieldY);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateFClassXSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testFClass");

      FClass<HashSet, String> arg1 = new FClass<HashSet, String>();
      LinkedList<HashSet> fieldX = new LinkedList<HashSet>();
      fieldX.add(RPCTypeCheckFactory.generateTestHashSet());
      LinkedList<String> fieldY = new LinkedList<String>();
      fieldY.add("foo");
      arg1.setX(fieldX);
      arg1.setY(fieldY);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateFClassYSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testFClass");

      FClass<Integer, HashSet> arg1 = new FClass<Integer, HashSet>();
      LinkedList<Integer> fieldX = new LinkedList<Integer>();
      fieldX.add(12345);
      LinkedList<HashSet> fieldY = new LinkedList<HashSet>();
      fieldY.add(RPCTypeCheckFactory.generateTestHashSet());
      arg1.setX(fieldX);
      arg1.setY(fieldY);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings("unchecked")
  private static String generateGDClassRaw1() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testGDClassRaw1");

      GDClassRaw gClass = new GDClassRaw();
      gClass.setY("foo");
      gClass.add(12345);
      strFactory.write((Object) gClass);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateGDClassRaw2() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testGDClassRaw2");

      GDClass gClass = new GDClass();
      gClass.setY("foo");
      gClass.add(12345);
      strFactory.write((Object) gClass);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateGDClassXSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testGDClass");

      GDClass<HashSet, String> gClass = new GDClass<HashSet, String>();
      gClass.setY("foo");
      gClass.add(RPCTypeCheckFactory.generateTestHashSet());
      strFactory.write((Object) gClass);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateGDClassYSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testGDClass");

      GDClass<Integer, HashSet> gClass = new GDClass<Integer, HashSet>();
      gClass.setY(RPCTypeCheckFactory.generateTestHashSet());
      gClass.add(12345);
      strFactory.write((Object) gClass);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"cast", "rawtypes"})
  private static String generateGEClassXSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testGEClass");

      GEClass<HashSet, String> arg1 = new GEClass<HashSet, String>();
      HashMap<String, HashSet> map = new HashMap<String, HashSet>();
      map.put("foo", RPCTypeCheckFactory.generateTestHashSet());
      arg1.setMap(map);
      strFactory.write((Object) arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes", "cast"})
  private static String generateGEClassYSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testGEClass");

      GEClass<Integer, HashSet> arg1 = new GEClass<Integer, HashSet>();
      arg1.setMap(RPCTypeCheckFactory.generateTestHashMap());
      strFactory.write((Object) arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateHashMapSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
      hashMap.put("foo", 12345);
      strFactory.write(hashMap);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateHashSetSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      HashSet<Integer> hashSet = new HashSet<Integer>();
      hashSet.add(12345);
      hashSet.add(67890);
      strFactory.write(hashSet);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateHDClassXSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testHDClass");

      HDClass<HashSet, String> hClass = new HDClass<HashSet, String>();
      hClass.dClass = new DClass<HashSet, String>();
      hClass.dClass.setY("foo");
      hClass.dClass.add(RPCTypeCheckFactory.generateTestHashSet());
      strFactory.write(hClass);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateHDClassYSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testHDClass");

      HDClass<Integer, HashSet> hClass = new HDClass<Integer, HashSet>();
      hClass.dClass = new DClass<Integer, HashSet>();
      hClass.dClass.setY(RPCTypeCheckFactory.generateTestHashSet());
      hClass.dClass.add(12345);
      strFactory.write(hClass);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateHEClassXSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testHEClass");

      HEClass<HashSet, String> arg1 = new HEClass<HashSet, String>();
      arg1.eClass = new EClass<String, HashSet>();
      HashMap<String, HashSet> map = new HashMap<String, HashSet>();
      map.put("foo", RPCTypeCheckFactory.generateTestHashSet());
      arg1.eClass.setMap(map);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateHEClassYSpoofing() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testHEClass");

      HEClass<Integer, HashSet> arg1 = new HEClass<Integer, HashSet>();
      arg1.eClass = new EClass<HashSet, Integer>();
      arg1.eClass.setMap(RPCTypeCheckFactory.generateTestHashMap());
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateIClassRaw() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testComplexGenericsRaw");

      /*
       * Generate an object that is valid for IClass<? extends T> where <T extends
       * Set<? super GEClass>>.
       * 
       * EClass is a superclass of GEClass, so we can use that in the thing that
       * extends Set.
       */
      HashMap<Integer, String> eClassField = new HashMap<Integer, String>();
      eClassField.put(12345, "foo");
      EClass<Integer, String> geClass = new EClass<Integer, String>();
      geClass.setMap(eClassField);
      TestHashSet<EClass<Integer, String>> set = new TestHashSet<EClass<Integer, String>>();
      set.add(geClass);
      IClass<TestHashSet<EClass<Integer, String>>> arg1 =
          new IClass<TestHashSet<EClass<Integer, String>>>(set);

      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateIClassSpoofingA() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testComplexGenerics");

      /*
       * Generate an object that spoofs IClass<? extends T> where <T extends
       * Set<? super GEClass<Integer, String>>> at the highest level (i.e.
       * something that does not extend Set).
       * 
       * EClass is a superclass of GEClass, so we can use that in the thing that
       * extends Set. But it switched the parameter order, so we need
       * EClass<String, Integer>.
       * 
       * LinkedList does not extend Set.
       * 
       * So we need to construct this: IClass<LinkedList<EClass<String,
       * Integer>>> arg1
       */
      HashMap<String, Integer> eClassField = new HashMap<String, Integer>();
      eClassField.put("foo", 12345);
      eClassField.put("bar", 67890);
      EClass<String, Integer> geClass = new EClass<String, Integer>();
      geClass.setMap(eClassField);
      LinkedList<EClass<String, Integer>> list = new LinkedList<EClass<String, Integer>>();
      list.add(geClass);
      IClass<LinkedList<EClass<String, Integer>>> arg1 =
          new IClass<LinkedList<EClass<String, Integer>>>(list);

      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateIClassSpoofingB() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testComplexGenerics");

      /*
       * Generate an object that spoofs IClass<? extends T> where <T extends
       * Set<? super GEClass<Integer, String>>> at the second highest level
       * (i.e. something that is not a superclass of GEClass).
       * 
       * Pathological hash set is not a superclass of GEClass, so we can use
       * that.
       * 
       * So we need to construct this: IClass<TestHashSet<HashSet<Integer,
       * String>>> arg1
       */
      HashSet hashSet = RPCTypeCheckFactory.generateTestHashSetHashSet();
      IClass<HashSet> arg1 = new IClass<HashSet>(hashSet);

      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes"})
  private static String generateIClassSpoofingC() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testComplexGenerics");

      /*
       * Generate an object that spoofs IClass<? extends T> where <T extends
       * Set<? super GEClass<Integer, String>>> at the deepest level (i.e.
       * GEClass parameter types).
       * 
       * EClass is a superclass of GEClass, so we can use that in the thing that
       * extends Set. But it switched the parameter order, so we need
       * EClass<String, HashSet>.
       */
      HashMap<String, HashSet> eClassField = new HashMap<String, HashSet>();
      eClassField.put("foo", RPCTypeCheckFactory.generateTestHashSet());
      EClass<String, HashSet> geClass = new EClass<String, HashSet>();
      geClass.setMap(eClassField);
      TestHashSet<EClass<String, HashSet>> set = new TestHashSet<EClass<String, HashSet>>();
      set.add(geClass);
      IClass<TestHashSet<EClass<String, HashSet>>> arg1 =
          new IClass<TestHashSet<EClass<String, HashSet>>>(set);

      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateIClassValid() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testComplexGenerics");

      /*
       * Generate an object that works for IClass<? extends T> where <T extends
       * Set<? super GEClass<Integer, String>>>.
       * 
       * EClass is a superclass of GEClass, so we can use that in the thing that
       * extends Set. But it switched the parameter order, so we need
       * EClass<String, Integer>.
       * 
       * HashSet extends Set.
       * 
       * RPCTypeCheckCollectionsTest.TestHashSet extends HashSet.
       * 
       * So we need to construct this: IClass<TestHashSet<EClass<String,
       * Integer>>> arg1
       */
      HashMap<String, Integer> eClassField = new HashMap<String, Integer>();
      eClassField.put("foo", 12345);
      eClassField.put("bar", 67890);
      EClass<String, Integer> geClass = new EClass<String, Integer>();
      geClass.setMap(eClassField);
      TestHashSet<EClass<String, Integer>> set = new TestHashSet<EClass<String, Integer>>();
      set.add(geClass);
      IClass<TestHashSet<EClass<String, Integer>>> arg1 =
          new IClass<TestHashSet<EClass<String, Integer>>>(set);

      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateIdentityHashMapSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      IdentityHashMap<String, Integer> hashMap = new IdentityHashMap<String, Integer>();
      hashMap.put("foo", 12345);
      strFactory.write(hashMap);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateIntegerSpoofingString() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(PrimitiveParamTestClass.class, "testIntegerString");

      Integer i = 12345;
      strFactory.write(i);

      Integer j = 67890;
      strFactory.write(j);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateIntSpoofingString() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(PrimitiveParamTestClass.class, "testIntString");

      int i = 12345;
      strFactory.write(i);

      int j = 67890;
      strFactory.write(j);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings("unchecked")
  private static String generateJClassRaw1() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testJClassRaw1");

      JClassRaw<Integer, String> arg1 = new JClassRaw<Integer, String>();
      arg1.field1 = new HashMap<Long, Double>();
      arg1.field1.put(123L, 0.12345);
      arg1.field2 = new EClass<Short, Float>();
      HashMap<Short, Float> eClassMap = new HashMap<Short, Float>();
      eClassMap.put((short) 567, 0.456f);
      arg1.field2.setMap(eClassMap);
      arg1.field3 = new HashMap<Integer, String>();
      arg1.field3.put(9876, "foo");
      arg1.field4 = new HashMap<String, Integer>();
      arg1.field4.put("bar", 765);
      HashMap<Integer, String> jClassMap = new HashMap<Integer, String>();
      jClassMap.put(4321, "baz");
      arg1.setMap(jClassMap);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateJClassRaw2() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testJClassRaw2");

      JClass arg1 = new JClass();
      arg1.field1 = new HashMap<Long, Double>();
      arg1.field1.put(123L, 0.12345);
      arg1.field2 = new EClass<Short, Float>();
      HashMap<Short, Float> eClassMap = new HashMap<Short, Float>();
      eClassMap.put((short) 567, 0.456f);
      arg1.field2.setMap(eClassMap);
      arg1.field3 = new HashMap<Integer, String>();
      arg1.field3.put(9876, "foo");
      arg1.field4 = new HashMap<String, Integer>();
      arg1.field4.put("bar", 765);
      HashMap<Integer, String> jClassMap = new HashMap<Integer, String>();
      jClassMap.put(4321, "baz");
      arg1.setMap(jClassMap);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateJClassSpoofing1() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testJClass");

      JClass<Integer, String> arg1 = new JClass<Integer, String>();
      arg1.field1 = (HashMap) RPCTypeCheckFactory.generateTestHashMap();
      arg1.field2 = new EClass<Short, Float>();
      HashMap<Short, Float> eClassMap = new HashMap<Short, Float>();
      eClassMap.put((short) 567, 0.456f);
      arg1.field2.setMap(eClassMap);
      arg1.field3 = new HashMap<Integer, String>();
      arg1.field3.put(9876, "foo");
      arg1.field4 = new HashMap<String, Integer>();
      arg1.field4.put("bar", 765);
      HashMap<Integer, String> jClassMap = new HashMap<Integer, String>();
      jClassMap.put(4321, "baz");
      arg1.setMap(jClassMap);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateJClassSpoofing2() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testJClass");

      JClass<Integer, String> arg1 = new JClass<Integer, String>();
      arg1.field1 = new HashMap<Long, Double>();
      arg1.field1.put(123L, 0.12345);
      arg1.field2 = new EClass<Short, Float>();
      arg1.field2.setMap((HashMap) RPCTypeCheckFactory.generateTestHashMap());
      arg1.field3 = new HashMap<Integer, String>();
      arg1.field3.put(9876, "foo");
      arg1.field4 = new HashMap<String, Integer>();
      arg1.field4.put("bar", 765);
      HashMap<Integer, String> jClassMap = new HashMap<Integer, String>();
      jClassMap.put(4321, "baz");
      arg1.setMap(jClassMap);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateJClassSpoofing3() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testJClass");

      JClass<Integer, String> arg1 = new JClass<Integer, String>();
      arg1.field1 = new HashMap<Long, Double>();
      arg1.field1.put(123L, 0.12345);
      arg1.field2 = new EClass<Short, Float>();
      HashMap<Short, Float> eClassMap = new HashMap<Short, Float>();
      eClassMap.put((short) 567, 0.456f);
      arg1.field2.setMap(eClassMap);
      arg1.field3 = (HashMap) RPCTypeCheckFactory.generateTestHashMap();
      arg1.field4 = new HashMap<String, Integer>();
      arg1.field4.put("bar", 765);
      HashMap<Integer, String> jClassMap = new HashMap<Integer, String>();
      jClassMap.put(4321, "baz");
      arg1.setMap(jClassMap);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateJClassSpoofing4() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testJClass");

      JClass<Integer, String> arg1 = new JClass<Integer, String>();
      arg1.field1 = new HashMap<Long, Double>();
      arg1.field1.put(123L, 0.12345);
      arg1.field2 = new EClass<Short, Float>();
      HashMap<Short, Float> eClassMap = new HashMap<Short, Float>();
      eClassMap.put((short) 567, 0.456f);
      arg1.field2.setMap(eClassMap);
      arg1.field3 = new HashMap<Integer, String>();
      arg1.field3.put(9876, "foo");
      arg1.field4 = (HashMap) RPCTypeCheckFactory.generateTestHashMap();
      HashMap<Integer, String> jClassMap = new HashMap<Integer, String>();
      jClassMap.put(4321, "baz");
      arg1.setMap(jClassMap);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateJClassSpoofing5() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testJClass");

      JClass<Integer, String> arg1 = new JClass<Integer, String>();
      arg1.field1 = new HashMap<Long, Double>();
      arg1.field1.put(123L, 0.12345);
      arg1.field2 = new EClass<Short, Float>();
      HashMap<Short, Float> eClassMap = new HashMap<Short, Float>();
      eClassMap.put((short) 567, 0.456f);
      arg1.field2.setMap(eClassMap);
      arg1.field3 = new HashMap<Integer, String>();
      arg1.field3.put(9876, "foo");
      arg1.field4 = new HashMap<String, Integer>();
      arg1.field4.put("bar", 765);
      arg1.setMap((HashMap) RPCTypeCheckFactory.generateTestHashMap());
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateJClassValid() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testJClass");

      JClass<Integer, String> arg1 = new JClass<Integer, String>();
      arg1.field1 = new HashMap<Long, Double>();
      arg1.field1.put(123L, 0.12345);
      arg1.field2 = new EClass<Short, Float>();
      HashMap<Short, Float> eClassMap = new HashMap<Short, Float>();
      eClassMap.put((short) 567, 0.456f);
      arg1.field2.setMap(eClassMap);
      arg1.field3 = new HashMap<Integer, String>();
      arg1.field3.put(9876, "foo");
      arg1.field4 = new HashMap<String, Integer>();
      arg1.field4.put("bar", 765);
      HashMap<Integer, String> jClassMap = new HashMap<Integer, String>();
      jClassMap.put(4321, "baz");
      arg1.setMap(jClassMap);
      strFactory.write(arg1);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings("unchecked")
  private static String generateKClassValid(String methodName) {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, methodName);
    
      DClass<String, Integer> field1 = new DClass<String, Integer>();
      field1.setY(12);
      field1.add("foo");

      DClass<String, Integer> field2 = new DClass<String, Integer>();
      field2.setY(34);
      field2.add("bar");

      DClass<String, Integer>[] field3 = new DClass[1];
      field3[0] = new DClass<String, Integer>();
      field3[0].setY(56);
      field3[0].add("oof");

      DClass<String, Integer>[] field4 = new DClass[1];
      field4[0] = new DClass<String, Integer>();
      field4[0].setY(78);
      field4[0].add("rab");
      
      KClass<String> arg1 = new KClass<String>();
      arg1.field1 = field1;
      arg1.field2 = field2;
      arg1.field3 = field3;
      arg1.field4 = field4;
      strFactory.write(arg1);
      
      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateKClassInvalid1(String methodName) {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, methodName);
    
      DClass<Integer, Integer> field1 = new DClass<Integer, Integer>();
      field1.setY(12);
      field1.add(90);

      DClass<String, Integer> field2 = new DClass<String, Integer>();
      field2.setY(34);
      field2.add("bar");

      DClass<String, Integer>[] field3 = new DClass[1];
      field3[0] = new DClass<String, Integer>();
      field3[0].setY(56);
      field3[0].add("oof");

      DClass<String, Integer>[] field4 = new DClass[1];
      field4[0] = new DClass<String, Integer>();
      field4[0].setY(78);
      field4[0].add("rab");
      
      KClass arg1 = new KClass();
      arg1.field1 = field1;
      arg1.field2 = field2;
      arg1.field3 = field3;
      arg1.field4 = field4;
      strFactory.write(arg1);
      
      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateKClassInvalid2() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testKClass");
    
      DClass<String, Integer> field1 = new DClass<String, Integer>();
      field1.setY(12);
      field1.add("foo");

      DClass<Integer, Integer> field2 = new DClass<Integer, Integer>();
      field2.setY(34);
      field2.add(90);

      DClass<String, Integer>[] field3 = new DClass[1];
      field3[0] = new DClass<String, Integer>();
      field3[0].setY(56);
      field3[0].add("oof");

      DClass<String, Integer>[] field4 = new DClass[1];
      field4[0] = new DClass<String, Integer>();
      field4[0].setY(78);
      field4[0].add("rab");
      
      KClass arg1 = new KClass();
      arg1.field1 = field1;
      arg1.field2 = field2;
      arg1.field3 = field3;
      arg1.field4 = field4;
      strFactory.write(arg1);
      
      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateKClassInvalid3() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testKClass");
    
      DClass<String, Integer> field1 = new DClass<String, Integer>();
      field1.setY(12);
      field1.add("foo");

      DClass<String, Integer> field2 = new DClass<String, Integer>();
      field2.setY(34);
      field2.add("bar");

      DClass<Integer, Integer>[] field3 = new DClass[1];
      field3[0] = new DClass<Integer, Integer>();
      field3[0].setY(56);
      field3[0].add(90);

      DClass<String, Integer>[] field4 = new DClass[1];
      field4[0] = new DClass<String, Integer>();
      field4[0].setY(78);
      field4[0].add("rab");
      
      KClass arg1 = new KClass();
      arg1.field1 = field1;
      arg1.field2 = field2;
      arg1.field3 = field3;
      arg1.field4 = field4;
      strFactory.write(arg1);
      
      return strFactory.toString();

    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateKClassInvalid4() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testKClass");
    
      DClass<String, Integer> field1 = new DClass<String, Integer>();
      field1.setY(12);
      field1.add("foo");

      DClass<String, Integer> field2 = new DClass<String, Integer>();
      field2.setY(34);
      field2.add("bar");

      DClass<String, Integer>[] field3 = new DClass[1];
      field3[0] = new DClass<String, Integer>();
      field3[0].setY(56);
      field3[0].add("oof");

      DClass<Integer, Integer>[] field4 = new DClass[1];
      field4[0] = new DClass<Integer, Integer>();
      field4[0].setY(78);
      field4[0].add(90);
      
      KClass arg1 = new KClass();
      arg1.field1 = field1;
      arg1.field2 = field2;
      arg1.field3 = field3;
      arg1.field4 = field4;
      strFactory.write(arg1);
      
      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static String generateKClassInvalid5() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testKClass");
    
      DClass<String, String> field1 = new DClass<String, String>();
      field1.setY("bar");
      field1.add("foo");

      DClass<String, Integer> field2 = new DClass<String, Integer>();
      field2.setY(34);
      field2.add("bar");

      DClass<String, Integer>[] field3 = new DClass[1];
      field3[0] = new DClass<String, Integer>();
      field3[0].setY(56);
      field3[0].add("oof");

      DClass<String, Integer>[] field4 = new DClass[1];
      field4[0] = new DClass<String, Integer>();
      field4[0].setY(78);
      field4[0].add("rab");
      
      KClass arg1 = new KClass();
      arg1.field1 = field1;
      arg1.field2 = field2;
      arg1.field3 = field3;
      arg1.field4 = field4;
      strFactory.write(arg1);
      
      return strFactory.toString();

    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }
  
  private static String generateLClassInvalid1() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testWildcardBounds");
    
      LClass<String, String> arg = new LClass<String, String>();
      arg.add("foo");
      arg.field1 = "foo";
      arg.field2 = new LinkedList<String>();
      arg.field2.add("bar");
      strFactory.write((Object) arg);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateLClassInvalid2() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testWildcardBounds");
    
      LClass<Integer, Integer> arg = new LClass<Integer, Integer>();
      arg.add(12345);
      arg.field1 = 67890;
      arg.field2 = new LinkedList<Integer>();
      arg.field2.add(45678);
      strFactory.write((Object) arg);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateLClassInvalid3() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testWildcardBounds");
    
      LClassInvalid1<Integer, String> arg = new LClassInvalid1<Integer, String>();
      arg.setA(12345);
      arg.field1 = "foo";
      arg.field2 = new LinkedList<String>();
      arg.field2.add("bar");
      strFactory.write(arg);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateLClassInvalid4() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testWildcardBounds");
    
      LClassInvalid2<Integer, String> arg = new LClassInvalid2<Integer, String>();
      arg.add(12345);
      arg.field1 = "foo";
      arg.field2 = new LinkedList<String>();
      arg.field2.add("bar");
      strFactory.write((Object) arg);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  private static String generateLClassInvalid5() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testWildcardBounds");
    
      LClass arg = new LClass();
      arg.add("oof");
      arg.field1 = "foo";
      arg.field2 = new LinkedList<String>();
      arg.field2.add("bar");
      strFactory.write((Object) arg);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  private static String generateLClassInvalid6() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testWildcardBounds");
    
      LClass arg = new LClass();
      arg.add(12345);
      arg.field1 = 67890;
      arg.field2 = new LinkedList<String>();
      arg.field2.add("bar");
      strFactory.write((Object) arg);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  private static String generateLClassInvalid7() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testWildcardBounds");
    
      LClass arg = new LClass();
      arg.add(12345);
      arg.field1 = "foo";
      arg.field2 = new LinkedList<Integer>();
      arg.field2.add(67890);
      strFactory.write((Object) arg);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateLClassValid() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testWildcardBounds");
    
      LClass<Integer, String> arg = new LClass<Integer, String>();
      arg.add(12345);
      arg.field1 = "foo";
      arg.field2 = new LinkedList<String>();
      arg.field2.add("bar");
      strFactory.write((Object) arg);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateLinkedHashMapSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      LinkedHashMap<String, Integer> hashMap = new LinkedHashMap<String, Integer>();
      hashMap.put("foo", 12345);
      strFactory.write(hashMap);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateLinkedHashSetSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      LinkedHashSet<Integer> hashSet = new LinkedHashSet<Integer>();
      hashSet.add(12345);
      hashSet.add(67890);
      strFactory.write(hashSet);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateLinkedListSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      LinkedList<Integer> list = new LinkedList<Integer>();
      list.add(12345);
      list.add(67890);
      strFactory.write(list);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateSingletonListSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      Integer i = new Integer(67890);
      List<Integer> singletonList = Collections.singletonList(i);
      strFactory.write(singletonList);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateStringSpoofingInt() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(PrimitiveParamTestClass.class, "testIntString");

      String arg1 = "foo";
      strFactory.write(arg1);

      String arg2 = "bar";
      strFactory.write(arg2);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateStringSpoofingInteger() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(PrimitiveParamTestClass.class, "testIntegerString");

      String arg1 = "foo";
      strFactory.write(arg1);

      String arg2 = "bar";
      strFactory.write(arg2);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateTreeMapSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>();
      treeMap.put("foo", 12345);
      strFactory.write(treeMap);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateTreeSetSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      ReverseSorter<Integer> sorter = new ReverseSorter<Integer>();
      TreeSet<Integer> treeSet = new TreeSet<Integer>(sorter);
      treeSet.add(12345);
      treeSet.add(67890);
      strFactory.write(treeSet);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  private static String generateVectorSpoofingClass() {
    try {
      RPCTypeCheckFactory strFactory =
          new RPCTypeCheckFactory(ClassesParamTestClass.class, "testAClass");

      Vector<Integer> vector = new Vector<Integer>();
      vector.add(12345);
      vector.add(67890);
      strFactory.write(vector);

      return strFactory.toString();
    } catch (Exception e) {
      fail(e.getMessage());

      return null;
    }
  }

  /**
   * This checks that ArrayList correctly reports that it is an incorrect type.
   */
  public void testArrayListSpoofingClass() {
    try {
      RPC.decodeRequest(generateArrayListSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testArrayListSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*ArrayList.*AClass.*"));
    }
  }

  /**
   * This checks that a List generated by Arrays.asList correctly reports that
   * it is an incorrect type.
   */
  public void testArraysAsListSpoofingClass() {
    try {
      RPC.decodeRequest(generateArraysAsListSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testArraysAsListSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Arrays\\$ArrayList.*AClass.*"));
    }
  }

  /**
   * This checks that generic fields of classes work correctly.
   */
  public void testClassFields() {
    try {
      RPC.decodeRequest(generateBClassSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testClassFields (1)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateCClassSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testClassFields (2)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
  }

  /**
   * This checks that raw collections fields of classes work correctly.
   */
  public void testClassFieldsRaw() {
    try {
      RPC.decodeRequest(generateBClassRaw());
    } catch (Exception e) {
      fail("Unexpected Exception from testClassFieldsRaw (1): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateCClassRaw());
    } catch (Exception e) {
      fail("Unexpected Exception from testClassFieldsRaw (2): " + e.getMessage());
    }
  }

  /**
   * This checks that complex generic declarations are both correctly serialized
   * (no false negatives) and correctly verified.
   */
  public void testComplexGenerics() {
    try {
      RPC.decodeRequest(generateIClassValid());
    } catch (Exception e) {
      fail("Unexpected assertion from testComplexGenerics (1a): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateIClassRaw());
    } catch (Exception e) {
      fail("Unexpected assertion from testComplexGenerics (1b): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateIClassSpoofingA());
      fail("Expected IncompatibleRemoteServiceException from testComplexGenerics (2)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*LinkedList.*? extends T.*"));
    }
    try {
      RPC.decodeRequest(generateIClassSpoofingB());
      fail("Expected IncompatibleRemoteServiceException from testComplexGenerics (3)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*? super .*GEClass.*"));
    }
    try {
      RPC.decodeRequest(generateIClassSpoofingC());
      fail("Expected IncompatibleRemoteServiceException from testComplexGenerics (4)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
  }

  /**
   * This checks that a List generated by Collections.emptyList correctly
   * reports that it is an incorrect type.
   */
  public void testEmptyListSpoofingClass() {
    try {
      RPC.decodeRequest(generateEmptyListSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testEmptyListSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*List.*AClass.*"));
    }
  }

  /**
   * This checks that a Map generated by Collections.emptyMap correctly reports
   * that it is an incorrect type.
   */
  public void testEmptyMapSpoofingClass() {
    try {
      RPC.decodeRequest(generateEmptyMapSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testEmptyMapSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Map.*AClass.*"));
    }
  }

  /**
   * This checks that a Set generated by Collections.emptySet correctly reports
   * that it is an incorrect type.
   */
  public void testEmptySetSpoofingClass() {
    try {
      RPC.decodeRequest(generateEmptySetSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testEmptySetSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Set.*AClass.*"));
    }
  }

  /**
   * This checks that fields of generic classes work correctly.
   */
  public void testGenericClasses() {
    try {
      RPC.decodeRequest(generateDClassRaw());
    } catch (Exception e) {
      fail("Unexpected assertion from testGenericClasses (1-): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateDClassXSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testGenericClasses (1)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateDClassYSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testGenericClasses (2)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*String.*"));
    }
    try {
      RPC.decodeRequest(generateEClassXSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testGenericClasses (3)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*String.*"));
    }
    try {
      RPC.decodeRequest(generateEClassYSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testGenericClasses (4)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateFClassRaw());
    } catch (Exception e) {
      fail("Unexpected assertion from testGenericClasses (5-): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateFClassXSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testGenericClasses (5)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateFClassYSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testGenericClasses (6)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*String.*"));
    }
  }

  /**
   * This tests that generic class with fields that have the same types but
   * different actual parameters are correctly handled.
   *
   * It also checks classes with fields that have more generic arguments
   * than the class provides, or that use instances with more parameters than
   * the field itself requires (i.e List<X> when used as Object).
   */
  public void testGenericFields() {
    try {
      RPC.decodeRequest(generateJClassValid());
    } catch (Exception e) {
      fail("Unexpected assertion from testGenericFields (1a): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateJClassRaw1());
    } catch (Exception e) {
      fail("Unexpected assertion from testGenericFields (1b): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateJClassRaw2());
    } catch (Exception e) {
      fail("Unexpected assertion from testGenericFields (1c): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateJClassSpoofing1());
      fail("Expected IncompatibleRemoteServiceException from testGenericFields (2)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Long.*"));
    }
    try {
      RPC.decodeRequest(generateJClassSpoofing2());
      fail("Expected IncompatibleRemoteServiceException from testGenericFields (3)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Short.*"));
    }
    try {
      RPC.decodeRequest(generateJClassSpoofing3());
      fail("Expected IncompatibleRemoteServiceException from testGenericFields (4)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateJClassSpoofing4());
      fail("Expected IncompatibleRemoteServiceException from testGenericFields (5)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*String.*"));
    }
    try {
      RPC.decodeRequest(generateJClassSpoofing5());
      fail("Expected IncompatibleRemoteServiceException from testGenericFields (6)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateKClassValid("testKClass"));
    } catch (Exception e) {
      fail("Unexpected assertion from testGenericFields (7a): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateKClassValid("testKClassRaw"));
    } catch (Exception e) {
      fail("Unexpected assertion from testGenericFields (7b): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateKClassInvalid1("testKClass"));
      fail("Expected IncompatibleRemoteServiceException from testGenericFields (7c)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Integer.*String.*"));
    }
    try {
      RPC.decodeRequest(generateKClassInvalid1("testKClassRaw"));
    } catch (Exception e) {
      fail("Unexpected assertion from testGenericFields (7d): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateKClassInvalid2());
      fail("Expected IncompatibleRemoteServiceException from testGenericFields (7e)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Integer.*String.*"));
    }
    try {
      RPC.decodeRequest(generateKClassInvalid3());
      fail("Expected IncompatibleRemoteServiceException from testGenericFields (7f)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Integer.*String.*"));
    }
    try {
      RPC.decodeRequest(generateKClassInvalid4());
      fail("Expected IncompatibleRemoteServiceException from testGenericFields (7g)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Integer.*String.*"));
    }
    try {
      RPC.decodeRequest(generateKClassInvalid5());
      fail("Expected IncompatibleRemoteServiceException from testGenericFields (7h)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*String.*Integer.*"));
    }
  }

  /**
   * Test for <a href="https://code.google.com/p/google-web-toolkit/issues/detail?id=7779">7779</a>.
   */
  public void testTypeVariableCycle() throws Exception {

    // Build an RPC request that calls dereference(hello)
    RPCTypeCheckFactory builder = new RPCTypeCheckFactory(TypeVariableCycle.class, "dereference");
    builder.write(TypeVariableCycle.HELLO);
    String request = builder.toString();

    // Make sure we can decode it.
    RPCRequest decoded = RPC.decodeRequest(request);
    Object deserializedArg = decoded.getParameters()[0];
    assertEquals(TypeVariableCycle.PtrPtr.class, deserializedArg.getClass());
    assertEquals("hello", ((TypeVariableCycle.PtrPtr) deserializedArg).get());
  }

  /**
   * This checks that HashMap correctly reports that it is an incorrect type.
   */
  public void testHashMapSpoofingClass() {
    try {
      RPC.decodeRequest(generateHashMapSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testHashMapSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashMap.*AClass.*"));
    }
  }

  /**
   * This checks that HashSet correctly reports that it is an incorrect type.
   */
  public void testHashSetSpoofingClass() {
    try {
      RPC.decodeRequest(generateHashSetSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testHashSetSpoofingClass (1)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(e.getCause().getClass(), SerializedTypeViolationException.class);
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*AClass.*"));
    }
    try {
      RPC.decodeRequest(generateLinkedHashSetSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testHashSetSpoofingClass (2)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*LinkedHashSet.*AClass.*"));
    }
  }

  /**
   * This checks that IdentityHashMap correctly reports that it is an incorrect
   * type.
   */
  public void testIdentityHashMapSpoofingClass() {
    try {
      RPC.decodeRequest(generateIdentityHashMapSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testIdentityHashMapSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*IdentityHashMap.*AClass.*"));
    }
  }

  /**
   * This checks that LinkedHashMap correctly reports that it is an incorrect
   * type.
   */
  public void testLinkedHashMapSpoofingClass() {
    try {
      RPC.decodeRequest(generateLinkedHashMapSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testLinkedHashMapSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*LinkedHashMap.*AClass.*"));
    }
  }

  /**
   * This checks that LinkedList correctly reports that it is an incorrect type.
   */
  public void testLinkedListSpoofingClass() {
    try {
      RPC.decodeRequest(generateLinkedListSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testLinkedListSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*LinkedList.*AClass.*"));
    }
  }

  /**
   * This checks that we correctly report, or don't report, errors when we
   * cannot know the actual value of a generic but may have bounds from the
   * method class.
   * 
   * In this case,
   * ClassesParamTestClass<T extends List<Integer> & MInterface<String>>
   * is the class containing the method, and the method expects an argument of
   * type T, so the thing in the RPC method should meet the bounds on T.
   */
  public void testMethodClassGenerics() {
    try {
      RPC.decodeRequest(generateLClassValid());
    } catch (Exception e) {
      fail("Unexpected assertion from testMethodClassGenerics (1): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateLClassInvalid1());
      fail("Expected IncompatibleRemoteServiceException from testMethodClassGenerics (2)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*String.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateLClassInvalid2());
      fail("Expected IncompatibleRemoteServiceException from testMethodClassGenerics (3)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Integer.*String.*"));
    }
    try {
      RPC.decodeRequest(generateLClassInvalid3());
      fail("Expected IncompatibleRemoteServiceException from testMethodClassGenerics (4)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*LClassInvalid1.*T.*"));
    }
    try {
      RPC.decodeRequest(generateLClassInvalid4());
      fail("Expected IncompatibleRemoteServiceException from testMethodClassGenerics (5)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*LClassInvalid2.*T.*"));
    }
    try {
      RPC.decodeRequest(generateLClassInvalid5());
      fail("Expected IncompatibleRemoteServiceException from testMethodClassGenerics (6)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*String.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateLClassInvalid6());
      fail("Expected IncompatibleRemoteServiceException from testMethodClassGenerics (7)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Integer.*String.*"));
    }
    try {
      RPC.decodeRequest(generateLClassInvalid7());
      fail("Expected IncompatibleRemoteServiceException from testMethodClassGenerics (8)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Integer.*String.*"));
    }
  }

  /**
   * This checks that fields of generic classes work correctly.
   */
  public void testNestedGenericClasses() {
    try {
      RPC.decodeRequest(generateGDClassRaw1());
    } catch (Exception e) {
      fail("Unexpected Exception from testNestedGenericClasses (0a): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateGDClassRaw2());
    } catch (Exception e) {
      fail("Unexpected Exception from testNestedGenericClasses (0b): " + e.getMessage());
    }
    try {
      RPC.decodeRequest(generateGDClassXSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testNestedGenericClasses (1)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateGDClassYSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testNestedGenericClasses (2)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*String.*"));
    }
    try {
      RPC.decodeRequest(generateGEClassXSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testNestedGenericClasses (3)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateGEClassYSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testNestedGenericClasses (4)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*String.*"));
    }
    try {
      RPC.decodeRequest(generateHDClassXSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testNestedGenericClasses (5)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateHDClassYSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testNestedGenericClasses (6)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*String.*"));
    }
    try {
      RPC.decodeRequest(generateHEClassXSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testNestedGenericClasses (7)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*Integer.*"));
    }
    try {
      RPC.decodeRequest(generateHEClassYSpoofing());
      fail("Expected IncompatibleRemoteServiceException from testNestedGenericClasses (8)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*HashSet.*String.*"));
    }
  }

  /**
   * This checks situations in which an RPC message is modified to replace
   * arguments of a primitive type with another primitive type.
   */
  public void testPrimitiveSpoofingPrimitive() {
    try {
      // An integer can pretend to be a string, and the result will be the
      // Integer class serialization string appearing as the string value.
      RPC.decodeRequest(generateIntegerSpoofingString());
    } catch (IncompatibleRemoteServiceException e) {
      fail("Unexpected IncompatibleRemoteServiceException from testPrimitiveSpoofingPrimitive (1)");
    }
    try {
      RPC.decodeRequest(generateStringSpoofingInteger());
      fail("Expected IncompatibleRemoteServiceException from testPrimitiveSpoofingPrimitive (2)");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializationException.class, e.getCause().getClass());
    }
  }

  /**
   * This checks that Collections.singletonList correctly reports that it is an
   * incorrect type.
   */
  public void testSingletonListSpoofingClass() {
    try {
      RPC.decodeRequest(generateSingletonListSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testSingletonListSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*List.*AClass.*"));
    }
  }

  /**
   * This checks that TreeMap correctly reports that it is an incorrect type.
   */
  public void testTreeMapSpoofingClass() {
    try {
      RPC.decodeRequest(generateTreeMapSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testTreeMapSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*TreeMap.*AClass.*"));
    }
  }

  /**
   * This checks that TreeSet correctly reports that it is an incorrect type.
   */
  public void testTreeSetSpoofingClass() {
    try {
      RPC.decodeRequest(generateTreeSetSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testTreeSetSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*TreeSet.*AClass.*"));
    }
  }

  /**
   * This checks situations in which an RPC message is modified to replace
   * arguments of a primitive value type with another primitive type.
   */
  public void testValueSpoofing() {
    boolean returned = false;
    try {
      // When an int appears in place of a string, the result will be the
      // int value indexing the string table, which will result in
      // an out of bounds exception if the index is out of bounds, or
      // an incorrect string if the integer value is within range of the string
      // table.
      RPC.decodeRequest(generateIntSpoofingString());
      returned = true;
    } catch (AssertionError e) {
      // Expected
    }
    if (returned) {
      fail("RPC.decodeRequest should have thrown.");
    }

    try {
      // When a string pretends to be an int, it simply results in an incorrect
      // integer value.
      RPC.decodeRequest(generateStringSpoofingInt());
    } catch (Exception e) {
      fail("Unexpected exception: " + e.toString());
    }
  }

  /**
   * This checks that Vector correctly reports that it is an incorrect type.
   */
  public void testVectorSpoofingClass() {
    try {
      RPC.decodeRequest(generateVectorSpoofingClass());
      fail("Expected IncompatibleRemoteServiceException from testVectorSpoofingClass");
    } catch (IncompatibleRemoteServiceException e) {
      // Expected to get here
      assertEquals(SerializedTypeViolationException.class, e.getCause().getClass());
      assertTrue(e.getCause().getMessage().matches(".*Vector.*AClass.*"));
    }
  }
}
