diff --git a/eclipse/samples/DynaTableRf/.classpath b/eclipse/samples/DynaTableRf/.classpath
index f2c5ce7..3bdab67 100644
--- a/eclipse/samples/DynaTableRf/.classpath
+++ b/eclipse/samples/DynaTableRf/.classpath
@@ -7,5 +7,10 @@
 	<classpathentry kind="var" path="GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA.jar" sourcepath="/GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA-sources.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA-sources.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/redist/json/r2_20080312/json-1.5.jar"/>
+	<classpathentry kind="src" path=".apt_generated">
+		<attributes>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="output" path="war/WEB-INF/classes"/>
 </classpath>
diff --git a/eclipse/samples/DynaTableRf/.factorypath b/eclipse/samples/DynaTableRf/.factorypath
new file mode 100644
index 0000000..3602e92
--- /dev/null
+++ b/eclipse/samples/DynaTableRf/.factorypath
@@ -0,0 +1,3 @@
+<factorypath>
+    <factorypathentry kind="VARJAR" id="GWT_TOOLS/lib/requestfactory/requestfactory-apt.jar" enabled="true" runInBatchMode="false"/>
+</factorypath>
diff --git a/requestfactory/build.xml b/requestfactory/build.xml
index 8b3ed84..28b786e 100755
--- a/requestfactory/build.xml
+++ b/requestfactory/build.xml
@@ -12,13 +12,15 @@
     <delete file="${gwt.build.lib}/requestfactory-server.jar" />
     <delete file="${gwt.build.lib}/requestfactory-server-src.jar" />
     <delete file="${gwt.build.lib}/requestfactory-server+src.jar" />
-    <delete file="${gwt.build.lib}/requestfactory-test+src.jar" />
+    <delete file="${gwt.build.lib}/requestfactory-test.jar" />
+    <delete file="${gwt.build.lib}/requestfactory-test-src.jar" />
+    <delete file="${gwt.build.lib}/requestfactory-test-validated.jar" />
   </target>
 
   <!-- Build a jar file containing a subset of requestfactory -->
   <macrodef name="requestfactory-jar">
     <!--
-         "target" should be one of {client,server,all}[(+|-)src] or test+src.
+         "target" should be one of {client,server,all}[(+|-)src] or test[-src].
          -src includes .java files only, +src includes .java and .class files
     -->
     <attribute name="target" default="client"/>
@@ -45,6 +47,11 @@
     <requestfactory-jar target="apt"/>
   </target>
 
+  <!-- Useful for Android testing -->
+  <target name="requestfactory-all" description="Build RequestFactory all jar">
+    <requestfactory-jar target="all"/>
+  </target>
+
   <target name="requestfactory-client" description="Build RequestFactory client jar">
     <requestfactory-jar target="client"/>
   </target>
@@ -70,8 +77,9 @@
   </target>
 
   <!-- This target requires classes from ../build/{dev,user}/bin-test -->
-  <target name="requestfactory-test+src" description="Build RequestFactory test source/class jar">
-    <requestfactory-jar target="test+src" />
+  <target name="requestfactory-test" description="Build RequestFactory test source/class jar">
+    <requestfactory-jar target="test" />
+    <requestfactory-jar target="test-src" />
   </target>
 
   <!-- Build all client jars -->
@@ -88,7 +96,28 @@
   <!-- Run RequestFactoryJreSuite from the requestfactory-test+src jar.
        Assumes test classes have been built in the trunk directory
   -->
-  <target name="test" depends="requestfactory-test+src" description="Run RequestFactoryJreSuite">
+  <target name="test" depends="requestfactory-test" description="Run RequestFactoryJreSuite">
+    <!-- There's no direct dependency on the Deobfuscator builders, so this gives us an opportunity
+         to test the post-compilation ValidationTool to generate the metadata from the precompiled
+         class files. If a new RequestFactory types is added without the argument list below being
+         updated, a runtime error will occur giving the name of the RequestFactory that needs to
+         be validated.
+    -->
+    <java failonerror="true" fork="true"
+      classname="com.google.web.bindery.requestfactory.apt.ValidationTool" >
+      <classpath>
+        <fileset dir="${gwt.build.lib}" includes="requestfactory-apt.jar" />
+        <fileset dir="${gwt.build.lib}" includes="requestfactory-client.jar" />
+        <fileset dir="${gwt.build.lib}" includes="requestfactory-test.jar" />
+      </classpath>
+      <arg path="${gwt.build.lib}/requestfactory-test-validated.jar" />
+      <arg value="com.google.web.bindery.requestfactory.gwt.client.RequestFactoryPolymorphicTest.Factory" />
+      <arg value="com.google.web.bindery.requestfactory.shared.BoxesAndPrimitivesTest.Factory" />
+      <arg value="com.google.web.bindery.requestfactory.shared.ComplexKeysTest.Factory" />
+      <arg value="com.google.web.bindery.requestfactory.shared.LocatorTest.Factory" />
+      <arg value="com.google.web.bindery.requestfactory.shared.ServiceInheritanceTest$Factory" />
+      <arg value="com.google.web.bindery.requestfactory.shared.SimpleRequestFactory" />
+    </java>
     <java failonerror="true" fork="true"
       classname="com.google.web.bindery.requestfactory.vm.RequestFactoryJreSuite">
       <jvmarg value="-Xss8m" />
@@ -100,9 +129,9 @@
         <fileset dir="${gwt.tools.lib}" includes="hibernate/validator/hibernate-validator-4.1.0.Final.jar" />
         <fileset dir="${gwt.tools.lib}" includes="javax/validation/validation-api-1.0.0.GA.jar" />
         <fileset dir="${gwt.tools.lib}" includes="javax/xml/bind/jaxb-api-2.1.jar" />
-        <fileset dir="${gwt.build.lib}" includes="requestfactory-apt.jar" />
-        <fileset dir="${gwt.build.lib}" includes="requestfactory-test+src.jar" />
-
+        <fileset dir="${gwt.build.lib}" includes="requestfactory-test.jar" />
+        <fileset dir="${gwt.build.lib}" includes="requestfactory-test-src.jar" />
+        <fileset dir="${gwt.build.lib}" includes="requestfactory-test-validated.jar" />
       </classpath>
     </java>
   </target>
diff --git a/samples/dynatablerf/build.xml b/samples/dynatablerf/build.xml
index 25d3a2d..9ffc6b7 100755
--- a/samples/dynatablerf/build.xml
+++ b/samples/dynatablerf/build.xml
@@ -5,6 +5,10 @@
   <import file="../common.ant.xml" />
   <!-- these are after the common.ant.xml so they have gwt.tools etc -->
   <path id="sample.extraclasspath">
+    <!-- Run the RequestFactory annotation processor when compiling the classes.
+         See http://code.google.com/p/google-web-toolkit/wiki/RequestFactoryInterfaceValidation
+    -->
+    <pathelement location="${gwt.build.lib}/requestfactory-apt.jar" />
     <pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA.jar" />
     <pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA-sources.jar" />
   </path>
diff --git a/samples/mobilewebapp/pom.xml b/samples/mobilewebapp/pom.xml
index 773988b..616b5b8 100644
--- a/samples/mobilewebapp/pom.xml
+++ b/samples/mobilewebapp/pom.xml
@@ -65,9 +65,7 @@
          of the GWT compiler.
 
          This dependency has a scope of "provided" so that it only gets used as a
-         compiler dependecy. The Maven GWT Plugin does not seem to honor this scoping,
-         though. For that reason we explicitly remove gwt-dev-*.jar from the produced
-         artifacts later on.
+         compiler dependecy.
     -->
     <dependency>
       <groupId>com.google.gwt</groupId>
@@ -190,8 +188,8 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>gwt-maven-plugin</artifactId>
-	<version>2.2.0</version>
-	<dependencies>
+        <version>2.3.0-1</version>
+        <dependencies>
           <dependency>
             <groupId>com.google.gwt</groupId>
             <artifactId>gwt-user</artifactId>
@@ -207,7 +205,7 @@
             <artifactId>gwt-servlet</artifactId>
             <version>${gwtVersion}</version>
           </dependency>
-	</dependencies>
+        </dependencies>
         <!-- JS is only needed in the package phase, this speeds up testing --> 
         <executions>
           <execution>
@@ -226,7 +224,7 @@
           <hostedWebapp>target/www</hostedWebapp>
           <!-- Ask GWT to create the Story of Your Compile (SOYC) (gwt:compile) -->
           <compileReport>true</compileReport>
-	  <module>com.google.gwt.sample.mobilewebapp.MobileWebApp</module>
+          <module>com.google.gwt.sample.mobilewebapp.MobileWebApp</module>
 
           <appEngineVersion>${gae.version}</appEngineVersion>
           <appEngineHome>${gae.home}</appEngineHome>
@@ -258,7 +256,7 @@
       <!-- Add source folders to test classpath in order to run gwt-tests as normal junit-tests -->
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
-	<version>2.5</version>
+        <version>2.5</version>
         <configuration>
           <additionalClasspathElements>
             <additionalClasspathElement>${project.build.sourceDirectory}</additionalClasspathElement>
@@ -276,7 +274,33 @@
           </systemProperties>
         </configuration>
       </plugin>
-      
+
+      <!-- Run the RequestFactory ValidationTool -->
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <version>1.2</version>
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <configuration>
+              <id>VerifyRequestFactoryInterfaces</id>
+              <executable>java</executable>
+              <arguments>
+                <argument>-cp</argument>
+                <classpath />
+                <argument>com.google.web.bindery.requestfactory.apt.ValidationTool</argument>
+                <argument>${project.build.outputDirectory}</argument>
+                <argument>com.google.gwt.sample.mobilewebapp.shared.MobileWebAppRequestFactory</argument>
+              </arguments>
+            </configuration>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
       <!-- Copy static web files before executing gwt:run -->
       <plugin>
         <artifactId>maven-resources-plugin</artifactId>
@@ -300,9 +324,9 @@
       </plugin>
 
       <plugin>
-	<artifactId>maven-eclipse-plugin</artifactId>
-	<version>2.8</version>
-	<configuration>
+        <artifactId>maven-eclipse-plugin</artifactId>
+        <version>2.8</version>
+        <configuration>
           <downloadSources>true</downloadSources>
           <downloadJavadocs>false</downloadJavadocs>
           <wtpversion>2.0</wtpversion>
@@ -315,45 +339,51 @@
             <projectnature>com.google.gwt.eclipse.core.gwtNature</projectnature>
             <projectnature>com.google.appengine.eclipse.core.gaeNature</projectnature>
           </additionalProjectnatures>
-	</configuration>
-      </plugin>
-
-      <plugin>
-        <!-- Don't deploy gwt-user nor gwt-dev jars to GAE.
-             These jars are needed to compile the
-             project and for DevMode, but not in AppEngine.
-        -->
-        <artifactId>maven-clean-plugin</artifactId>
-        <version>2.3</version>
-        <executions>
-          <execution>
-            <id>default-clean</id>
-            <phase>clean</phase>
-            <goals>
-              <goal>clean</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>remove-gwt-dev-jar</id>
-            <phase>process-classes</phase>
-            <goals>
-              <goal>clean</goal>
-            </goals>
-            <configuration>
-              <excludeDefaultDirectories>true</excludeDefaultDirectories>
-              <filesets>
-                <fileset>
-                  <directory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</directory>
-                  <includes>
-                    <include>gwt-dev*jar</include>
-                    <include>gwt-user*jar</include>
-                  </includes>
-                </fileset>
-              </filesets>
-            </configuration>
-          </execution>
-        </executions>
+        </configuration>
       </plugin>
     </plugins>
+
+    <pluginManagement>
+      <plugins>
+        <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.datanucleus</groupId>
+                    <artifactId>maven-datanucleus-plugin</artifactId>
+                    <versionRange>[1.1.4,)</versionRange>
+                    <goals>
+                      <goal>enhance</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore></ignore>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>net.kindleit</groupId>
+                    <artifactId>maven-gae-plugin</artifactId>
+                    <versionRange>[0.7.3,)</versionRange>
+                    <goals>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <execute />
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
   </build>
 </project>
diff --git a/samples/mobilewebapp/src/main/webapp/WEB-INF/web.xml b/samples/mobilewebapp/src/main/webapp/WEB-INF/web.xml
index a8d039f..7490828 100644
--- a/samples/mobilewebapp/src/main/webapp/WEB-INF/web.xml
+++ b/samples/mobilewebapp/src/main/webapp/WEB-INF/web.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE web-app
-    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
-    "http://java.sun.com/dtd/web-app_2_3.dtd">
-
-<web-app>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
+              http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         version="2.5"
+         xmlns="http://java.sun.com/xml/ns/javaee">
 
   <!--
     Require login. We only require login for the MobileWebApp.html page (instead of *.html) because
@@ -36,10 +36,10 @@
 
   <filter>
     <filter-name>GaeAuthFilter</filter-name>
-    <description>
+    <!--
       This filter demonstrates making GAE authentication
       services visible to a RequestFactory client.
-    </description>
+    -->
     <filter-class>com.google.gwt.sample.gaerequest.server.GaeAuthFilter</filter-class>
   </filter>
   <filter-mapping>
diff --git a/user/build.xml b/user/build.xml
index 63a0eaa..69cfaaa 100755
--- a/user/build.xml
+++ b/user/build.xml
@@ -151,7 +151,9 @@
   <target name="precompile.modules" depends="compile">
     <outofdate>
       <sourcefiles>
-        <fileset dir="${gwt.root}/user/src" />
+        <fileset dir="${gwt.root}/user/src" >
+          <exclude name="com/google/web/bindery/requestfactory/apt/**"/>
+        </fileset>
         <fileset dir="${gwt.root}/user/super" />
         <fileset dir="${gwt.root}/dev/core/src" />
         <fileset dir="${gwt.root}/dev/core/super" />
diff --git a/user/src/com/google/gwt/user/tools/templates/sample/_warFolder_/WEB-INF/web.xmlsrc b/user/src/com/google/gwt/user/tools/templates/sample/_warFolder_/WEB-INF/web.xmlsrc
index fa54208..d35c414 100644
--- a/user/src/com/google/gwt/user/tools/templates/sample/_warFolder_/WEB-INF/web.xmlsrc
+++ b/user/src/com/google/gwt/user/tools/templates/sample/_warFolder_/WEB-INF/web.xmlsrc
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE web-app
-    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
-    "http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
+              http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         version="2.5"
+         xmlns="http://java.sun.com/xml/ns/javaee">
 
-<web-app>
-  
   <!-- Servlets -->
   <servlet>
     <servlet-name>greetServlet</servlet-name>
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/ClientToDomainMapper.java b/user/src/com/google/web/bindery/requestfactory/apt/ClientToDomainMapper.java
new file mode 100644
index 0000000..dd1f28c
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/ClientToDomainMapper.java
@@ -0,0 +1,154 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.NoType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+
+/**
+ * Uses information in a State object to convert client types to their domain
+ * equivalents. This types assumes that any incoming type has already been
+ * determined to be a transportable type.
+ */
+class ClientToDomainMapper extends TypeVisitorBase<TypeMirror> {
+  public static class UnmappedTypeException extends RuntimeException {
+    private final TypeMirror clientType;
+
+    public UnmappedTypeException() {
+      super();
+      clientType = null;
+    }
+
+    public UnmappedTypeException(TypeMirror clientType) {
+      super("No domain type resolved for " + clientType.toString());
+      this.clientType = clientType;
+    }
+
+    public TypeMirror getClientType() {
+      return clientType;
+    }
+  }
+
+  @Override
+  public TypeMirror visitDeclared(DeclaredType x, State state) {
+    if (x.asElement().getKind().equals(ElementKind.ENUM)) {
+      // Enums map to enums
+      return x;
+    }
+    if (state.types.isAssignable(x, state.entityProxyType)
+        || state.types.isAssignable(x, state.valueProxyType)) {
+      // FooProxy -> FooDomain
+      /*
+       * TODO(bobv): This if statement should be widened to baseProxy to support
+       * heterogenous collections of any proxy type. The BaseProxy interface
+       * would also need to be annotated with an @ProxyFor mapping. This can be
+       * done once RFIV is removed, since it only allows homogenous collections.
+       */
+      TypeElement domainType =
+          (TypeElement) state.getClientToDomainMap().get(state.types.asElement(x));
+      if (domainType == null) {
+        return defaultAction(x, state);
+      }
+      return domainType.asType();
+    }
+    if (state.types.isAssignable(x, state.entityProxyIdType)) {
+      // EntityProxyId<FooProxy> -> FooDomain
+      return convertSingleParamType(x, state.entityProxyIdType, 0, state);
+    }
+    if (state.types.isAssignable(x, state.requestType)) {
+      // Request<FooProxy> -> FooDomain
+      return convertSingleParamType(x, state.requestType, 0, state);
+    }
+    if (state.types.isAssignable(x, state.instanceRequestType)) {
+      // InstanceRequest<FooProxy, X> -> FooDomain
+      return convertSingleParamType(x, state.instanceRequestType, 1, state);
+    }
+    for (DeclaredType valueType : getValueTypes(state)) {
+      if (state.types.isAssignable(x, valueType)) {
+        // Value types map straight through
+        return x;
+      }
+    }
+    if (state.types.isAssignable(x, state.findType(List.class))
+        || state.types.isAssignable(x, state.findType(Set.class))) {
+      // Convert Set,List<FooProxy> to Set,List<FooDomain>
+      TypeMirror param = convertSingleParamType(x, state.findType(Collection.class), 0, state);
+      return state.types.getDeclaredType((TypeElement) state.types.asElement(x), param);
+    }
+    return defaultAction(x, state);
+  }
+
+  @Override
+  public TypeMirror visitNoType(NoType x, State state) {
+    if (x.getKind().equals(TypeKind.VOID)) {
+      // Pass void through
+      return x;
+    }
+    // Here, x would be NONE or PACKAGE, neither of which make sense
+    return defaultAction(x, state);
+  }
+
+  @Override
+  public TypeMirror visitPrimitive(PrimitiveType x, State state) {
+    // Primitives pass through
+    return x;
+  }
+
+  @Override
+  public TypeMirror visitTypeVariable(TypeVariable x, State state) {
+    // Convert <T extends FooProxy> to FooDomain
+    return x.getUpperBound().accept(this, state);
+  }
+
+  @Override
+  public TypeMirror visitWildcard(WildcardType x, State state) {
+    // Convert <? extends FooProxy> to FooDomain
+    return state.types.erasure(x).accept(this, state);
+  }
+
+  /**
+   * Utility method to convert a {@code Foo<BarProxy> -> BarDomain}. The
+   * {@code param} parameter specifies the index of the type paramater to
+   * extract.
+   */
+  protected TypeMirror convertSingleParamType(DeclaredType x, DeclaredType convertTo, int param,
+      State state) {
+    DeclaredType converted = (DeclaredType) State.viewAs(convertTo, x, state);
+    if (converted == null) {
+      return state.types.getNoType(TypeKind.NONE);
+    }
+    if (converted.getTypeArguments().isEmpty()) {
+      return defaultAction(x, state);
+    }
+    return converted.getTypeArguments().get(param).accept(this, state);
+  }
+
+  @Override
+  protected TypeMirror defaultAction(TypeMirror x, State state) {
+    throw new UnmappedTypeException(x);
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/DeobfuscatorBuilder.java b/user/src/com/google/web/bindery/requestfactory/apt/DeobfuscatorBuilder.java
new file mode 100644
index 0000000..2b8f2b1
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/DeobfuscatorBuilder.java
@@ -0,0 +1,237 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.vm.impl.Deobfuscator;
+import com.google.web.bindery.requestfactory.vm.impl.OperationData;
+import com.google.web.bindery.requestfactory.vm.impl.OperationKey;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaFileObject;
+
+/**
+ * Visits a RequestFactory to create its associated DeobfuscatorBuilder, a
+ * self-configuring subtype of
+ * {@link com.google.web.bindery.requestfactory.vm.impl.Deobfuscator.Builder}
+ * which provides the ServiceLayer with type- and method-mapping information.
+ */
+class DeobfuscatorBuilder extends ScannerBase<Void> {
+  private TypeElement requestFactoryElement;
+  private final StringBuilder sb = new StringBuilder();
+
+  public String toString() {
+    return sb.toString();
+  }
+
+  /**
+   * Examine a method defined within a RequestFactory.
+   */
+  @Override
+  public Void visitExecutable(ExecutableElement x, State state) {
+    if (shouldIgnore(x, state)) {
+      return null;
+    }
+    final TypeElement requestContextElement =
+        (TypeElement) state.types.asElement(x.getReturnType());
+    new ScannerBase<Void>() {
+
+      /**
+       * Scan a method within a RequestContext.
+       */
+      @Override
+      public Void visitExecutable(ExecutableElement x, State state) {
+        if (shouldIgnore(x, state)) {
+          return null;
+        }
+        String requestContextBinaryName =
+            state.elements.getBinaryName(requestContextElement).toString();
+        String clientMethodDescriptor = x.asType().accept(new DescriptorBuilder(), state);
+        ExecutableElement domainElement = (ExecutableElement) state.getClientToDomainMap().get(x);
+        if (domainElement == null) {
+          /*
+           * No mapping from the client to domain type, probably because of an
+           * unresolved ServiceName annotation. This can be fixed when building
+           * the server by running ValidationTool.
+           */
+          if (state.mustResolveAllAnnotations()) {
+            state.poison(requestContextElement, Messages
+                .deobfuscatorMissingContext(requestContextElement.getSimpleName()));
+          }
+          return super.visitExecutable(x, state);
+        }
+        String domainMethodDescriptor =
+            domainElement.asType().accept(new DescriptorBuilder(), state);
+        String methodName = x.getSimpleName().toString();
+
+        OperationKey key =
+            new OperationKey(requestContextBinaryName, methodName, clientMethodDescriptor);
+        println("withOperation(new OperationKey(\"%s\"),", key.get());
+        println("  new OperationData.Builder()");
+        println("  .withClientMethodDescriptor(\"%s\")", clientMethodDescriptor);
+        println("  .withDomainMethodDescriptor(\"%s\")", domainMethodDescriptor);
+        println("  .withMethodName(\"%s\")", methodName);
+        println("  .withRequestContext(\"%s\")", requestContextBinaryName);
+        println("  .build());");
+        return super.visitExecutable(x, state);
+      }
+
+      /**
+       * Scan a RequestContext.
+       */
+      @Override
+      public Void visitType(TypeElement x, State state) {
+        scanAllInheritedMethods(x, state);
+        return null;
+      }
+    }.scan(requestContextElement, state);
+    return null;
+  }
+
+  /**
+   * Scan a RequestFactory type.
+   */
+  @Override
+  public Void visitType(TypeElement x, State state) {
+    requestFactoryElement = x;
+    String simpleName = computeSimpleName(x, state);
+    String packageName = state.elements.getPackageOf(x).getQualifiedName().toString();
+
+    println("// Automatically Generated -- DO NOT EDIT");
+    println("// %s", state.elements.getBinaryName(x));
+    println("package %s;", packageName);
+    println("import %s;", Arrays.class.getCanonicalName());
+    println("import %s;", OperationData.class.getCanonicalName());
+    println("import %s;", OperationKey.class.getCanonicalName());
+    println("public final class %s extends %s {", simpleName, Deobfuscator.Builder.class
+        .getCanonicalName());
+    println("{");
+    scanAllInheritedMethods(x, state);
+    writeTypeAndTokenMap(state);
+    println("}}");
+
+    // Don't write the deobfuscator if something has gone wrong.
+    if (state.isPoisoned()) {
+      return null;
+    }
+
+    try {
+      JavaFileObject obj = state.filer.createSourceFile(packageName + "." + simpleName, x);
+      Writer w = obj.openWriter();
+      w.write(sb.toString());
+      w.close();
+    } catch (Exception e) {
+      StringWriter sw = new StringWriter();
+      e.printStackTrace(new PrintWriter(sw));
+      state.poison(x, sw.toString());
+    }
+    return null;
+  }
+
+  private String computeSimpleName(TypeElement x, State state) {
+    // See constants in Deobfuscator
+    String simpleName = state.elements.getBinaryName(x).toString() + "DeobfuscatorBuilder";
+    if (state.isClientOnly()) {
+      simpleName += "Lite";
+    }
+    simpleName = simpleName.substring(simpleName.lastIndexOf('.') + 1);
+    return simpleName;
+  }
+
+  private void println(String line, Object... args) {
+    sb.append(String.format(line, args)).append("\n");
+  }
+
+  /**
+   * Write calls to {@code withRawTypeToken} and
+   * {@code withClientToDomainMappings}.
+   */
+  private void writeTypeAndTokenMap(State state) {
+    /*
+     * A map and its comparator to build up the mapping between domain types and
+     * the client type(s) that it is mapped to.
+     */
+    TypeComparator comparator = new TypeComparator(state);
+    Map<TypeElement, SortedSet<TypeElement>> domainToClientMappings =
+        new TreeMap<TypeElement, SortedSet<TypeElement>>(comparator);
+    // Map accumulated by previous visitors
+    Map<Element, Element> clientToDomainMap = state.getClientToDomainMap();
+    // Get all types used by the RequestFactory
+    Set<TypeElement> referredTypes = ReferredTypesCollector.collect(requestFactoryElement, state);
+
+    for (TypeElement clientType : referredTypes) {
+      // Ignare non-proxy types
+      if (!state.types.isAssignable(clientType.asType(), state.baseProxyType)) {
+        continue;
+      }
+      String binaryName = state.elements.getBinaryName(clientType).toString();
+      // withRawTypeToken("1234ABC", "com.example.FooProxy");
+      println("withRawTypeToken(\"%s\", \"%s\");", OperationKey.hash(binaryName), binaryName);
+
+      TypeElement domainType = (TypeElement) clientToDomainMap.get(clientType);
+      if (domainType == null) {
+        /*
+         * Missing proxy mapping, probably due to an unresolved ProxyForName. If
+         * we're running as part of a build tool or an IDE, the
+         * mustResolveAllAnnotations() call below will return false. The
+         * isMappingRequired() check avoid false-positives on proxy supertypes
+         * that extend BaseProxy but that don't declare a ProxyFor annotation.
+         */
+        if (state.mustResolveAllAnnotations() && state.isMappingRequired(domainType)) {
+          state.poison(clientType, Messages.deobfuscatorMissingProxy(clientType.getSimpleName()));
+        }
+        continue;
+      }
+      // Generic get-and-add code
+      SortedSet<TypeElement> clientTypes = domainToClientMappings.get(domainType);
+      if (clientTypes == null) {
+        clientTypes = new TreeSet<TypeElement>(comparator);
+        domainToClientMappings.put(domainType, clientTypes);
+      }
+      clientTypes.add(clientType);
+    }
+
+    for (Map.Entry<TypeElement, SortedSet<TypeElement>> entry : domainToClientMappings.entrySet()) {
+      // Arrays.asList("com.example.FooView1Proxy", "com.example.FooView2Proxy")
+      StringBuilder list = new StringBuilder("Arrays.asList(");
+      boolean needsComma = false;
+      for (TypeElement elt : entry.getValue()) {
+        if (needsComma) {
+          list.append(", ");
+        } else {
+          needsComma = true;
+        }
+        list.append('"').append(state.elements.getBinaryName(elt)).append('"');
+      }
+      list.append(")");
+
+      // withClientToDomainMappings("com.example.Domain", Arrays.asList(...))
+      println("withClientToDomainMappings(\"%s\", %s);", state.elements.getBinaryName(entry
+          .getKey()), list);
+    }
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/DescriptorBuilder.java b/user/src/com/google/web/bindery/requestfactory/apt/DescriptorBuilder.java
new file mode 100644
index 0000000..0b2ac40
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/DescriptorBuilder.java
@@ -0,0 +1,117 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.gwt.core.ext.typeinfo.JniConstants;
+import com.google.gwt.dev.util.Name.BinaryName;
+
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.NoType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.SimpleTypeVisitor6;
+
+/**
+ * Builds descriptors from TypeMirrors for both simple types and methods. Used
+ * by {@link DeobfuscatorBuilder} to construct client-to-server method mappings.
+ */
+class DescriptorBuilder extends SimpleTypeVisitor6<String, State> {
+
+  /**
+   * Arrays aren't actually used anywhere in RequestFactory, but it's trivial to
+   * implement and might be useful later on.
+   */
+  @Override
+  public String visitArray(ArrayType x, State state) {
+    return "[" + x.getComponentType().accept(this, state);
+  }
+
+  @Override
+  public String visitDeclared(DeclaredType x, State state) {
+    return "L"
+        + BinaryName.toInternalName(state.elements.getBinaryName((TypeElement) x.asElement())
+            .toString()) + ";";
+  }
+
+  /**
+   * Only generates the method descriptor, which does not include the method's
+   * name.
+   */
+  @Override
+  public String visitExecutable(ExecutableType x, State state) {
+    StringBuilder sb = new StringBuilder();
+    sb.append("(");
+    for (TypeMirror param : x.getParameterTypes()) {
+      sb.append(param.accept(this, state));
+    }
+    sb.append(")");
+    sb.append(x.getReturnType().accept(this, state));
+    return sb.toString();
+  }
+
+  @Override
+  public String visitNoType(NoType x, State state) {
+    if (x.getKind().equals(TypeKind.VOID)) {
+      return "V";
+    }
+    // The mythical NONE or PACKAGE type
+    return super.visitNoType(x, state);
+  }
+
+  @Override
+  public String visitPrimitive(PrimitiveType x, State state) {
+    switch (x.getKind()) {
+      case BOOLEAN:
+        return String.valueOf(JniConstants.DESC_BOOLEAN);
+      case BYTE:
+        return String.valueOf(JniConstants.DESC_BYTE);
+      case CHAR:
+        return String.valueOf(JniConstants.DESC_CHAR);
+      case DOUBLE:
+        return String.valueOf(JniConstants.DESC_DOUBLE);
+      case FLOAT:
+        return String.valueOf(JniConstants.DESC_FLOAT);
+      case INT:
+        return String.valueOf(JniConstants.DESC_INT);
+      case LONG:
+        return String.valueOf(JniConstants.DESC_LONG);
+      case SHORT:
+        return String.valueOf(JniConstants.DESC_SHORT);
+    }
+    return super.visitPrimitive(x, state);
+  }
+
+  @Override
+  public String visitTypeVariable(TypeVariable x, State state) {
+    return state.types.erasure(x).accept(this, state);
+  }
+
+  @Override
+  public String visitWildcard(WildcardType x, State state) {
+    return state.types.erasure(x).accept(this, state);
+  }
+
+  @Override
+  protected String defaultAction(TypeMirror x, State state) {
+    throw new RuntimeException("Unhandled type: " + x.toString());
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java b/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java
new file mode 100644
index 0000000..5f5839f
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java
@@ -0,0 +1,394 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.apt.ClientToDomainMapper.UnmappedTypeException;
+import com.google.web.bindery.requestfactory.shared.ProxyFor;
+import com.google.web.bindery.requestfactory.shared.ProxyForName;
+import com.google.web.bindery.requestfactory.shared.Service;
+import com.google.web.bindery.requestfactory.shared.ServiceName;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.MirroredTypeException;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+
+/**
+ * Checks client to domain mappings.
+ */
+class DomainChecker extends ScannerBase<Void> {
+
+  /**
+   * Attempt to find the most specific method that conforms to a given
+   * signature.
+   */
+  static class MethodFinder extends ScannerBase<ExecutableElement> {
+    private TypeElement domainType;
+    private ExecutableElement found;
+    private final boolean boxReturnType;
+    private final CharSequence name;
+    private final TypeMirror returnType;
+    private final List<TypeMirror> params;
+
+    public MethodFinder(CharSequence name, TypeMirror returnType, List<TypeMirror> params,
+        boolean boxReturnType, State state) {
+      this.boxReturnType = boxReturnType;
+      this.name = name;
+      this.returnType = TypeSimplifier.simplify(returnType, boxReturnType, state);
+      List<TypeMirror> temp = new ArrayList<TypeMirror>(params.size());
+      for (TypeMirror param : params) {
+        temp.add(TypeSimplifier.simplify(param, false, state));
+      }
+      this.params = Collections.unmodifiableList(temp);
+    }
+
+    @Override
+    public ExecutableElement visitExecutable(ExecutableElement domainMethodElement, State state) {
+      // Quick check for name, paramer count, and return type assignability
+      if (domainMethodElement.getSimpleName().contentEquals(name)
+          && domainMethodElement.getParameters().size() == params.size()) {
+        // Pick up parameterizations in domain type
+        ExecutableType domainMethod = viewIn(domainType, domainMethodElement, state);
+
+        boolean returnTypeMatches;
+        if (returnType == null) {
+          /*
+           * This condition is for methods that we don't really care about the
+           * domain return types (for getId(), getVersion()).
+           */
+          returnTypeMatches = true;
+        } else {
+          TypeMirror domainReturn =
+              TypeSimplifier.simplify(domainMethod.getReturnType(), boxReturnType, state);
+          // The isSameType handles the NONE case.
+          returnTypeMatches = state.types.isSubtype(domainReturn, returnType);
+        }
+        if (returnTypeMatches) {
+          boolean paramsMatch = true;
+          Iterator<TypeMirror> lookFor = params.iterator();
+          Iterator<? extends TypeMirror> domainParam = domainMethod.getParameterTypes().iterator();
+          while (lookFor.hasNext()) {
+            assert domainParam.hasNext();
+            TypeMirror requestedType = lookFor.next();
+            TypeMirror paramType = TypeSimplifier.simplify(domainParam.next(), false, state);
+            if (!state.types.isSubtype(requestedType, paramType)) {
+              paramsMatch = false;
+            }
+          }
+
+          if (paramsMatch) {
+            // Keep most-specific method signature
+            if (found == null
+                || state.types.isSubsignature(domainMethod, (ExecutableType) found.asType())) {
+              found = domainMethodElement;
+            }
+          }
+        }
+      }
+
+      return found;
+    }
+
+    @Override
+    public ExecutableElement visitType(TypeElement domainType, State state) {
+      this.domainType = domainType;
+      return scanAllInheritedMethods(domainType, state);
+    }
+  }
+
+  /**
+   * This is used as the target for errors since generic methods show up as
+   * synthetic elements that don't correspond to any source.
+   */
+  private TypeElement checkedElement;
+  private boolean currentTypeIsProxy;
+  private TypeElement domainElement;
+  private boolean requireInstanceDomainMethods;
+  private boolean requireStaticDomainMethods;
+
+  @Override
+  public Void visitExecutable(ExecutableElement clientMethodElement, State state) {
+    if (shouldIgnore(clientMethodElement, state)) {
+      return null;
+    }
+    // Ignore overrides of stableId() in proxies
+    Name name = clientMethodElement.getSimpleName();
+    if (currentTypeIsProxy && name.contentEquals("stableId")
+        && clientMethodElement.getParameters().isEmpty()) {
+      return null;
+    }
+
+    ExecutableType clientMethod = viewIn(checkedElement, clientMethodElement, state);
+    List<TypeMirror> lookFor = new ArrayList<TypeMirror>();
+    // Convert client method signature to domain types
+    TypeMirror returnType;
+    try {
+      returnType = convertToDomainTypes(clientMethod, lookFor, clientMethodElement, state);
+    } catch (UnmappedTypeException e) {
+      /*
+       * Unusual: this would happen if a RequestContext for which we have a
+       * resolved domain service method uses unresolved proxy types. For
+       * example, the RequestContext uses a @Service annotation, while one or
+       * more proxy types use @ProxyForName("") and specify a domain type not
+       * available to the compiler.
+       */
+      return null;
+    }
+
+    ExecutableElement domainMethod;
+    if (currentTypeIsProxy && isSetter(clientMethodElement, state)) {
+      // Look for void setFoo(...)
+      domainMethod =
+          new MethodFinder(name, state.types.getNoType(TypeKind.VOID), lookFor, false, state).scan(
+              domainElement, state);
+      if (domainMethod == null) {
+        // Try a builder style
+        domainMethod =
+            new MethodFinder(name, domainElement.asType(), lookFor, false, state).scan(
+                domainElement, state);
+      }
+    } else {
+      /*
+       * The usual case for getters and all service methods. Only box return
+       * types when matching context methods since there's a significant
+       * semantic difference between a null Integer and 0.
+       */
+      domainMethod =
+          new MethodFinder(name, returnType, lookFor, !currentTypeIsProxy, state).scan(
+              domainElement, state);
+    }
+
+    if (domainMethod == null) {
+      // Did not find a service method
+      StringBuilder sb = new StringBuilder();
+      sb.append(returnType).append(" ").append(name).append("(");
+      for (TypeMirror param : lookFor) {
+        sb.append(param);
+      }
+      sb.append(")");
+
+      state.poison(clientMethodElement, Messages.domainMissingMethod(sb));
+      return null;
+    }
+    
+     /*
+     * Check the domain method for any requirements for it to be static.
+     * InstanceRequests assume instance methods on the domain type.
+     */
+    boolean isInstanceRequest =
+        state.types.isSubtype(clientMethod.getReturnType(), state.instanceRequestType);
+
+    if ((isInstanceRequest || requireInstanceDomainMethods)
+        && domainMethod.getModifiers().contains(Modifier.STATIC)) {
+      state.poison(checkedElement, Messages.domainMethodWrongModifier(false, domainMethod
+          .getSimpleName()));
+    }
+    if (!isInstanceRequest && requireStaticDomainMethods
+        && !domainMethod.getModifiers().contains(Modifier.STATIC)) {
+      state.poison(checkedElement, Messages.domainMethodWrongModifier(true, domainMethod
+          .getSimpleName()));
+    }
+
+    // Record the mapping
+    state.addMapping(clientMethodElement, domainMethod);
+    return null;
+  }
+
+  @Override
+  public Void visitType(TypeElement clientTypeElement, State state) {
+    TypeMirror clientType = clientTypeElement.asType();
+    checkedElement = clientTypeElement;
+    boolean isEntityProxy = state.types.isSubtype(clientType, state.entityProxyType);
+    currentTypeIsProxy = isEntityProxy || state.types.isSubtype(clientType, state.valueProxyType);
+    domainElement = (TypeElement) state.getClientToDomainMap().get(clientTypeElement);
+    if (domainElement == null) {
+      // A proxy with an unresolved domain type (e.g. ProxyForName(""))
+      return null;
+    }
+
+    requireInstanceDomainMethods = false;
+    requireStaticDomainMethods = false;
+
+    if (currentTypeIsProxy) {
+      // Require domain property methods to be instance methods
+      requireInstanceDomainMethods = true;
+      if (!hasProxyLocator(clientTypeElement, state)) {
+        // Domain types without a Locator should have a no-arg constructor
+        if (!hasNoArgConstructor(domainElement)) {
+          state.warn(clientTypeElement, Messages.domainNoDefaultConstructor(domainElement
+              .getSimpleName(), clientTypeElement.getSimpleName(), state.requestContextType
+              .asElement().getSimpleName()));
+        }
+
+        /*
+         * Check for getId(), getVersion(), and findFoo() for any type that
+         * extends EntityProxy, but not on EntityProxy itself, since EntityProxy
+         * is mapped to java.lang.Object.
+         */
+        if (isEntityProxy && !state.types.isSameType(clientType, state.entityProxyType)) {
+          checkDomainEntityMethods(state);
+        }
+      }
+    } else if (!hasServiceLocator(clientTypeElement, state)) {
+      /*
+       * Otherwise, we're looking at a RequestContext. If it doesn't have a
+       * ServiceLocator, all methods must be static.
+       */
+      requireStaticDomainMethods = true;
+    }
+
+    scanAllInheritedMethods(clientTypeElement, state);
+    return null;
+  }
+
+  /**
+   * Check that {@code getId()} and {@code getVersion()} exist and that they are
+   * non-static. Check that {@code findFoo()} exists, is static, returns an
+   * appropriate type, and its parameter is assignable from the return value
+   * from {@code getId()}.
+   */
+  private void checkDomainEntityMethods(State state) {
+    ExecutableElement getId =
+        new MethodFinder("getId", null, Collections.<TypeMirror> emptyList(), false, state).scan(
+            domainElement, state);
+    if (getId == null) {
+      state.poison(checkedElement, Messages.domainNoGetId(domainElement.asType()));
+    } else {
+      if (getId.getModifiers().contains(Modifier.STATIC)) {
+        state.poison(checkedElement, Messages.domainGetIdStatic());
+      }
+
+      // Can only check findFoo() if we have a getId
+      ExecutableElement find =
+          new MethodFinder("find" + domainElement.getSimpleName(), domainElement.asType(),
+              Collections.singletonList(getId.getReturnType()), false, state).scan(domainElement,
+              state);
+      if (find == null) {
+        state.warn(checkedElement, Messages.domainMissingFind(domainElement.asType(), domainElement
+            .getSimpleName(), getId.getReturnType(), checkedElement.getSimpleName()));
+      } else if (!find.getModifiers().contains(Modifier.STATIC)) {
+        state.poison(checkedElement, Messages.domainFindNotStatic(domainElement.getSimpleName()));
+      }
+    }
+
+    ExecutableElement getVersion =
+        new MethodFinder("getVersion", null, Collections.<TypeMirror> emptyList(), false, state)
+            .scan(domainElement, state);
+    if (getVersion == null) {
+      state.poison(checkedElement, Messages.domainNoGetVersion(domainElement.asType()));
+    } else if (getVersion.getModifiers().contains(Modifier.STATIC)) {
+      state.poison(checkedElement, Messages.domainGetVersionStatic());
+    }
+  }
+
+  /**
+   * Converts a client method's types to their domain counterparts.
+   * 
+   * @param clientMethod the RequestContext method to validate
+   * @param parameterAccumulator an out parameter that will be populated with
+   *          the converted paramater types
+   * @param warnTo The element to which warnings should be posted if one or more
+   *          client types cannot be converted to domain types for validation
+   * @param state the State object
+   * @throws UnmappedTypeException if one or more types used in
+   *           {@code clientMethod} cannot be resolved to domain types
+   */
+  private TypeMirror convertToDomainTypes(ExecutableType clientMethod,
+      List<TypeMirror> parameterAccumulator, ExecutableElement warnTo, State state)
+      throws UnmappedTypeException {
+    boolean error = false;
+    TypeMirror returnType;
+    try {
+      returnType = clientMethod.getReturnType().accept(new ClientToDomainMapper(), state);
+    } catch (UnmappedTypeException e) {
+      error = true;
+      returnType = null;
+      state.warn(warnTo, Messages.methodNoDomainPeer(e.getClientType(), false));
+    }
+    for (TypeMirror param : clientMethod.getParameterTypes()) {
+      try {
+        parameterAccumulator.add(param.accept(new ClientToDomainMapper(), state));
+      } catch (UnmappedTypeException e) {
+        parameterAccumulator.add(null);
+        error = true;
+        state.warn(warnTo, Messages.methodNoDomainPeer(e.getClientType(), true));
+      }
+    }
+    if (error) {
+      throw new UnmappedTypeException();
+    }
+    return returnType;
+  }
+
+  /**
+   * Looks for a no-arg constructor or no constructors at all. Instance
+   * initializers are ignored.
+   */
+  private boolean hasNoArgConstructor(TypeElement x) {
+    List<ExecutableElement> constructors = ElementFilter.constructorsIn(x.getEnclosedElements());
+    if (constructors.isEmpty()) {
+      return true;
+    }
+    for (ExecutableElement constructor : constructors) {
+      if (constructor.getParameters().isEmpty()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private boolean hasProxyLocator(TypeElement x, State state) {
+    ProxyFor proxyFor = x.getAnnotation(ProxyFor.class);
+    if (proxyFor != null) {
+      // See javadoc on getAnnotation
+      try {
+        proxyFor.locator();
+        throw new RuntimeException("Should not reach here");
+      } catch (MirroredTypeException expected) {
+        TypeMirror locatorType = expected.getTypeMirror();
+        return !state.types.asElement(locatorType).equals(state.locatorType.asElement());
+      }
+    }
+    ProxyForName proxyForName = x.getAnnotation(ProxyForName.class);
+    return proxyForName != null && !proxyForName.locator().isEmpty();
+  }
+
+  private boolean hasServiceLocator(TypeElement x, State state) {
+    Service service = x.getAnnotation(Service.class);
+    if (service != null) {
+      // See javadoc on getAnnotation
+      try {
+        service.locator();
+        throw new RuntimeException("Should not reach here");
+      } catch (MirroredTypeException expected) {
+        TypeMirror locatorType = expected.getTypeMirror();
+        return !state.types.asElement(locatorType).equals(state.serviceLocatorType.asElement());
+      }
+    }
+    ServiceName serviceName = x.getAnnotation(ServiceName.class);
+    return serviceName != null && !serviceName.locator().isEmpty();
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/ExtraTypesScanner.java b/user/src/com/google/web/bindery/requestfactory/apt/ExtraTypesScanner.java
new file mode 100644
index 0000000..a1d09f8
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/ExtraTypesScanner.java
@@ -0,0 +1,71 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.util.List;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * Looks for {@code ExtraTypes} annotations and calls
+ * {@link #scanExtraType(TypeElement)}.
+ */
+abstract class ExtraTypesScanner<T> extends ScannerBase<T> {
+  /**
+   * Check an element for a declaration.
+   */
+  protected void checkForAnnotation(Element x, State state) {
+    // Bug similar to Eclipse 261969 makes ExtraTypes.value() unreliable.
+    for (AnnotationMirror mirror : x.getAnnotationMirrors()) {
+      if (!state.types.isSameType(mirror.getAnnotationType(), state.extraTypesAnnotation)) {
+        continue;
+      }
+      // The return of the Class[] value() method
+      AnnotationValue value = mirror.getElementValues().values().iterator().next();
+      // which is represented by a list
+      @SuppressWarnings("unchecked")
+      List<? extends AnnotationValue> valueList =
+          (List<? extends AnnotationValue>) value.getValue();
+      for (AnnotationValue clazz : valueList) {
+        TypeMirror type = (TypeMirror) clazz.getValue();
+        scanExtraType((TypeElement) state.types.asElement(type));
+      }
+    }
+  }
+
+  /**
+   * Check a type and all of its supertypes for the annotation.
+   */
+  protected void checkForAnnotation(TypeElement x, State state) {
+    // Check type's declaration
+    checkForAnnotation((Element) x, state);
+    // Look at superclass, if it exists
+    if (!x.getSuperclass().getKind().equals(TypeKind.NONE)) {
+      checkForAnnotation((TypeElement) state.types.asElement(x.getSuperclass()), state);
+    }
+    // Check super-interfaces
+    for (TypeMirror intf : x.getInterfaces()) {
+      checkForAnnotation((TypeElement) state.types.asElement(intf), state);
+    }
+  }
+
+  protected abstract void scanExtraType(TypeElement extraType);
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/Finder.java b/user/src/com/google/web/bindery/requestfactory/apt/Finder.java
new file mode 100644
index 0000000..0d5d79a
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/Finder.java
@@ -0,0 +1,44 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.TypeElement;
+
+/**
+ * Looks for all types assignable to {@code RequestFactory} and adds them to the
+ * output state. This is necessary to support factory types declared as inner
+ * classes.
+ */
+class Finder extends ScannerBase<Void> {
+  @Override
+  public Void visitType(TypeElement x, State state) {
+    // Ignore anything other than interfaces
+    if (x.getKind().equals(ElementKind.INTERFACE)) {
+      if (state.types.isAssignable(x.asType(), state.requestFactoryType)) {
+        state.maybeScanFactory(x);
+      }
+      if (state.types.isAssignable(x.asType(), state.requestContextType)) {
+        state.maybeScanContext(x);
+      }
+      if (state.types.isAssignable(x.asType(), state.entityProxyType)
+          || state.types.isAssignable(x.asType(), state.valueProxyType)) {
+        state.maybeScanProxy(x);
+      }
+    }
+    return super.visitType(x, state);
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/HaltException.java b/user/src/com/google/web/bindery/requestfactory/apt/HaltException.java
new file mode 100644
index 0000000..98b0f46
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/HaltException.java
@@ -0,0 +1,22 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+/**
+ * An un-logged RuntimeException used to abort processing.
+ */
+class HaltException extends RuntimeException {
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/Messages.java b/user/src/com/google/web/bindery/requestfactory/apt/Messages.java
new file mode 100644
index 0000000..1379596
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/Messages.java
@@ -0,0 +1,163 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.JsonRpcProxy;
+import com.google.web.bindery.requestfactory.shared.JsonRpcService;
+import com.google.web.bindery.requestfactory.shared.ProxyFor;
+import com.google.web.bindery.requestfactory.shared.ProxyForName;
+import com.google.web.bindery.requestfactory.shared.Service;
+import com.google.web.bindery.requestfactory.shared.ServiceName;
+
+/**
+ * Contains string-formatting methods to produce error messages. This class
+ * exists to avoid the need to duplicate error messages in test code. All method
+ * parameters in this class accept {@code Object} so that the production code
+ * can pass {@code javax.lang.model} types and the test code can pass Strings.
+ */
+class Messages {
+  /*
+   * Note to maintainers: When new messages are added to this class, the
+   * RfValidatorTest.testErrorsAndWarnings() method should be updated to test
+   * the new message.
+   */
+
+  public static String contextMissingDomainType(Object domainTypeName) {
+    return String.format("Cannot fully validate context since domain type %s is not available.\n"
+        + "You must run the ValidationTool as part of your server build process.", domainTypeName);
+  }
+
+  public static String contextMustBeAnnotated(Object requestContextName) {
+    return String.format("The type %s must be annotated with %s, %s, or %s", requestContextName,
+        Service.class.getSimpleName(), ServiceName.class.getSimpleName(), JsonRpcService.class
+            .getSimpleName());
+  }
+
+  public static String contextRequiredReturnTypes(Object requestName, Object instanceRequestName) {
+    return String.format("The return type must be a %s or %s", requestName, instanceRequestName);
+  }
+
+  public static String deobfuscatorMissingContext(Object contextName) {
+    return String.format("Could not load domain mapping for context %s.\n"
+        + "Check that both the shared interfaces and server domain types are on the classpath.",
+        contextName);
+  }
+
+  public static String deobfuscatorMissingProxy(Object proxyName) {
+    return String.format("Could not load domain mapping for proxy %s.\n"
+        + "Check that both the shared interfaces and server domain types are on the classpath.",
+        proxyName);
+  }
+
+  public static String domainFindNotStatic(Object domainTypeName) {
+    return String.format("The domain object's find%s() method is not static", domainTypeName);
+  }
+
+  public static String domainGetIdStatic() {
+    return "The domain type's getId() method must not be static";
+  }
+
+  public static String domainGetVersionStatic() {
+    return "The domain type's getVersion() method must not be static";
+  }
+
+  public static String domainMethodWrongModifier(boolean expectStatic, Object domainMethodName) {
+    return String.format("Found %s domain method %s when %s method required", expectStatic
+        ? "instance" : "static", domainMethodName, expectStatic ? "static" : "instance");
+  }
+
+  public static String domainMissingFind(Object domainType, Object simpleName,
+      Object getIdReturnType, Object checkedTypeName) {
+    return String.format("The domain type %s has no %s find%s(%s) method. "
+        + "Attempting to send a %s to the server will result in a server error.", domainType,
+        simpleName, simpleName, getIdReturnType, checkedTypeName);
+  }
+
+  public static String domainMissingMethod(Object description) {
+    return String.format("Could not find domain method similar to %s", description);
+  }
+
+  public static String domainNoDefaultConstructor(Object domainName, Object proxyName,
+      Object requestContextName) {
+    return String.format("The domain type %s has no default constructor."
+        + " Calling %s.create(%s.class) will cause a server error.", domainName,
+        requestContextName, proxyName);
+  }
+
+  public static String domainNoGetId(Object domainType) {
+    return String.format("Domain type %s does not have a getId() method", domainType);
+  }
+
+  public static String domainNoGetVersion(Object domainType) {
+    return String.format("Domain type %s does not have a getVersion() method", domainType);
+  }
+
+  public static String factoryMustBeAssignable(Object assignableTo) {
+    return String.format("The return type of this method must return a %s", assignableTo);
+  }
+
+  public static String factoryMustReturnInterface(Object returnType) {
+    return String.format("The return type %s must be an interface", returnType);
+  }
+
+  public static String factoryNoMethodParameters() {
+    return "This method must have no parameters";
+  }
+
+  public static String methodNoDomainPeer(Object proxyTypeName, boolean isParameter) {
+    return String.format("Cannot validate this method because the domain mapping for "
+        + " %s type (%s) could not be resolved to a domain type", isParameter ? "a parameter of"
+        : "the return", proxyTypeName);
+  }
+
+  public static String noSuchType(String binaryTypeName) {
+    return String.format("Could not find root type %s", binaryTypeName);
+  }
+
+  public static String proxyMissingDomainType(Object missingDomainName) {
+    return String.format("Cannot fully validate proxy since type %s is not available",
+        missingDomainName);
+  }
+
+  public static String proxyMustBeAnnotated(Object typeName) {
+    return String.format("The proxy type %s must be annotated with %s, %s, or %s", typeName,
+        ProxyFor.class.getSimpleName(), ProxyForName.class.getSimpleName(), JsonRpcProxy.class
+            .getSimpleName());
+  }
+
+  public static String proxyOnlyGettersSetters() {
+    return "Only getters and setters allowed";
+  }
+
+  public static String rawType() {
+    return "A raw type may not be used here";
+  }
+
+  public static String redundantAnnotation(Object annotationName) {
+    return String.format("Redundant annotation: %s", annotationName);
+  }
+
+  public static String untransportableType(Object returnType) {
+    return String.format("The type %s cannot be used here", returnType);
+  }
+
+  public static String warnSuffix() {
+    return "\n\nAdd @SuppressWarnings(\"requestfactory\") to dismiss.";
+  }
+
+  private Messages() {
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java b/user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java
new file mode 100644
index 0000000..2b72edf
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java
@@ -0,0 +1,101 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.gwt.dev.util.Name.BinaryName;
+import com.google.web.bindery.requestfactory.shared.JsonRpcProxy;
+import com.google.web.bindery.requestfactory.shared.ProxyFor;
+import com.google.web.bindery.requestfactory.shared.ProxyForName;
+
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.MirroredTypeException;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * Examines the methods declared in a proxy interface. Also records the client
+ * to domain mapping for the proxy type.
+ */
+class ProxyScanner extends ScannerBase<Void> {
+
+  @Override
+  public Void visitExecutable(ExecutableElement x, State state) {
+    if (shouldIgnore(x, state)) {
+      return null;
+    }
+
+    if (isGetter(x, state)) {
+      TypeMirror returnType = x.getReturnType();
+      if (!state.isTransportableType(returnType)) {
+        state.poison(x, Messages.untransportableType(returnType));
+      }
+    } else if (!isSetter(x, state)) {
+      state.poison(x, Messages.proxyOnlyGettersSetters());
+    }
+    // Parameters checked by visitVariable
+    return super.visitExecutable(x, state);
+  }
+
+  @Override
+  public Void visitType(TypeElement x, State state) {
+    ProxyFor proxyFor = x.getAnnotation(ProxyFor.class);
+    ProxyForName proxyForName = x.getAnnotation(ProxyForName.class);
+    JsonRpcProxy jsonRpcProxy = x.getAnnotation(JsonRpcProxy.class);
+    if (proxyFor != null) {
+      poisonIfAnnotationPresent(state, x, proxyForName, jsonRpcProxy);
+
+      // See javadoc on Element.getAnnotation() for why it works this way
+      try {
+        proxyFor.value();
+        throw new RuntimeException("Should not reach here");
+      } catch (MirroredTypeException expected) {
+        TypeMirror type = expected.getTypeMirror();
+        state.addMapping(x, (TypeElement) state.types.asElement(type));
+      }
+    }
+    if (proxyForName != null) {
+      poisonIfAnnotationPresent(state, x, jsonRpcProxy);
+      TypeElement domain =
+          state.elements.getTypeElement(BinaryName.toSourceName(proxyForName.value()));
+      if (domain == null) {
+        state.warn(x, Messages.proxyMissingDomainType(proxyForName.value()));
+      }
+      state.addMapping(x, domain);
+    }
+
+    scanAllInheritedMethods(x, state);
+    state.checkExtraTypes(x);
+    return null;
+  }
+
+  @Override
+  public Void visitVariable(VariableElement x, State state) {
+    if (!state.isTransportableType(x.asType())) {
+      state.poison(x, Messages.untransportableType(x.asType()));
+    }
+    return super.visitVariable(x, state);
+  }
+
+  @Override
+  protected boolean shouldIgnore(ExecutableElement x, State state) {
+    // Ignore overrides of stableId()
+    if (x.getSimpleName().contentEquals("stableId") && x.getParameters().isEmpty()) {
+      return true;
+    }
+    return super.shouldIgnore(x, state);
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/ReferredTypesCollector.java b/user/src/com/google/web/bindery/requestfactory/apt/ReferredTypesCollector.java
new file mode 100644
index 0000000..a8eb5e1
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/ReferredTypesCollector.java
@@ -0,0 +1,145 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.Stack;
+import java.util.TreeSet;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+
+/**
+ * Given a RequestFactory interface, return all RequestContext and proxy types
+ * transitively referenced.
+ */
+class ReferredTypesCollector extends ExtraTypesScanner<Void> {
+
+  /**
+   * Finds TypeElements that we care about from TypeMirror API. This is used to
+   * handle generic type signatures and supertypes.
+   */
+  private class ElementFinder extends TypeVisitorBase<Void> {
+    @Override
+    public Void visitDeclared(DeclaredType x, State state) {
+      // Some generic types don't have elements
+      Element elt = state.types.asElement(x);
+      if (elt != null) {
+        ReferredTypesCollector.this.scan(elt, state);
+      }
+      // Capture List<FooProxy>
+      for (TypeMirror a : x.getTypeArguments()) {
+        a.accept(this, state);
+      }
+      return null;
+    }
+
+    @Override
+    public Void visitExecutable(ExecutableType x, State state) {
+      x.getReturnType().accept(this, state);
+      for (TypeMirror p : x.getParameterTypes()) {
+        p.accept(this, state);
+      }
+      for (TypeMirror t : x.getTypeVariables()) {
+        t.accept(this, state);
+      }
+      return null;
+    }
+
+    @Override
+    public Void visitTypeVariable(TypeVariable x, State state) {
+      return state.types.erasure(x).accept(this, state);
+    }
+
+    @Override
+    public Void visitWildcard(WildcardType x, State state) {
+      return state.types.erasure(x).accept(this, state);
+    }
+  }
+
+  /**
+   * Collect all RequestContext and proxy types reachable from the given
+   * RequestFactory.
+   */
+  public static Set<TypeElement> collect(TypeElement requestFactory, State state) {
+    ReferredTypesCollector c = new ReferredTypesCollector(state);
+    c.scan(requestFactory, state);
+    return c.seen;
+  }
+
+  private final Stack<TypeElement> currentType = new Stack<TypeElement>();
+  private final SortedSet<TypeElement> seen;
+  private final State state;
+
+  private ReferredTypesCollector(State state) {
+    seen = new TreeSet<TypeElement>(new TypeComparator(state));
+    this.state = state;
+  }
+
+  @Override
+  public Void visitExecutable(ExecutableElement x, State state) {
+    if (shouldIgnore(x, state)) {
+      return null;
+    }
+    ExecutableType xType = viewIn(currentType.peek(), x, state);
+    xType.accept(new ElementFinder(), state);
+    checkForAnnotation(x, state);
+    return null;
+  }
+
+  @Override
+  public Void visitType(TypeElement x, State state) {
+    // Only look at proxies and contexts
+    boolean isContext = state.types.isAssignable(x.asType(), state.requestContextType);
+    boolean isFactory = state.types.isAssignable(x.asType(), state.requestFactoryType);
+    boolean isProxy = state.types.isAssignable(x.asType(), state.baseProxyType);
+    if (isProxy || isFactory || isContext) {
+      currentType.push(x);
+      try {
+        // Ignore previously-seen types and factories
+        if ((isContext || isProxy) && !seen.add(x)) {
+          return null;
+        }
+        // Visit a proxy's supertypes
+        if (isProxy) {
+          x.getSuperclass().accept(new ElementFinder(), state);
+          for (TypeMirror intf : x.getInterfaces()) {
+            intf.accept(new ElementFinder(), state);
+          }
+        }
+        // Visit methods
+        scanAllInheritedMethods(x, state);
+        // Scan for extra types
+        checkForAnnotation(x, state);
+      } finally {
+        currentType.pop();
+      }
+    }
+    return null;
+  }
+
+  @Override
+  protected void scanExtraType(TypeElement extraType) {
+    scan(extraType, state);
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/RequestContextScanner.java b/user/src/com/google/web/bindery/requestfactory/apt/RequestContextScanner.java
new file mode 100644
index 0000000..8a07085
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/RequestContextScanner.java
@@ -0,0 +1,126 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.gwt.dev.util.Name.BinaryName;
+import com.google.web.bindery.requestfactory.shared.JsonRpcService;
+import com.google.web.bindery.requestfactory.shared.Service;
+import com.google.web.bindery.requestfactory.shared.ServiceName;
+
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.MirroredTypeException;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * Scans a RequestContext declaration. This visitor will call out to the State
+ * object to validate the types that it encounters.
+ */
+class RequestContextScanner extends ScannerBase<Void> {
+
+  @Override
+  public Void visitExecutable(ExecutableElement x, State state) {
+    if (shouldIgnore(x, state)) {
+      return null;
+    }
+    TypeMirror returnType = x.getReturnType();
+    if (state.types.isAssignable(returnType, state.requestType)) {
+      // Extract Request<Foo> type
+      DeclaredType asRequest = (DeclaredType) State.viewAs(state.requestType, returnType, state);
+      if (asRequest.getTypeArguments().isEmpty()) {
+        state.poison(x, Messages.rawType());
+      } else {
+        TypeMirror requestReturn = asRequest.getTypeArguments().get(0);
+        if (!state.isTransportableType(requestReturn)) {
+          state.poison(x, Messages.untransportableType(requestReturn));
+        }
+      }
+    } else if (state.types.isAssignable(returnType, state.instanceRequestType)) {
+      // Extract InstanceRequest<FooProxy, String>
+      DeclaredType asInstanceRequest =
+          (DeclaredType) State.viewAs(state.instanceRequestType, returnType, state);
+      if (asInstanceRequest.getTypeArguments().isEmpty()) {
+        state.poison(x, Messages.rawType());
+      } else {
+        TypeMirror instanceType = asInstanceRequest.getTypeArguments().get(0);
+        state.maybeScanProxy((TypeElement) state.types.asElement(instanceType));
+        TypeMirror requestReturn = asInstanceRequest.getTypeArguments().get(1);
+        if (!state.isTransportableType(requestReturn)) {
+          state.poison(x, Messages.untransportableType(requestReturn));
+        }
+      }
+    } else if (isSetter(x, state)) {
+      // Parameter checked in visitVariable
+    } else {
+      state.poison(x, Messages.contextRequiredReturnTypes(state.requestType.asElement()
+          .getSimpleName(), state.instanceRequestType.asElement().getSimpleName()));
+    }
+    return super.visitExecutable(x, state);
+  }
+
+  @Override
+  public Void visitType(TypeElement x, State state) {
+    Service service = x.getAnnotation(Service.class);
+    ServiceName serviceName = x.getAnnotation(ServiceName.class);
+    JsonRpcService jsonRpcService = x.getAnnotation(JsonRpcService.class);
+    if (service != null) {
+      poisonIfAnnotationPresent(state, x, serviceName, jsonRpcService);
+
+      // See javadoc on Element.getAnnotation() for why it works this way
+      try {
+        service.value();
+        throw new RuntimeException("Should not reach here");
+      } catch (MirroredTypeException expected) {
+        TypeMirror type = expected.getTypeMirror();
+        state.addMapping(x, (TypeElement) state.types.asElement(type));
+      }
+    }
+    if (serviceName != null) {
+      poisonIfAnnotationPresent(state, x, jsonRpcService);
+      TypeElement domain =
+          state.elements.getTypeElement(BinaryName.toSourceName(serviceName.value()));
+      if (domain == null) {
+        state.warn(x, Messages.contextMissingDomainType(serviceName.value()));
+      }
+      state.addMapping(x, domain);
+    }
+
+    scanAllInheritedMethods(x, state);
+    state.checkExtraTypes(x);
+    return null;
+  }
+
+  @Override
+  public Void visitTypeParameter(TypeParameterElement x, State state) {
+    for (TypeMirror bound : x.getBounds()) {
+      if (!state.isTransportableType(bound)) {
+        state.poison(x, Messages.untransportableType(bound));
+      }
+    }
+    return super.visitTypeParameter(x, state);
+  }
+
+  @Override
+  public Void visitVariable(VariableElement x, State state) {
+    if (!state.isTransportableType(x.asType())) {
+      state.poison(x, Messages.untransportableType(x.asType()));
+    }
+    return super.visitVariable(x, state);
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/RequestFactoryScanner.java b/user/src/com/google/web/bindery/requestfactory/apt/RequestFactoryScanner.java
new file mode 100644
index 0000000..3f881f7
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/RequestFactoryScanner.java
@@ -0,0 +1,67 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * Scans a RequestFactory declaration for errors. This visitor will call out to
+ * the State object to validate the types that it encounters.
+ */
+class RequestFactoryScanner extends ScannerBase<Void> {
+  @Override
+  public Void visitExecutable(ExecutableElement x, State state) {
+    if (shouldIgnore(x, state)) {
+      // Ignore initializers and methods from Object and RequestFactory
+      return null;
+    }
+    if (!x.getParameters().isEmpty()) {
+      state.poison(x, Messages.factoryNoMethodParameters());
+    }
+    TypeMirror returnType = x.getReturnType();
+    if (state.types.isAssignable(returnType, state.requestContextType)) {
+      Element returnTypeElement = state.types.asElement(returnType);
+      if (!returnTypeElement.getKind().equals(ElementKind.INTERFACE)) {
+        state.poison(x, Messages.factoryMustReturnInterface(returnTypeElement.getSimpleName()));
+      } else {
+        TypeElement contextElement = (TypeElement) returnTypeElement;
+        state.maybeScanContext(contextElement);
+        state.requireMapping(contextElement);
+      }
+    } else {
+      state.poison(x, Messages.factoryMustBeAssignable(state.requestContextType.asElement()
+          .getSimpleName()));
+    }
+    return null;
+  }
+
+  @Override
+  public Void visitType(TypeElement x, State state) {
+    // Ignore RequestFactory itself
+    if (state.types.isSameType(state.requestFactoryType, x.asType())) {
+      return null;
+    }
+
+    scanAllInheritedMethods(x, state);
+    state.checkExtraTypes(x);
+    return null;
+  }
+
+}
\ No newline at end of file
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/RfApt.java b/user/src/com/google/web/bindery/requestfactory/apt/RfApt.java
deleted file mode 100644
index 2afd346..0000000
--- a/user/src/com/google/web/bindery/requestfactory/apt/RfApt.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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.web.bindery.requestfactory.apt;
-
-import static com.google.web.bindery.requestfactory.vm.impl.TypeTokenResolver.TOKEN_MANIFEST;
-
-import com.google.web.bindery.requestfactory.shared.BaseProxy;
-import com.google.web.bindery.requestfactory.vm.impl.OperationKey;
-import com.google.web.bindery.requestfactory.vm.impl.TypeTokenResolver;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.FilerException;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.annotation.processing.RoundEnvironment;
-import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.annotation.processing.SupportedOptions;
-import javax.annotation.processing.SupportedSourceVersion;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementFilter;
-import javax.lang.model.util.ElementScanner6;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
-import javax.tools.Diagnostic.Kind;
-import javax.tools.FileObject;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardLocation;
-
-/**
- * An annotation processor that creates an obfuscated type manifest that is used
- * by {@link com.google.web.bindery.requestfactory.vm.RequestFactorySource} and
- * related implementation classes.
- */
-@SupportedAnnotationTypes("com.google.web.bindery.requestfactory.*")
-@SupportedSourceVersion(SourceVersion.RELEASE_6)
-@SupportedOptions("verbose")
-public class RfApt extends AbstractProcessor {
-
-  /**
-   * Looks for all types assignable to {@link BaseProxy} and adds them to the
-   * output state.
-   */
-  private class Finder extends ElementScanner6<Void, Void> {
-    // Only valid for a single round
-    TypeMirror baseProxyType = elements.getTypeElement(BaseProxy.class.getCanonicalName()).asType();
-
-    @Override
-    public Void visitType(TypeElement elt, Void arg1) {
-      String binaryName = elements.getBinaryName(elt).toString();
-      if (types.isSubtype(elt.asType(), baseProxyType)) {
-        String hash = OperationKey.hash(binaryName);
-        builder.addTypeToken(hash, binaryName);
-        log(elt, "Processed proxy %s %s", binaryName, hash);
-      }
-      return super.visitType(elt, arg1);
-    }
-  }
-
-  private TypeTokenResolver.Builder builder;
-  private Elements elements;
-  private Filer filer;
-  private boolean verbose;
-  private Types types;
-
-  @Override
-  public synchronized void init(ProcessingEnvironment processingEnv) {
-    super.init(processingEnv);
-    log("RfApt init");
-    elements = processingEnv.getElementUtils();
-    filer = processingEnv.getFiler();
-    types = processingEnv.getTypeUtils();
-    verbose = Boolean.parseBoolean(processingEnv.getOptions().get("verbose"));
-  }
-
-  @Override
-  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
-    log("RequestFactory processing a round");
-
-    if (builder == null) {
-      builder = new TypeTokenResolver.Builder();
-      // Try not to obliterate existing data
-      try {
-        FileObject resource = filer.getResource(StandardLocation.CLASS_OUTPUT, "", TOKEN_MANIFEST);
-        builder.load(resource.openInputStream());
-        log("Reusing old data");
-      } catch (IOException e) {
-        // Likely because the file does not exist
-        log("Not reusing existing manifest file: " + e.getMessage());
-      }
-    }
-
-    // Extract data
-    new Finder().scan(ElementFilter.typesIn(roundEnv.getRootElements()), null);
-
-    // On the last round, write out accumulated data
-    if (roundEnv.processingOver()) {
-      TypeTokenResolver d = builder.build();
-      builder = null;
-      try {
-        FileObject res = filer.createResource(StandardLocation.CLASS_OUTPUT, "", TOKEN_MANIFEST);
-        d.store(res.openOutputStream());
-      } catch (IOException e) {
-        error("Could not write output: " + e.getMessage());
-      }
-
-      /*
-       * Getting the TOKEN_MANIFEST resource into an Android APK generated by
-       * the Android Eclipse plugin is non-trivial. (Users of ant and apkbuilder
-       * can just use -rf to include the relevant file). To support the common
-       * use-case, we'll generate a subclass of TypeTokenResolver.Builder that
-       * has all of the data already baked into it. This synthetic subtype is
-       * looked for first by TypeTokenResolver and any manifests that are on the
-       * classpath will be added on top.
-       */
-      try {
-        String packageName = TypeTokenResolver.class.getPackage().getName();
-        String simpleName = TypeTokenResolver.class.getSimpleName() + "BuilderImpl";
-        JavaFileObject classfile = filer.createSourceFile(packageName + "." + simpleName);
-        PrintWriter pw = new PrintWriter(classfile.openWriter());
-        pw.println("package " + packageName + ";");
-        pw.println("public class " + simpleName + " extends "
-            + TypeTokenResolver.Builder.class.getCanonicalName() + " {");
-        pw.println("public " + simpleName + "() {");
-        for (Map.Entry<String, String> entry : d.getAllTypeTokens().entrySet()) {
-          if (elements.getTypeElement(entry.getValue()) != null) {
-            pw.println("addTypeToken(\"" + entry.getKey() + "\", " + entry.getValue()
-                + ".class.getName());");
-          }
-        }
-        pw.println("}");
-        pw.println("}");
-        pw.close();
-      } catch (FilerException e) {
-        log("Ignoring exception: %s", e.getMessage());
-      } catch (IOException e) {
-        error("Could not write BuilderImpl: " + e.getMessage());
-      }
-      log("Finished!");
-    }
-    return false;
-  }
-
-  private void error(String message, Object... args) {
-    processingEnv.getMessager().printMessage(Kind.ERROR, "ERROR: " + String.format(message, args));
-  }
-
-  private void log(Element elt, String message, Object... args) {
-    if (verbose) {
-      processingEnv.getMessager().printMessage(Kind.NOTE, String.format(message, args), elt);
-    }
-  }
-
-  private void log(String message, Object... args) {
-    if (verbose) {
-      processingEnv.getMessager().printMessage(Kind.NOTE, String.format(message, args));
-    }
-  }
-}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/RfValidator.java b/user/src/com/google/web/bindery/requestfactory/apt/RfValidator.java
new file mode 100644
index 0000000..55b23db
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/RfValidator.java
@@ -0,0 +1,131 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.gwt.dev.util.Name.BinaryName;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedOptions;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
+
+/**
+ * The entry point for annotation validation.
+ */
+@SupportedAnnotationTypes("*")
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+@SupportedOptions({"rootOverride", "suppressErrors", "suppressWarnings", "verbose"})
+public class RfValidator extends AbstractProcessor {
+
+  private boolean clientOnly;
+  private boolean mustResolveAllMappings;
+  private List<String> rootOverride;
+  private boolean forceErrors;
+  private State state;
+
+  @Override
+  public synchronized void init(ProcessingEnvironment processingEnv) {
+    super.init(processingEnv);
+    String option = processingEnv.getOptions().get("rootOverride");
+    if (option != null) {
+      setRootOverride(Arrays.asList(option.split(",")));
+    }
+  }
+
+  @Override
+  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    // Are we finished, if so, clean up
+    if (roundEnv.processingOver()) {
+      state = null;
+      return false;
+    }
+
+    // Newly initialized or being reused?
+    if (state == null) {
+      state = forceErrors ? new State.ForTesting(processingEnv) : new State(processingEnv);
+      if (state.isPoisoned()) {
+        // Could not initialize State object, bail out
+        return false;
+      }
+      // Produce a "lite" map just for JRE-only clients
+      state.setClientOnly(clientOnly);
+      // Disallow @ProxyForName or @ServiceName that can't be resolved
+      state.setMustResolveAllMappings(mustResolveAllMappings);
+    }
+
+    try {
+      // Bootstrap the State's work queue
+      new Finder().scan(getTypesToProcess(state, roundEnv), state);
+      // Execute the work items
+      state.executeJobs();
+    } catch (HaltException ignored) {
+      // Already logged. Let any unhandled RuntimeExceptions fall out.
+    }
+    return false;
+  }
+
+  public void setClientOnly(boolean clientOnly) {
+    this.clientOnly = clientOnly;
+  }
+
+  void setForceErrors(boolean forceErrors) {
+    this.forceErrors = forceErrors;
+  }
+
+  /**
+   * Make it an error to not resolve all ProxyForName and ServiceName mappings.
+   */
+  void setMustResolveAllMappings(boolean requireAll) {
+    this.mustResolveAllMappings = requireAll;
+  }
+
+  /**
+   * Instead of scanning the round's root elements, scan these type names
+   * instead. This is used by the ValidationTool to scan pre-compiled
+   * classfiles.
+   */
+  void setRootOverride(List<String> binaryTypeNames) {
+    this.rootOverride = binaryTypeNames;
+  }
+
+  private Set<TypeElement> getTypesToProcess(State state, RoundEnvironment roundEnv) {
+    if (rootOverride == null) {
+      return ElementFilter.typesIn(roundEnv.getRootElements());
+    }
+    Set<TypeElement> toScan = new HashSet<TypeElement>();
+    for (String binaryTypeName : rootOverride) {
+      TypeElement found =
+          state.elements.getTypeElement(BinaryName.toSourceName(binaryTypeName.trim()));
+      if (found == null) {
+        state.poison(null, Messages.noSuchType(binaryTypeName));
+      } else {
+        toScan.add(found);
+      }
+    }
+    rootOverride = null;
+    return toScan;
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/ScannerBase.java b/user/src/com/google/web/bindery/requestfactory/apt/ScannerBase.java
new file mode 100644
index 0000000..73efdb6
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/ScannerBase.java
@@ -0,0 +1,144 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.ElementScanner6;
+
+/**
+ * Contains utility methods for traversing RequestFactory declarations.
+ */
+class ScannerBase<R> extends ElementScanner6<R, State> {
+
+  /**
+   * Poisons the given type if one or more of the annotation values are
+   * non-null.
+   */
+  protected static void poisonIfAnnotationPresent(State state, TypeElement x,
+      Annotation... annotations) {
+    for (Annotation a : annotations) {
+      if (a != null) {
+        state.poison(x, Messages.redundantAnnotation(a.annotationType().getSimpleName()));
+      }
+    }
+  }
+
+  protected static ExecutableType viewIn(TypeElement lookIn, ExecutableElement methodElement, State state) {
+    try {
+      return (ExecutableType) state.types.asMemberOf(state.types.getDeclaredType(lookIn),
+          methodElement);
+    } catch (IllegalArgumentException e) {
+      return (ExecutableType) methodElement.asType();
+    }
+  }
+
+  @Override
+  public final R scan(Element x, State state) {
+    try {
+      return super.scan(x, state);
+    } catch (HaltException e) {
+      throw e;
+    } catch (Throwable e) {
+      StringWriter sw = new StringWriter();
+      e.printStackTrace(new PrintWriter(sw));
+      state.poison(x, sw.toString());
+      throw new HaltException();
+    }
+  }
+
+  /**
+   * No parameters, name stars with "get" or is a boolean / Boolean isFoo hasFoo
+   * method.
+   */
+  protected boolean isGetter(ExecutableElement x, State state) {
+    String name = x.getSimpleName().toString();
+    TypeMirror returnType = x.getReturnType();
+    if (!x.getParameters().isEmpty()) {
+      return false;
+    }
+    if (name.startsWith("get")) {
+      return true;
+    }
+    if (name.startsWith("is") || name.startsWith("has")) {
+      TypeMirror javaLangBoolean =
+          state.types.boxedClass(state.types.getPrimitiveType(TypeKind.BOOLEAN)).asType();
+      if (returnType.getKind().equals(TypeKind.BOOLEAN)
+          || state.types.isSameType(returnType, javaLangBoolean)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Name starts with set, has one parameter, returns either null or something
+   * assignable from the element's enclosing type.
+   */
+  protected boolean isSetter(ExecutableElement x, State state) {
+    String name = x.getSimpleName().toString();
+    TypeMirror returnType = x.getReturnType();
+
+    if (x.getParameters().size() != 1) {
+      return false;
+    }
+    if (!name.startsWith("set")) {
+      return false;
+    }
+    if (returnType.getKind().equals(TypeKind.VOID)) {
+      return true;
+    }
+    if (x.getEnclosingElement() != null
+        && state.types.isAssignable(x.getEnclosingElement().asType(), returnType)) {
+      return true;
+    }
+    return false;
+  }
+
+  protected R scanAllInheritedMethods(TypeElement x, State state) {
+    R toReturn = DEFAULT_VALUE;
+    List<ExecutableElement> methods = ElementFilter.methodsIn(state.elements.getAllMembers(x));
+    for (ExecutableElement method : methods) {
+      toReturn = scan(method, state);
+    }
+    return toReturn;
+  }
+
+  /**
+   * Ignore all static initializers and methods defined in the base
+   * RequestFactory interfaces
+   */
+  protected boolean shouldIgnore(ExecutableElement x, State state) {
+    TypeMirror enclosingType = x.getEnclosingElement().asType();
+    return x.getKind().equals(ElementKind.STATIC_INIT)
+        || state.types.isSameType(state.objectType, enclosingType)
+        || state.types.isSameType(state.requestFactoryType, enclosingType)
+        || state.types.isSameType(state.requestContextType, enclosingType)
+        || state.types.isSameType(state.entityProxyType, enclosingType)
+        || state.types.isSameType(state.valueProxyType, enclosingType);
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/State.java b/user/src/com/google/web/bindery/requestfactory/apt/State.java
new file mode 100644
index 0000000..2b2a2c4
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/State.java
@@ -0,0 +1,466 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic.Kind;
+
+class State {
+  /**
+   * Slightly tweaked implementation used when running tests.
+   */
+  static class ForTesting extends State {
+    public ForTesting(ProcessingEnvironment processingEnv) {
+      super(processingEnv);
+    }
+
+    @Override
+    boolean respectAnnotations() {
+      return false;
+    }
+  }
+
+  /**
+   * Implements comparable for priority ordering.
+   */
+  private static class Job implements Comparable<Job> {
+    private static long count;
+
+    public final TypeElement element;
+    public final ScannerBase<?> scanner;
+    private final long order = count++;
+    private final int priority;
+
+    public Job(TypeElement element, ScannerBase<?> scanner, int priority) {
+      this.element = element;
+      this.priority = priority;
+      this.scanner = scanner;
+    }
+
+    @Override
+    public int compareTo(Job o) {
+      int c = priority - o.priority;
+      if (c != 0) {
+        return c;
+      }
+      return Long.signum(order - o.order);
+    }
+
+    @Override
+    public String toString() {
+      return scanner.getClass().getSimpleName() + " " + element.getSimpleName();
+    }
+  }
+
+  /**
+   * Used to take a {@code FooRequest extends Request<Foo>} and find the
+   * {@code Request<Foo>} type.
+   */
+  static TypeMirror viewAs(DeclaredType desiredType, TypeMirror searchFrom, State state) {
+    if (!desiredType.getTypeArguments().isEmpty()) {
+      throw new IllegalArgumentException("Expecting raw type, received " + desiredType.toString());
+    }
+    Element searchElement = state.types.asElement(searchFrom);
+    switch (searchElement.getKind()) {
+      case CLASS:
+      case INTERFACE:
+      case ENUM: {
+        TypeMirror rawSearchFrom = state.types.getDeclaredType((TypeElement) searchElement);
+        if (state.types.isSameType(desiredType, rawSearchFrom)) {
+          return searchFrom;
+        }
+        for (TypeMirror s : state.types.directSupertypes(searchFrom)) {
+          TypeMirror maybe = viewAs(desiredType, s, state);
+          if (maybe != null) {
+            return maybe;
+          }
+        }
+        break;
+      }
+      case TYPE_PARAMETER: {
+        // Search <T extends Foo> as Foo
+        return viewAs(desiredType, ((TypeVariable) searchElement).getUpperBound(), state);
+      }
+    }
+    return null;
+  }
+
+  final TypeMirror baseProxyType;
+  final Elements elements;
+  final DeclaredType entityProxyIdType;
+  final DeclaredType entityProxyType;
+  final DeclaredType extraTypesAnnotation;
+  final Filer filer;
+  final DeclaredType instanceRequestType;
+  final DeclaredType locatorType;
+  final DeclaredType objectType;
+  final DeclaredType requestContextType;
+  final DeclaredType requestFactoryType;
+  final DeclaredType requestType;
+  final DeclaredType serviceLocatorType;
+  final Set<TypeElement> seen;
+  final Types types;
+  final DeclaredType valueProxyType;
+  private final Map<Element, Element> clientToDomainMain;
+  private final SortedSet<Job> jobs = new TreeSet<Job>();
+  private final Messager messager;
+  private boolean poisoned;
+  private boolean requireAllMappings;
+  private final boolean suppressErrors;
+  private final boolean suppressWarnings;
+  private final boolean verbose;
+  /**
+   * Prevents duplicate messages from being emitted.
+   */
+  private final Map<Element, Set<String>> previousMessages = new HashMap<Element, Set<String>>();
+
+  private final Set<TypeElement> typesRequiringMapping = new LinkedHashSet<TypeElement>();
+  private boolean clientOnly;
+
+  public State(ProcessingEnvironment processingEnv) {
+    clientToDomainMain = new HashMap<Element, Element>();
+    elements = processingEnv.getElementUtils();
+    filer = processingEnv.getFiler();
+    messager = processingEnv.getMessager();
+    types = processingEnv.getTypeUtils();
+    suppressErrors = Boolean.parseBoolean(processingEnv.getOptions().get("suppressErrors"));
+    suppressWarnings = Boolean.parseBoolean(processingEnv.getOptions().get("suppressWarnings"));
+    verbose = Boolean.parseBoolean(processingEnv.getOptions().get("verbose"));
+
+    baseProxyType = findType("BaseProxy");
+    entityProxyType = findType("EntityProxy");
+    entityProxyIdType = findType("EntityProxyId");
+    extraTypesAnnotation = findType("ExtraTypes");
+    instanceRequestType = findType("InstanceRequest");
+    locatorType = findType("Locator");
+    objectType = findType(Object.class);
+    requestType = findType("Request");
+    requestContextType = findType("RequestContext");
+    requestFactoryType = findType("RequestFactory");
+    seen = new HashSet<TypeElement>();
+    serviceLocatorType = findType("ServiceLocator");
+    valueProxyType = findType("ValueProxy");
+  }
+
+  /**
+   * Add a mapping from a client method to a domain method.
+   */
+  public void addMapping(ExecutableElement clientMethod, ExecutableElement domainMethod) {
+    if (domainMethod == null) {
+      debug(clientMethod, "No domain mapping");
+    } else {
+      debug(clientMethod, "Found domain method %s", domainMethod.toString());
+    }
+    clientToDomainMain.put(clientMethod, domainMethod);
+  }
+
+  /**
+   * Add a mapping from a client type to a domain type.
+   */
+  public void addMapping(TypeElement clientType, TypeElement domainType) {
+    if (domainType == null) {
+      debug(clientType, "No domain mapping");
+    } else {
+      debug(clientType, "Found domain type %s", domainType.toString());
+    }
+    clientToDomainMain.put(clientType, domainType);
+  }
+
+  /**
+   * Check an element for an {@code ExtraTypes} annotation. Handles both methods
+   * and types.
+   */
+  public void checkExtraTypes(Element x) {
+    (new ExtraTypesScanner<Void>() {
+      @Override
+      public Void visitExecutable(ExecutableElement x, State state) {
+        checkForAnnotation(x, state);
+        return null;
+      }
+
+      @Override
+      public Void visitType(TypeElement x, State state) {
+        checkForAnnotation(x, state);
+        return null;
+      }
+
+      @Override
+      protected void scanExtraType(TypeElement extraType) {
+        maybeScanProxy(extraType);
+      }
+    }).scan(x, this);
+  }
+
+  /**
+   * Print a warning message if verbose mode is enabled. A warning is used to
+   * ensure that the message shows up in Eclipse's editor (a note only makes it
+   * into the error console).
+   */
+  public void debug(Element elt, String message, Object... args) {
+    if (verbose) {
+      messager.printMessage(Kind.WARNING, String.format(message, args), elt);
+    }
+  }
+
+  public void executeJobs() {
+    while (!jobs.isEmpty()) {
+      Job job = jobs.first();
+      jobs.remove(job);
+      debug(job.element, "Scanning");
+      try {
+        job.scanner.scan(job.element, this);
+      } catch (HaltException ignored) {
+        // Already reported
+      } catch (Throwable e) {
+        StringWriter sw = new StringWriter();
+        e.printStackTrace(new PrintWriter(sw));
+        poison(job.element, sw.toString());
+      }
+    }
+    if (clientOnly) {
+      // Don't want to check for mappings in client-only mode
+      return;
+    }
+    for (TypeElement element : typesRequiringMapping) {
+      if (!getClientToDomainMap().containsKey(element)) {
+        if (types.isAssignable(element.asType(), requestContextType)) {
+          poison(element, Messages.contextMustBeAnnotated(element.getSimpleName()));
+        } else {
+          poison(element, Messages.proxyMustBeAnnotated(element.getSimpleName()));
+        }
+      }
+    }
+  }
+
+  /**
+   * Utility method to look up raw types from class literals.
+   */
+  public DeclaredType findType(Class<?> clazz) {
+    return types.getDeclaredType(elements.getTypeElement(clazz.getCanonicalName()));
+  }
+
+  /**
+   * Returns a map of client elements to their domain counterparts. The keys may
+   * be RequestContext or Proxy types or methods within those types.
+   */
+  public Map<Element, Element> getClientToDomainMap() {
+    return Collections.unmodifiableMap(clientToDomainMain);
+  }
+
+  public boolean isClientOnly() {
+    return clientOnly;
+  }
+
+  public boolean isMappingRequired(TypeElement element) {
+    return typesRequiringMapping.contains(element);
+  }
+
+  public boolean isPoisoned() {
+    return poisoned;
+  }
+
+  /**
+   * Verifies that the given type may be used with RequestFactory.
+   * 
+   * @see TransportableTypeVisitor
+   */
+  public boolean isTransportableType(TypeMirror asType) {
+    return asType.accept(new TransportableTypeVisitor(), this);
+  }
+
+  public void maybeScanContext(TypeElement requestContext) {
+    // Also ignore RequestContext itself
+    if (fastFail(requestContext) || types.isSameType(requestContextType, requestContext.asType())) {
+      return;
+    }
+    jobs.add(new Job(requestContext, new RequestContextScanner(), 0));
+    if (!clientOnly) {
+      jobs.add(new Job(requestContext, new DomainChecker(), 1));
+    }
+  }
+
+  public void maybeScanFactory(TypeElement factoryType) {
+    if (fastFail(factoryType) || types.isSameType(requestFactoryType, factoryType.asType())) {
+      return;
+    }
+    jobs.add(new Job(factoryType, new RequestFactoryScanner(), 0));
+    jobs.add(new Job(factoryType, new DeobfuscatorBuilder(), 2));
+  }
+
+  public void maybeScanProxy(TypeElement proxyType) {
+    if (fastFail(proxyType)) {
+      return;
+    }
+    jobs.add(new Job(proxyType, new ProxyScanner(), 0));
+    if (!clientOnly) {
+      jobs.add(new Job(proxyType, new DomainChecker(), 1));
+    }
+  }
+
+  public boolean mustResolveAllAnnotations() {
+    return requireAllMappings;
+  }
+
+  /**
+   * Emits a fatal error message attached to an element. If the element or an
+   * eclosing type is annotated with {@link SkipInterfaceValidation} the message
+   * will be dropped.
+   */
+  public void poison(Element elt, String message) {
+    if (suppressErrors) {
+      return;
+    }
+
+    if (squelchMessage(elt, message)) {
+      return;
+    }
+
+    if (respectAnnotations()) {
+      Element check = elt;
+      while (check != null) {
+        if (check.getAnnotation(SkipInterfaceValidation.class) != null) {
+          return;
+        }
+        check = check.getEnclosingElement();
+      }
+    }
+    poisoned = true;
+    if (elt == null) {
+      messager.printMessage(Kind.ERROR, message);
+    } else {
+      messager.printMessage(Kind.ERROR, message, elt);
+    }
+  }
+
+  public void requireMapping(TypeElement interfaceElement) {
+    typesRequiringMapping.add(interfaceElement);
+  }
+
+  /**
+   * Set to {@code true} to indicate that only JVM-client support code needs to
+   * be generated.
+   */
+  public void setClientOnly(boolean clientOnly) {
+    this.clientOnly = clientOnly;
+  }
+
+  /**
+   * Set to {@code true} if it is an error for unresolved ProxyForName and
+   * ServiceName annotations to be left over.
+   */
+  public void setMustResolveAllMappings(boolean requireAllMappings) {
+    this.requireAllMappings = requireAllMappings;
+  }
+
+  /**
+   * Emits a warning message, unless the element or an enclosing element are
+   * annotated with a {@code @SuppressWarnings("requestfactory")}.
+   */
+  public void warn(Element elt, String message) {
+    if (suppressWarnings) {
+      return;
+    }
+
+    if (squelchMessage(elt, message)) {
+      return;
+    }
+
+    if (respectAnnotations()) {
+      SuppressWarnings suppress;
+      Element check = elt;
+      while (check != null) {
+        if (check.getAnnotation(SkipInterfaceValidation.class) != null) {
+          return;
+        }
+        suppress = check.getAnnotation(SuppressWarnings.class);
+        if (suppress != null) {
+          if (Arrays.asList(suppress.value()).contains("requestfactory")) {
+            return;
+          }
+        }
+        check = check.getEnclosingElement();
+      }
+    }
+
+    messager.printMessage(Kind.WARNING, message + Messages.warnSuffix(), elt);
+  }
+
+  /**
+   * This switch allows the RfValidatorTest code to be worked on in the IDE
+   * without causing compilation failures.
+   */
+  boolean respectAnnotations() {
+    return true;
+  }
+
+  private boolean fastFail(TypeElement element) {
+    return !seen.add(element);
+  }
+
+  /**
+   * Utility method to look up raw types from the requestfactory.shared package.
+   * This method is used instead of class literals in order to minimize the
+   * number of dependencies that get packed into {@code requestfactoy-apt.jar}.
+   * If the requested type cannot be found, the State will be poisoned.
+   */
+  private DeclaredType findType(String simpleName) {
+    TypeElement element =
+        elements.getTypeElement("com.google.web.bindery.requestfactory.shared." + simpleName);
+    if (element == null) {
+      poison(null, "Unable to find RequestFactory built-in type. "
+          + "Is requestfactory-[client|server].jar on the classpath?");
+      return null;
+    }
+    return types.getDeclaredType(element);
+  }
+
+  /**
+   * Prevents duplicate messages from being emitted.
+   */
+  private boolean squelchMessage(Element elt, String message) {
+    Set<String> set = previousMessages.get(elt);
+    if (set == null) {
+      set = new HashSet<String>();
+      // HashMap allows the null key
+      previousMessages.put(elt, set);
+    }
+    return !set.add(message);
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/TransportableTypeVisitor.java b/user/src/com/google/web/bindery/requestfactory/apt/TransportableTypeVisitor.java
new file mode 100644
index 0000000..9d47dd1
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/TransportableTypeVisitor.java
@@ -0,0 +1,116 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+
+/**
+ * Scans a TypeMirror to determine if it can be transported by RequestFactory.
+ */
+class TransportableTypeVisitor extends TypeVisitorBase<Boolean> {
+
+  /**
+   * AutoBeans supports arbitrary parameterizations, but there's work that needs
+   * to be done on the Request serialization code to support arbitrarily-complex
+   * parameterizations. For the moment, we'll disallow anything other than a
+   * one-level parameterization.
+   */
+  private boolean allowNestedParameterization = true;
+
+  @Override
+  public Boolean visitDeclared(DeclaredType t, State state) {
+    if (t.asElement().getKind().equals(ElementKind.ENUM)) {
+      return true;
+    }
+    if (state.types.isAssignable(t, state.entityProxyType)
+        || state.types.isAssignable(t, state.valueProxyType)) {
+      TypeElement proxyElement = (TypeElement) t.asElement();
+      state.maybeScanProxy(proxyElement);
+      state.requireMapping(proxyElement);
+      return true;
+    }
+    if (state.types.isAssignable(t, state.entityProxyIdType)) {
+      DeclaredType asId = (DeclaredType) State.viewAs(state.entityProxyIdType, t, state);
+      if (asId.getTypeArguments().isEmpty()) {
+        return false;
+      }
+      return asId.getTypeArguments().get(0).accept(this, state);
+    }
+    for (DeclaredType valueType : getValueTypes(state)) {
+      if (state.types.isAssignable(t, valueType)) {
+        return true;
+      }
+    }
+    if (state.types.isAssignable(t, state.findType(List.class))
+        || state.types.isAssignable(t, state.findType(Set.class))) {
+      if (!allowNestedParameterization) {
+        return false;
+      }
+      allowNestedParameterization = false;
+      DeclaredType asCollection =
+          (DeclaredType) State.viewAs(state.findType(Collection.class), t, state);
+      if (asCollection.getTypeArguments().isEmpty()) {
+        return false;
+      }
+      return t.getTypeArguments().get(0).accept(this, state);
+    }
+    return false;
+  }
+
+  @Override
+  public Boolean visitPrimitive(PrimitiveType x, State state) {
+    return true;
+  }
+
+  @Override
+  public Boolean visitTypeVariable(TypeVariable t, State state) {
+    if (t.equals(t.getUpperBound())) {
+      /*
+       * Weird case seen in Eclipse with self-parameterized type variables such
+       * as <T extends Enum<T>>.
+       * 
+       * TODO(bobv): Should intersection types be allowed at all? They don't
+       * seem to make much sense in the most-derived interface types, since the
+       * RF Generator won't know how to implement them.
+       */
+      return state.types.erasure(t).accept(this, state);
+    }
+    // Allow <T extends FooProxy>
+    return t.getUpperBound().accept(this, state);
+  }
+
+  @Override
+  public Boolean visitWildcard(WildcardType t, State state) {
+    // Allow List<? extends FooProxy>
+    return state.types.erasure(t).accept(this, state);
+  }
+
+  @Override
+  protected Boolean defaultAction(TypeMirror arg0, State arg1) {
+    return false;
+  }
+
+}
\ No newline at end of file
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/TypeComparator.java b/user/src/com/google/web/bindery/requestfactory/apt/TypeComparator.java
new file mode 100644
index 0000000..4de2e8f
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/TypeComparator.java
@@ -0,0 +1,50 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.util.Comparator;
+
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+
+/**
+ * Orders TypeElements by assignability, with most-derived types ordered first,
+ * and then by name.
+ */
+class TypeComparator implements Comparator<TypeElement> {
+  private final State state;
+
+  public TypeComparator(State state) {
+    this.state = state;
+  }
+
+  @Override
+  public int compare(TypeElement a, TypeElement b) {
+    DeclaredType typeA = state.types.getDeclaredType(a);
+    DeclaredType typeB = state.types.getDeclaredType(b);
+    if (state.types.isSameType(typeA, typeB)) {
+      return 0;
+    }
+    if (state.types.isSubtype(typeA, typeB)) {
+      return -1;
+    }
+    if (state.types.isSubtype(typeB, typeA)) {
+      return 1;
+    }
+    return state.elements.getBinaryName(a).toString().compareTo(
+        state.elements.getBinaryName(b).toString());
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/TypeSimplifier.java b/user/src/com/google/web/bindery/requestfactory/apt/TypeSimplifier.java
new file mode 100644
index 0000000..676005f
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/TypeSimplifier.java
@@ -0,0 +1,112 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.NoType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.SimpleTypeVisitor6;
+
+/**
+ * Utility type for reducing complex type declarations to ones suitable for
+ * determining assignability based on RequestFactory's type-mapping semantics.
+ * <p>
+ * Rules:
+ * <ul>
+ * <li>primitive type {@code ->} boxed type (optional)</li>
+ * <li>{@code void -> Void} (optional)</li>
+ * <li>{@code <T extends Foo> -> Foo}</li>
+ * <li>{@code ? extends Foo -> Foo}</li>
+ * <li>{@code Foo<complex type> -> Foo<simplified type>}</li>
+ * </ul>
+ */
+public class TypeSimplifier extends SimpleTypeVisitor6<TypeMirror, State> {
+
+  public static TypeMirror simplify(TypeMirror toBox, boolean boxPrimitives, State state) {
+    if (toBox == null) {
+      return null;
+    }
+    return toBox.accept(new TypeSimplifier(boxPrimitives), state);
+  }
+
+  private final boolean boxPrimitives;
+
+  private TypeSimplifier(boolean boxPrimitives) {
+    this.boxPrimitives = boxPrimitives;
+  }
+
+  @Override
+  public TypeMirror visitDeclared(DeclaredType x, State state) {
+    if (x.getTypeArguments().isEmpty()) {
+      return x;
+    }
+    List<TypeMirror> newArgs = new ArrayList<TypeMirror>(x.getTypeArguments().size());
+    for (TypeMirror original : x.getTypeArguments()) {
+      // Are we looking at a self-parameterized type like Foo<T extends Foo<T>>?
+      if (original.getKind().equals(TypeKind.TYPEVAR) && state.types.isAssignable(original, x)) {
+        // If so, return a raw type
+        return state.types.getDeclaredType((TypeElement) x.asElement());
+      } else {
+        newArgs.add(original.accept(this, state));
+      }
+    }
+    return state.types.getDeclaredType((TypeElement) x.asElement(), newArgs
+        .toArray(new TypeMirror[newArgs.size()]));
+  }
+
+  @Override
+  public TypeMirror visitNoType(NoType x, State state) {
+    if (boxPrimitives) {
+      return state.findType(Void.class);
+    }
+    return x;
+  }
+
+  @Override
+  public TypeMirror visitPrimitive(PrimitiveType x, State state) {
+    if (boxPrimitives) {
+      return state.types.boxedClass(x).asType();
+    }
+    return x;
+  }
+
+  @Override
+  public TypeMirror visitTypeVariable(TypeVariable x, State state) {
+    if (x.equals(x.getUpperBound())) {
+      // See comment in TransportableTypeVisitor
+      return state.types.erasure(x);
+    }
+    return x.getUpperBound().accept(this, state);
+  }
+
+  @Override
+  public TypeMirror visitWildcard(WildcardType x, State state) {
+    return state.types.erasure(x).accept(this, state);
+  }
+
+  @Override
+  protected TypeMirror defaultAction(TypeMirror x, State state) {
+    return state.types.getNoType(TypeKind.NONE);
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/TypeVisitorBase.java b/user/src/com/google/web/bindery/requestfactory/apt/TypeVisitorBase.java
new file mode 100644
index 0000000..5468981
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/TypeVisitorBase.java
@@ -0,0 +1,63 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.util.SimpleTypeVisitor6;
+
+/**
+ * Provides utility functions for type visitors.
+ * 
+ * @param <T> the return type for the visitor
+ */
+class TypeVisitorBase<T> extends SimpleTypeVisitor6<T, State> {
+  /**
+   * This method should be kept in sync with
+   * {@code ValueCodex.getAllValueTypes()}. It doesn't use
+   * {@code getAllValueTypes()} because a dependency on {@code ValueCodex} would
+   * pull in a large number of dependencies into the minimal
+   * {@code requestfactory-apt.jar}.
+   */
+  protected List<DeclaredType> getValueTypes(State state) {
+    List<DeclaredType> types = new ArrayList<DeclaredType>();
+    for (TypeKind kind : TypeKind.values()) {
+      if (kind.isPrimitive()) {
+        PrimitiveType primitiveType = state.types.getPrimitiveType(kind);
+        TypeElement boxedClass = state.types.boxedClass(primitiveType);
+        types.add((DeclaredType) boxedClass.asType());
+      }
+    }
+    types.add(state.findType(BigDecimal.class));
+    types.add(state.findType(BigInteger.class));
+    types.add(state.findType(Date.class));
+    types.add(state.findType(String.class));
+    types.add(state.findType(Void.class));
+    // Avoids compile-dependency bloat
+    types.add(state.types.getDeclaredType(state.elements
+        .getTypeElement("com.google.web.bindery.autobean.shared.Splittable")));
+    return Collections.unmodifiableList(types);
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/apt/ValidationTool.java b/user/src/com/google/web/bindery/requestfactory/apt/ValidationTool.java
new file mode 100644
index 0000000..206b9e9
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/apt/ValidationTool.java
@@ -0,0 +1,279 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.gwt.dev.util.Name.BinaryName;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
+
+import javax.lang.model.SourceVersion;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+/**
+ * Provides "late" validation services when server types aren't available to the
+ * shared-interface compilation process. This tool is provided the name of an
+ * output jar and the binary names of RequestFactory interfaces that should be
+ * validated. The validation process will provide pre-computed type map builders
+ * for use by the ServiceLayer.
+ * 
+ * @see http://code.google.com/p/google-web-toolkit/wiki/
+ *      RequestFactoryInterfaceValidation
+ */
+public class ValidationTool {
+  /**
+   * A JavaFileManager that writes the class outputs into a jar file or a
+   * directory.
+   */
+  static class JarOrDirectoryOutputFileManager extends ForwardingJavaFileManager<JavaFileManager> {
+    private final List<MemoryJavaFileObject> toOutput = new ArrayList<MemoryJavaFileObject>();
+    private final File output;
+
+    JarOrDirectoryOutputFileManager(File output, JavaFileManager fileManager) {
+      super(fileManager);
+      this.output = output;
+    }
+
+    @Override
+    public void close() throws IOException {
+      if (output.isDirectory()) {
+        writeToDirectory();
+      } else {
+        writeToJar();
+      }
+    }
+
+    /**
+     * Not expected to be called. Overridden to prevent accidental writes to
+     * disk.
+     */
+    @Override
+    public FileObject getFileForOutput(Location location, String packageName, String relativeName,
+        FileObject sibling) throws IOException {
+      throw new UnsupportedOperationException("Not expecting to write " + packageName + "/"
+          + relativeName);
+    }
+
+    /**
+     * This method will receive generated source and class files.
+     */
+    @Override
+    public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind,
+        FileObject sibling) throws IOException {
+      String path = BinaryName.toInternalName(className);
+      String suffix;
+      switch (kind) {
+        case CLASS:
+          suffix = ".class";
+          break;
+        case SOURCE:
+          suffix = ".java";
+          break;
+        default:
+          throw new UnsupportedOperationException("Unexpected kind " + kind);
+      }
+      MemoryJavaFileObject toReturn =
+          new MemoryJavaFileObject(uri("memory:///" + path + suffix), kind);
+      if (StandardLocation.CLASS_OUTPUT.equals(location) && Kind.CLASS.equals(kind)) {
+        toOutput.add(toReturn);
+      }
+      return toReturn;
+    }
+
+    @Override
+    public boolean isSameFile(FileObject a, FileObject b) {
+      if (a instanceof MemoryJavaFileObject && b instanceof MemoryJavaFileObject) {
+        MemoryJavaFileObject memoryA = (MemoryJavaFileObject) a;
+        MemoryJavaFileObject memoryB = (MemoryJavaFileObject) b;
+        return memoryA.getKind().equals(memoryB.getKind())
+            && memoryA.toUri().equals(memoryB.toUri());
+      }
+      if (a instanceof FakeJavaFileObject && b instanceof FakeJavaFileObject) {
+        // Only one file ever created
+        return true;
+      }
+      return super.isSameFile(a, b);
+    }
+
+    private void writeToDirectory() throws IOException {
+      for (MemoryJavaFileObject file : toOutput) {
+        String path = file.toUri().getPath();
+        if (path.equals("/fake/Fake.class")) {
+          // ignore dummy class
+          continue;
+        }
+        File target = new File(output, path);
+        target.getParentFile().mkdirs();
+        FileOutputStream out = new FileOutputStream(target);
+        out.write(file.bytes.toByteArray());
+        out.close();
+      }
+    }
+
+    private void writeToJar() throws IOException, FileNotFoundException {
+      JarOutputStream jar = new JarOutputStream(new FileOutputStream(output));
+      for (MemoryJavaFileObject file : toOutput) {
+        String path = file.toUri().getPath();
+        if (path.equals("/fake/Fake.class")) {
+          // ignore dummy class
+          continue;
+        }
+        // Strip leading /
+        ZipEntry entry = new ZipEntry(path.substring(1));
+        jar.putNextEntry(entry);
+        jar.write(file.bytes.toByteArray());
+      }
+      jar.close();
+    }
+  }
+
+  /**
+   * Provides a fake type to seed the compilation process with.
+   */
+  private static class FakeJavaFileObject extends SimpleJavaFileObject {
+    public FakeJavaFileObject() {
+      super(uri("fake:///fake/Fake.java"), JavaFileObject.Kind.SOURCE);
+    }
+
+    @Override
+    public CharSequence getCharContent(boolean arg0) throws IOException {
+      return "package fake; interface Fake {}";
+    }
+  }
+
+  /**
+   * An in-memory implementation of JavaFileObject.
+   */
+  private static class MemoryJavaFileObject extends SimpleJavaFileObject {
+    private ByteArrayOutputStream bytes;
+    private StringWriter charContents;
+
+    public MemoryJavaFileObject(URI uri, JavaFileObject.Kind kind) {
+      super(uri, kind);
+    }
+
+    @Override
+    public CharSequence getCharContent(boolean ignored) throws IOException {
+      return charContents.toString();
+    }
+
+    @Override
+    public OutputStream openOutputStream() throws IOException {
+      bytes = new ByteArrayOutputStream();
+      return bytes;
+    }
+
+    @Override
+    public Writer openWriter() throws IOException {
+      charContents = new StringWriter();
+      return charContents;
+    }
+  }
+
+  public static void main(String[] args) throws IOException {
+    System.exit(exec(args) ? 0 : -1);
+  }
+
+  /**
+   * A testable "main" method.
+   */
+  static boolean exec(String[] args) throws IOException {
+    if (args.length < 2) {
+      System.err.println("java -cp requestfactory-client.jar:your_server-code.jar "
+          + ValidationTool.class.getCanonicalName()
+          + " (/some/directory | output.jar) com.example.shared.MyRequestFactory");
+      System.err.println("See "
+          + "http://code.google.com/p/google-web-toolkit/wiki/RequestFactoryInterfaceValidation "
+          + "for more information.");
+      return false;
+    }
+    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+    if (compiler == null) {
+      System.err.println("This tool must be run with a JDK, not a JRE");
+      return false;
+    }
+    if (!compiler.getSourceVersions().contains(SourceVersion.RELEASE_6)) {
+      System.err.println("This tool must be run with a Java 1.6 compiler");
+      return false;
+    }
+
+    boolean clientOnly = false;
+    List<String> argList = new ArrayList<String>(Arrays.asList(args));
+    if (argList.get(0).equals("-client")) {
+      clientOnly = true;
+      argList.remove(0);
+    }
+
+    // Control how the compile process writes data to disk
+    JavaFileManager fileManager =
+        new JarOrDirectoryOutputFileManager(new File(argList.remove(0)), compiler
+            .getStandardFileManager(null, null, null));
+
+    // Create a validator and require it to process the specified types
+    RfValidator processor = new RfValidator();
+    if (clientOnly) {
+      processor.setClientOnly(true);
+    } else {
+      processor.setMustResolveAllMappings(true);
+    }
+    processor.setRootOverride(argList);
+
+    // Create the compilation task
+    CompilationTask task =
+        compiler.getTask(null, fileManager, null, null, null, Arrays
+            .asList(new FakeJavaFileObject()));
+    task.setProcessors(Arrays.asList(processor));
+    if (!task.call()) {
+      return false;
+    }
+    // Save data only on successful compilation
+    fileManager.close();
+    return true;
+  }
+
+  /**
+   * Convenience method for discarding {@link URISyntaxException}.
+   */
+  private static URI uri(String contents) {
+    try {
+      return new URI(contents);
+    } catch (URISyntaxException e) {
+      throw new RuntimeException(e);
+    }
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/server/Deobfuscator.java b/user/src/com/google/web/bindery/requestfactory/server/Deobfuscator.java
deleted file mode 100644
index 22abf24..0000000
--- a/user/src/com/google/web/bindery/requestfactory/server/Deobfuscator.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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.web.bindery.requestfactory.server;
-
-import com.google.gwt.dev.asm.Type;
-import com.google.web.bindery.requestfactory.vm.impl.OperationKey;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-
-/**
- * Provides access to payload deobfuscation services.
- */
-class Deobfuscator {
-  public static class Builder {
-    private Deobfuscator d = new Deobfuscator();
-    {
-      d.domainToClientType = new HashMap<String, List<String>>();
-      d.operationData = new HashMap<OperationKey, OperationData>();
-      d.typeTokens = new HashMap<String, String>();
-    }
-
-    public Builder addClientToDomainMapping(String domainBinaryName, SortedSet<Type> value) {
-      List<String> clientBinaryNames;
-      switch (value.size()) {
-        case 0:
-          clientBinaryNames = Collections.emptyList();
-          break;
-        case 1:
-          clientBinaryNames = Collections.singletonList(value.first().getClassName());
-          break;
-        default:
-          clientBinaryNames = new ArrayList<String>(value.size());
-          for (Type t : value) {
-            clientBinaryNames.add(t.getClassName());
-          }
-          clientBinaryNames = Collections.unmodifiableList(clientBinaryNames);
-      }
-      d.domainToClientType.put(domainBinaryName, clientBinaryNames);
-      return this;
-    }
-
-    public Builder addClientToDomainMappings(Map<Type, SortedSet<Type>> data) {
-      for (Map.Entry<Type, SortedSet<Type>> entry : data.entrySet()) {
-        String domainBinaryName = entry.getKey().getClassName();
-        SortedSet<Type> value = entry.getValue();
-        addClientToDomainMapping(domainBinaryName, value);
-      }
-      return this;
-    }
-
-    public Builder addOperation(OperationKey key, OperationData data) {
-      d.operationData.put(key, data);
-      return this;
-    }
-
-    public Builder addOperationData(Map<OperationKey, OperationData> operationData) {
-      d.operationData.putAll(operationData);
-      return this;
-    }
-
-    public Builder addRawTypeToken(String token, String binaryName) {
-      d.typeTokens.put(token, binaryName);
-      return this;
-    }
-
-    public Builder addRawTypeTokens(Map<String, String> typeTokens) {
-      for (Map.Entry<String, String> entry : typeTokens.entrySet()) {
-        addRawTypeToken(entry.getKey(), entry.getValue());
-      }
-      return this;
-    }
-
-    public Builder addTypeTokens(Map<String, Type> typeTokens) {
-      for (Map.Entry<String, Type> entry : typeTokens.entrySet()) {
-        d.typeTokens.put(entry.getKey(), entry.getValue().getClassName());
-      }
-      return this;
-    }
-
-    public Deobfuscator build() {
-      Deobfuscator toReturn = d;
-      toReturn.domainToClientType = Collections.unmodifiableMap(toReturn.domainToClientType);
-      toReturn.operationData = Collections.unmodifiableMap(toReturn.operationData);
-      toReturn.typeTokens = Collections.unmodifiableMap(toReturn.typeTokens);
-      d = null;
-      return toReturn;
-    }
-
-    public Builder merge(Deobfuscator deobfuscator) {
-      d.domainToClientType.putAll(deobfuscator.domainToClientType);
-      d.operationData.putAll(deobfuscator.operationData);
-      d.typeTokens.putAll(deobfuscator.typeTokens);
-      return this;
-    }
-  }
-
-  /**
-   * Maps domain types (e.g Foo) to client proxy types (e.g. FooAProxy,
-   * FooBProxy).
-   */
-  private Map<String, List<String>> domainToClientType;
-  private Map<OperationKey, OperationData> operationData;
-  /**
-   * Map of obfuscated ids to binary class names.
-   */
-  private Map<String, String> typeTokens;
-
-  Deobfuscator() {
-  }
-
-  /**
-   * Returns the client proxy types whose {@code @ProxyFor} is exactly
-   * {@code binaryTypeName}. Ordered such that the most-derived types will be
-   * iterated over first.
-   */
-  public List<String> getClientProxies(String binaryTypeName) {
-    return domainToClientType.get(binaryTypeName);
-  }
-
-  /**
-   * Returns a method descriptor that should be invoked on the service object.
-   */
-  public String getDomainMethodDescriptor(String operation) {
-    OperationData data = getData(operation);
-    return data == null ? null : data.getDomainMethodDescriptor();
-  }
-
-  public String getRequestContext(String operation) {
-    OperationData data = getData(operation);
-    return data == null ? null : data.getRequestContext();
-  }
-
-  public String getRequestContextMethodDescriptor(String operation) {
-    OperationData data = getData(operation);
-    return data == null ? null : data.getClientMethodDescriptor();
-  }
-
-  public String getRequestContextMethodName(String operation) {
-    OperationData data = getData(operation);
-    return data == null ? null : data.getMethodName();
-  }
-
-  /**
-   * Returns a type's binary name based on an obfuscated token.
-   */
-  public String getTypeFromToken(String token) {
-    return typeTokens.get(token);
-  }
-
-  private OperationData getData(String operation) {
-    OperationData data = operationData.get(new OperationKey(operation));
-    return data;
-  }
-}
\ No newline at end of file
diff --git a/user/src/com/google/web/bindery/requestfactory/server/RequestFactoryInterfaceValidator.java b/user/src/com/google/web/bindery/requestfactory/server/RequestFactoryInterfaceValidator.java
deleted file mode 100644
index f2c8b49..0000000
--- a/user/src/com/google/web/bindery/requestfactory/server/RequestFactoryInterfaceValidator.java
+++ /dev/null
@@ -1,1622 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.web.bindery.requestfactory.server;
-
-import com.google.gwt.dev.asm.AnnotationVisitor;
-import com.google.gwt.dev.asm.ClassReader;
-import com.google.gwt.dev.asm.ClassVisitor;
-import com.google.gwt.dev.asm.MethodVisitor;
-import com.google.gwt.dev.asm.Opcodes;
-import com.google.gwt.dev.asm.Type;
-import com.google.gwt.dev.asm.commons.EmptyVisitor;
-import com.google.gwt.dev.asm.commons.Method;
-import com.google.gwt.dev.asm.signature.SignatureReader;
-import com.google.gwt.dev.asm.signature.SignatureVisitor;
-import com.google.gwt.dev.util.Name;
-import com.google.gwt.dev.util.Name.BinaryName;
-import com.google.gwt.dev.util.Name.SourceOrBinaryName;
-import com.google.web.bindery.autobean.shared.ValueCodex;
-import com.google.web.bindery.requestfactory.shared.BaseProxy;
-import com.google.web.bindery.requestfactory.shared.EntityProxy;
-import com.google.web.bindery.requestfactory.shared.ExtraTypes;
-import com.google.web.bindery.requestfactory.shared.InstanceRequest;
-import com.google.web.bindery.requestfactory.shared.ProxyFor;
-import com.google.web.bindery.requestfactory.shared.ProxyForName;
-import com.google.web.bindery.requestfactory.shared.Request;
-import com.google.web.bindery.requestfactory.shared.RequestContext;
-import com.google.web.bindery.requestfactory.shared.RequestFactory;
-import com.google.web.bindery.requestfactory.shared.Service;
-import com.google.web.bindery.requestfactory.shared.ServiceName;
-import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation;
-import com.google.web.bindery.requestfactory.shared.ValueProxy;
-import com.google.web.bindery.requestfactory.vm.impl.OperationKey;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.annotation.Annotation;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Encapsulates validation logic to determine if a {@link RequestFactory}
- * interface, its {@link RequestContext}, and associated {@link EntityProxy}
- * interfaces match their domain counterparts. This implementation examines the
- * classfiles directly in order to avoid the need to load the types into the
- * JVM.
- * <p>
- * This class is amenable to being used as a unit test:
- * 
- * <pre>
- * public void testRequestFactory() {
- *   Logger logger = Logger.getLogger("");
- *   RequestFactoryInterfaceValidator v = new RequestFactoryInterfaceValidator(
- *     logger, new ClassLoaderLoader(MyRequestContext.class.getClassLoader()));
- *   v.validateRequestContext(MyRequestContext.class.getName());
- *   assertFalse(v.isPoisoned());
- * }
- * </pre>
- * This class also has a {@code main} method and can be used as a build-time
- * tool:
- * 
- * <pre>
- * java -cp gwt-servlet.jar:your-code.jar \
- *   com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidator \
- *   com.example.MyRequestFactory
- * </pre>
- */
-public class RequestFactoryInterfaceValidator {
-  /**
-   * An implementation of {@link Loader} that uses a {@link ClassLoader} to
-   * retrieve the class files.
-   */
-  public static class ClassLoaderLoader implements Loader {
-    private final ClassLoader loader;
-
-    public ClassLoaderLoader(ClassLoader loader) {
-      this.loader = loader;
-    }
-
-    public boolean exists(String resource) {
-      return loader.getResource(resource) != null;
-    }
-
-    public InputStream getResourceAsStream(String resource) {
-      return loader.getResourceAsStream(resource);
-    }
-  }
-
-  /**
-   * Abstracts the mechanism by which class files are loaded.
-   * 
-   * @see ClassLoaderLoader
-   */
-  public interface Loader {
-    /**
-     * Returns true if the specified resource can be loaded.
-     * 
-     * @param resource a resource name (e.g. <code>com/example/Foo.class</code>)
-     */
-    boolean exists(String resource);
-
-    /**
-     * Returns an InputStream to access the specified resource, or
-     * <code>null</code> if no such resource exists.
-     * 
-     * @param resource a resource name (e.g. <code>com/example/Foo.class</code>)
-     */
-    InputStream getResourceAsStream(String resource);
-  }
-
-  /**
-   * Improves error messages by providing context for the user.
-   * <p>
-   * Visible for testing.
-   */
-  static class ErrorContext {
-    private final Logger logger;
-    private final ErrorContext parent;
-    private Type currentType;
-    private Method currentMethod;
-    private RequestFactoryInterfaceValidator validator;
-
-    public ErrorContext(Logger logger) {
-      this.logger = logger;
-      this.parent = null;
-    }
-
-    protected ErrorContext(ErrorContext parent) {
-      this.logger = parent.logger;
-      this.parent = parent;
-      this.validator = parent.validator;
-    }
-
-    public void poison(String msg, Object... args) {
-      poison();
-      logger.logp(Level.SEVERE, currentType(), currentMethod(), String.format(msg, args));
-      validator.poisoned = true;
-    }
-
-    public void poison(String msg, Throwable t) {
-      poison();
-      logger.logp(Level.SEVERE, currentType(), currentMethod(), msg, t);
-      validator.poisoned = true;
-    }
-
-    public ErrorContext setMethod(Method method) {
-      ErrorContext toReturn = fork();
-      toReturn.currentMethod = method;
-      return toReturn;
-    }
-
-    public ErrorContext setType(Type type) {
-      ErrorContext toReturn = fork();
-      toReturn.currentType = type;
-      return toReturn;
-    }
-
-    public void spam(String msg, Object... args) {
-      logger.logp(Level.FINEST, currentType(), currentMethod(), String.format(msg, args));
-    }
-
-    protected ErrorContext fork() {
-      return new ErrorContext(this);
-    }
-
-    void setValidator(RequestFactoryInterfaceValidator validator) {
-      assert this.validator == null : "Cannot set validator twice";
-      this.validator = validator;
-    }
-
-    private String currentMethod() {
-      if (currentMethod != null) {
-        return print(currentMethod);
-      }
-      if (parent != null) {
-        return parent.currentMethod();
-      }
-      return null;
-    }
-
-    private String currentType() {
-      if (currentType != null) {
-        return print(currentType);
-      }
-      if (parent != null) {
-        return parent.currentType();
-      }
-      return null;
-    }
-
-    /**
-     * Populate {@link RequestFactoryInterfaceValidator#badTypes} with the
-     * current context.
-     */
-    private void poison() {
-      if (currentType != null) {
-        validator.badTypes.add(currentType.getClassName());
-      }
-      if (parent != null) {
-        parent.poison();
-      }
-    }
-  }
-
-  /**
-   * Used internally as a placeholder for types that cannot be mapped to a
-   * domain object.
-   */
-  interface MissingDomainType {
-  }
-
-  /**
-   * Collects the ProxyFor or Service annotation from an EntityProxy or
-   * RequestContext type.
-   */
-  private class DomainMapper extends EmptyVisitor {
-    private final ErrorContext logger;
-    private String domainInternalName;
-    private List<Class<? extends Annotation>> found = new ArrayList<Class<? extends Annotation>>();
-    private String locatorInternalName;
-
-    public DomainMapper(ErrorContext logger) {
-      this.logger = logger;
-      logger.spam("Finding domain mapping annotation");
-    }
-
-    public String getDomainInternalName() {
-      return domainInternalName;
-    }
-
-    public String getLocatorInternalName() {
-      return locatorInternalName;
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature, String superName,
-        String[] interfaces) {
-      if ((access & Opcodes.ACC_INTERFACE) == 0) {
-        logger.poison("Type must be an interface");
-      }
-    }
-
-    /**
-     * This method examines one annotation at a time.
-     */
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-      // Set to true if the annotation should have class literal values
-      boolean expectClasses = false;
-      // Set to true if the annonation has string values
-      boolean expectNames = false;
-
-      if (desc.equals(Type.getDescriptor(ProxyFor.class))) {
-        expectClasses = true;
-        found.add(ProxyFor.class);
-      } else if (desc.equals(Type.getDescriptor(ProxyForName.class))) {
-        expectNames = true;
-        found.add(ProxyForName.class);
-      } else if (desc.equals(Type.getDescriptor(Service.class))) {
-        expectClasses = true;
-        found.add(Service.class);
-      } else if (desc.equals(Type.getDescriptor(ServiceName.class))) {
-        expectNames = true;
-        found.add(ServiceName.class);
-      }
-
-      if (expectClasses) {
-        return new EmptyVisitor() {
-          @Override
-          public void visit(String name, Object value) {
-            if ("value".equals(name)) {
-              domainInternalName = ((Type) value).getInternalName();
-            } else if ("locator".equals(name)) {
-              locatorInternalName = ((Type) value).getInternalName();
-            }
-          }
-        };
-      }
-
-      if (expectNames) {
-        return new EmptyVisitor() {
-          @Override
-          public void visit(String name, Object value) {
-            String sourceName;
-            boolean locatorRequired = "locator".equals(name);
-            boolean valueRequired = "value".equals(name);
-            if (valueRequired || locatorRequired) {
-              sourceName = (String) value;
-            } else {
-              return;
-            }
-
-            /*
-             * The input is a source name, so we need to convert it to an
-             * internal name. We'll do this by substituting dollar signs for the
-             * last slash in the name until there are no more slashes.
-             */
-            StringBuffer desc = new StringBuffer(sourceName.replace('.', '/'));
-            while (!loader.exists(desc.toString() + ".class")) {
-              logger.spam("Did not find " + desc.toString());
-              int idx = desc.lastIndexOf("/");
-              if (idx == -1) {
-                if (locatorRequired) {
-                  logger.poison("Cannot find locator named %s", value);
-                } else if (valueRequired) {
-                  logger.poison("Cannot find domain type named %s", value);
-                }
-                return;
-              }
-              desc.setCharAt(idx, '$');
-            }
-
-            if (locatorRequired) {
-              locatorInternalName = desc.toString();
-              logger.spam(locatorInternalName);
-            } else if (valueRequired) {
-              domainInternalName = desc.toString();
-              logger.spam(domainInternalName);
-            } else {
-              throw new RuntimeException("Should not reach here");
-            }
-          }
-        };
-      }
-      return null;
-    }
-
-    @Override
-    public void visitEnd() {
-      // Only allow one annotation
-      if (found.size() > 1) {
-        StringBuilder sb = new StringBuilder();
-        for (Class<?> clazz : found) {
-          sb.append(" @").append(clazz.getSimpleName());
-        }
-        logger.poison("Redundant domain mapping annotations present:%s", sb.toString());
-      }
-    }
-  }
-
-  private class ExtraTypesCollector extends EmptyVisitor {
-    private final ErrorContext logger;
-    private final Set<Type> collected = new HashSet<Type>();
-
-    public ExtraTypesCollector(ErrorContext logger) {
-      this.logger = logger;
-      logger.spam("Collecting extra types");
-    }
-
-    public Type[] exec(Type type) {
-      for (Type toExamine : getSupertypes(logger, type)) {
-        RequestFactoryInterfaceValidator.this.visit(logger, toExamine.getInternalName(), this);
-      }
-      return collected.toArray(new Type[collected.size()]);
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-      if (!desc.equals(Type.getDescriptor(ExtraTypes.class))) {
-        return null;
-      }
-
-      return new EmptyVisitor() {
-
-        @Override
-        public AnnotationVisitor visitArray(String name) {
-          if (!"value".equals(name)) {
-            return null;
-          }
-          return new EmptyVisitor() {
-            @Override
-            public void visit(String name, Object value) {
-              collected.add((Type) value);
-            }
-          };
-        }
-
-      };
-    }
-  }
-
-  /**
-   * Collects information about domain objects. This visitor is intended to be
-   * iteratively applied to collect all methods in a type hierarchy.
-   */
-  private class MethodsInHierarchyCollector extends EmptyVisitor {
-    private final ErrorContext logger;
-    private Set<RFMethod> methods = new LinkedHashSet<RFMethod>();
-    private Set<String> seen = new HashSet<String>();
-
-    private MethodsInHierarchyCollector(ErrorContext logger) {
-      this.logger = logger;
-    }
-
-    public Set<RFMethod> exec(String internalName) {
-      RequestFactoryInterfaceValidator.this.visit(logger, internalName, this);
-
-      Map<RFMethod, RFMethod> toReturn = new HashMap<RFMethod, RFMethod>();
-      // Return most-derived methods
-      for (RFMethod method : methods) {
-        RFMethod key =
-            new RFMethod(method.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, method
-                .getArgumentTypes()));
-
-        RFMethod compareTo = toReturn.get(key);
-        if (compareTo == null) {
-          toReturn.put(key, method);
-        } else if (isAssignable(logger, compareTo.getReturnType(), method.getReturnType())) {
-          toReturn.put(key, method);
-        }
-      }
-
-      return new HashSet<RFMethod>(toReturn.values());
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature, String superName,
-        String[] interfaces) {
-      if (!seen.add(name)) {
-        return;
-      }
-      if (!objectType.getInternalName().equals(superName)) {
-        RequestFactoryInterfaceValidator.this.visit(logger, superName, this);
-      }
-      if (interfaces != null) {
-        for (String intf : interfaces) {
-          RequestFactoryInterfaceValidator.this.visit(logger, intf, this);
-        }
-      }
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-        String[] exceptions) {
-      // Ignore initializers
-      if ("<clinit>".equals(name) || "<init>".equals(name)) {
-        return null;
-      }
-      final RFMethod method = new RFMethod(name, desc);
-      method.setDeclaredStatic((access & Opcodes.ACC_STATIC) != 0);
-      method.setDeclaredSignature(signature);
-      methods.add(method);
-
-      return new EmptyVisitor() {
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-          if (desc.equals(Type.getDescriptor(SkipInterfaceValidation.class))) {
-            method.setValidationSkipped(true);
-          }
-          return null;
-        }
-      };
-    }
-  }
-
-  private static class RFMethod extends Method {
-    private boolean isDeclaredStatic;
-    private String signature;
-    private boolean isValidationSkipped;
-
-    public RFMethod(String name, String desc) {
-      super(name, desc);
-    }
-
-    public String getSignature() {
-      return signature;
-    }
-
-    public boolean isDeclaredStatic() {
-      return isDeclaredStatic;
-    }
-
-    public boolean isValidationSkipped() {
-      return isValidationSkipped;
-    }
-
-    public void setDeclaredSignature(String signature) {
-      this.signature = signature;
-    }
-
-    public void setDeclaredStatic(boolean value) {
-      isDeclaredStatic = value;
-    }
-
-    public void setValidationSkipped(boolean isValidationSkipped) {
-      this.isValidationSkipped = isValidationSkipped;
-    }
-
-    @Override
-    public String toString() {
-      return (isDeclaredStatic ? "static " : "") + super.toString();
-    }
-  }
-
-  private class SupertypeCollector extends EmptyVisitor {
-    private final ErrorContext logger;
-    private final Set<String> seen = new HashSet<String>();
-    private final List<Type> supers = new ArrayList<Type>();
-
-    public SupertypeCollector(ErrorContext logger) {
-      this.logger = logger;
-    }
-
-    public List<Type> exec(Type type) {
-      RequestFactoryInterfaceValidator.this.visit(logger, type.getInternalName(), this);
-      return supers;
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature, String superName,
-        String[] interfaces) {
-      if (!seen.add(name)) {
-        return;
-      }
-      supers.add(Type.getObjectType(name));
-      if (!objectType.getInternalName().equals(name)) {
-        RequestFactoryInterfaceValidator.this.visit(logger, superName, this);
-      }
-      if (interfaces != null) {
-        for (String intf : interfaces) {
-          RequestFactoryInterfaceValidator.this.visit(logger, intf, this);
-        }
-      }
-    }
-  }
-
-  /**
-   * Return all types referenced by a method signature.
-   */
-  private static class TypesInSignatureCollector extends SignatureAdapter {
-    private final Set<Type> found = new HashSet<Type>();
-
-    public Type[] getFound() {
-      return found.toArray(new Type[found.size()]);
-    }
-
-    @Override
-    public SignatureVisitor visitArrayType() {
-      return this;
-    }
-
-    @Override
-    public SignatureVisitor visitClassBound() {
-      return this;
-    }
-
-    @Override
-    public void visitClassType(String name) {
-      found.add(Type.getObjectType(name));
-    }
-
-    @Override
-    public SignatureVisitor visitExceptionType() {
-      return this;
-    }
-
-    @Override
-    public SignatureVisitor visitInterface() {
-      return this;
-    }
-
-    @Override
-    public SignatureVisitor visitInterfaceBound() {
-      return this;
-    }
-
-    @Override
-    public SignatureVisitor visitParameterType() {
-      return this;
-    }
-
-    @Override
-    public SignatureVisitor visitReturnType() {
-      return this;
-    }
-
-    @Override
-    public SignatureVisitor visitSuperclass() {
-      return this;
-    }
-
-    @Override
-    public SignatureVisitor visitTypeArgument(char wildcard) {
-      return this;
-    }
-  }
-
-  static final Set<Class<?>> VALUE_TYPES = ValueCodex.getAllValueTypes();
-
-  public static void main(String[] args) {
-    if (args.length == 0) {
-      System.err.println("Usage: java -cp gwt-servlet.jar:your-code.jar "
-          + RequestFactoryInterfaceValidator.class.getCanonicalName()
-          + " com.example.MyRequestFactory");
-      System.exit(1);
-    }
-    RequestFactoryInterfaceValidator validator =
-        new RequestFactoryInterfaceValidator(Logger
-            .getLogger(RequestFactoryInterfaceValidator.class.getName()), new ClassLoaderLoader(
-            Thread.currentThread().getContextClassLoader()));
-    validator.validateRequestFactory(args[0]);
-    System.exit(validator.isPoisoned() ? 1 : 0);
-  }
-
-  static String messageCouldNotFindMethod(Type domainType, List<? extends Method> methods) {
-    StringBuilder sb = new StringBuilder();
-    sb.append(String.format("Could not find matching method in %s.\nPossible matches:\n",
-        print(domainType)));
-    for (Method domainMethod : methods) {
-      sb.append("  ").append(print(domainMethod)).append("\n");
-    }
-    return sb.toString();
-  }
-
-  private static String print(Method method) {
-    StringBuilder sb = new StringBuilder();
-    sb.append(print(method.getReturnType())).append(" ").append(method.getName()).append("(");
-    for (Type t : method.getArgumentTypes()) {
-      sb.append(print(t)).append(" ");
-    }
-    sb.append(")");
-    return sb.toString();
-  }
-
-  private static String print(Type type) {
-    return SourceOrBinaryName.toSourceName(type.getClassName());
-  }
-
-  /**
-   * A set of binary type names that are known to be bad.
-   */
-  private final Set<String> badTypes = new HashSet<String>();
-  /**
-   * The type {@link BaseProxy}.
-   */
-  private final Type baseProxyIntf = Type.getType(BaseProxy.class);
-  /**
-   * Maps client types (e.g. FooProxy) to server domain types (e.g. Foo).
-   */
-  private final Map<Type, Type> clientToDomainType = new HashMap<Type, Type>();
-  /**
-   * Maps client types (e.g. FooProxy or FooContext) to their locator types
-   * (e.g. FooLocator or FooServiceLocator).
-   */
-  private final Map<Type, Type> clientToLocatorMap = new HashMap<Type, Type>();
-  /**
-   * Maps domain types (e.g Foo) to client proxy types (e.g. FooAProxy,
-   * FooBProxy).
-   */
-  private final Map<Type, SortedSet<Type>> domainToClientType =
-      new HashMap<Type, SortedSet<Type>>();
-  /**
-   * The type {@link EntityProxy}.
-   */
-  private final Type entityProxyIntf = Type.getType(EntityProxy.class);
-  /**
-   * The type {@link Enum}.
-   */
-  private final Type enumType = Type.getType(Enum.class);
-  /**
-   * A placeholder type for client types that could not be resolved to a domain
-   * type.
-   */
-  private final Type errorType = Type.getType(MissingDomainType.class);
-  /**
-   * The type {@link InstanceRequest}.
-   */
-  private final Type instanceRequestIntf = Type.getType(InstanceRequest.class);
-  private final Loader loader;
-  /**
-   * A cache of all methods defined in a type hierarchy.
-   */
-  private final Map<Type, Set<RFMethod>> methodsInHierarchy = new HashMap<Type, Set<RFMethod>>();
-  /**
-   * Not static because it depends on {@link #parentLogger}.
-   */
-  private final Comparator<Type> typeNameComparator = new Comparator<Type>() {
-    @Override
-    public int compare(Type a, Type b) {
-      if (isAssignable(parentLogger, a, b)) {
-        return 1;
-      } else if (isAssignable(parentLogger, b, a)) {
-        return -1;
-      }
-      return a.getInternalName().compareTo(b.getInternalName());
-    }
-  };
-  /**
-   * Used to resolve obfuscated type tokens.
-   */
-  private final Map<String, Type> typeTokens = new HashMap<String, Type>();
-  /**
-   * The type {@link Object}.
-   */
-  private final Type objectType = Type.getObjectType("java/lang/Object");
-  /**
-   * Maps obfuscated operation names to dispatch information.
-   */
-  private final Map<OperationKey, OperationData> operationData =
-      new HashMap<OperationKey, OperationData>();
-  private final ErrorContext parentLogger;
-  private boolean poisoned;
-  /**
-   * The type {@link Request}.
-   */
-  private final Type requestIntf = Type.getType(Request.class);
-
-  /**
-   * The type {@link RequestContext}.
-   */
-  private final Type requestContextIntf = Type.getType(RequestContext.class);
-
-  /**
-   * A map of a type to all types that it could be assigned to.
-   */
-  private final Map<Type, List<Type>> supertypes = new HashMap<Type, List<Type>>();
-
-  /**
-   * The type {@link ValueProxy}.
-   */
-  private final Type valueProxyIntf = Type.getType(ValueProxy.class);
-
-  /**
-   * A set to prevent re-validation of a type.
-   */
-  private final Set<String> validatedTypes = new HashSet<String>();
-
-  /**
-   * Contains vaue types (e.g. Integer).
-   */
-  private final Set<Type> valueTypes = new HashSet<Type>();
-
-  /**
-   * Maps a domain object to the type returned from its getId method.
-   */
-  private final Map<Type, Type> unresolvedKeyTypes = new HashMap<Type, Type>();
-
-  {
-    for (Class<?> clazz : VALUE_TYPES) {
-      valueTypes.add(Type.getType(clazz));
-    }
-  }
-
-  public RequestFactoryInterfaceValidator(Logger logger, Loader loader) {
-    this.parentLogger = new ErrorContext(logger);
-    parentLogger.setValidator(this);
-    this.loader = loader;
-  }
-
-  /**
-   * Visible for testing.
-   */
-  RequestFactoryInterfaceValidator(ErrorContext errorContext, Loader loader) {
-    this.parentLogger = errorContext;
-    this.loader = loader;
-    errorContext.setValidator(this);
-  }
-
-  /**
-   * Reset the poisoned status of the validator so that it may be reused without
-   * destroying cached state.
-   */
-  public void antidote() {
-    poisoned = false;
-  }
-
-  public Deobfuscator getDeobfuscator() {
-    return new Deobfuscator.Builder().addClientToDomainMappings(domainToClientType)
-        .addOperationData(operationData).addTypeTokens(typeTokens).build();
-  }
-
-  /**
-   * Returns true if validation failed.
-   */
-  public boolean isPoisoned() {
-    return poisoned;
-  }
-
-  /**
-   * This method checks an EntityProxy interface against its peer domain object
-   * to determine if the server code would be able to process a request using
-   * the methods defined in the EntityProxy interface. It does not perform any
-   * checks as to whether or not the EntityProxy could actually be generated by
-   * the Generator.
-   * <p>
-   * This method may be called repeatedly on a single instance of the validator.
-   * Doing so will amortize type calculation costs.
-   * <p>
-   * Checks implemented:
-   * <ul>
-   * <li> <code>binaryName</code> implements EntityProxy</li>
-   * <li><code>binaryName</code> has a {@link ProxyFor} or {@link ProxyForName}
-   * annotation</li>
-   * <li>The domain object has getId() and getVersion() methods</li>
-   * <li>All property methods in the EntityProxy can be mapped onto an
-   * equivalent domain method (unless validation is skipped for the method)</li>
-   * <li>All referenced proxy types are valid</li>
-   * </ul>
-   * 
-   * @param binaryName the binary name (e.g. {@link Class#getName()}) of the
-   *          EntityProxy subtype
-   */
-  public void validateEntityProxy(String binaryName) {
-    validateProxy(binaryName, entityProxyIntf, true);
-  }
-
-  /**
-   * Determine if the specified type implements a proxy interface and apply the
-   * appropriate validations. This can be used as a general-purpose entry method
-   * when writing unit tests.
-   * 
-   * @param binaryName the binary name (e.g. {@link Class#getName()}) of the
-   *          EntityProxy or ValueProxy subtype
-   */
-  public void validateProxy(String binaryName) {
-    /*
-     * Don't call fastFail() here or the proxy may not be validated, since
-     * validateXProxy delegates to validateProxy() which would re-check.
-     */
-    Type proxyType = Type.getObjectType(BinaryName.toInternalName(binaryName));
-    if (isAssignable(parentLogger, entityProxyIntf, proxyType)) {
-      validateEntityProxy(binaryName);
-    } else if (isAssignable(parentLogger, valueProxyIntf, proxyType)) {
-      validateValueProxy(binaryName);
-    } else {
-      parentLogger.poison("%s is neither an %s nor a %s", print(proxyType), print(entityProxyIntf),
-          print(valueProxyIntf));
-    }
-  }
-
-  /**
-   * This method checks a RequestContext interface against its peer domain
-   * domain object to determine if the server code would be able to process a
-   * request using the the methods defined in the RequestContext interface. It
-   * does not perform any checks as to whether or not the RequestContext could
-   * actually be generated by the Generator.
-   * <p>
-   * This method may be called repeatedly on a single instance of the validator.
-   * Doing so will amortize type calculation costs.
-   * <p>
-   * Checks implemented:
-   * <ul>
-   * <li> <code>binaryName</code> implements RequestContext</li>
-   * <li><code>binaryName</code> has a {@link Service} or {@link ServiceName}
-   * annotation</li>
-   * <li>All service methods in the RequestContext can be mapped onto an
-   * equivalent domain method (unless validation is skipped for the method)</li>
-   * <li>All referenced EntityProxy types are valid</li>
-   * </ul>
-   * 
-   * @param binaryName the binary name (e.g. {@link Class#getName()}) of the
-   *          RequestContext subtype
-   * @see #validateEntityProxy(String)
-   */
-  public void validateRequestContext(String binaryName) {
-    if (fastFail(binaryName)) {
-      return;
-    }
-
-    Type requestContextType = Type.getObjectType(BinaryName.toInternalName(binaryName));
-    final ErrorContext logger = parentLogger.setType(requestContextType);
-
-    // Quick sanity check for calling code
-    if (!isAssignable(logger, requestContextIntf, requestContextType)) {
-      logger.poison("%s is not a %s", print(requestContextType), RequestContext.class
-          .getSimpleName());
-      return;
-    }
-
-    Type domainServiceType = getDomainType(logger, requestContextType, false);
-    if (domainServiceType == errorType) {
-      logger.poison("The type %s must be annotated with a @%s or @%s annotation", BinaryName
-          .toSourceName(binaryName), Service.class.getSimpleName(), ServiceName.class
-          .getSimpleName());
-      return;
-    }
-
-    for (RFMethod method : getMethodsInHierarchy(logger, requestContextType)) {
-      // Ignore methods in RequestContext itself
-      if (findCompatibleMethod(logger, requestContextIntf, method, false, true, true) != null) {
-        continue;
-      }
-
-      // Check the client method against the domain
-      Method found =
-          checkClientMethodInDomain(logger, method, domainServiceType, !clientToLocatorMap
-              .containsKey(requestContextType));
-      if (found != null) {
-        OperationKey key = new OperationKey(binaryName, method.getName(), method.getDescriptor());
-        OperationData data =
-            new OperationData.Builder().setClientMethodDescriptor(method.getDescriptor())
-                .setDomainMethodDescriptor(found.getDescriptor()).setMethodName(method.getName())
-                .setRequestContext(requestContextType.getClassName()).build();
-        operationData.put(key, data);
-      }
-      maybeCheckReferredProxies(logger, method);
-    }
-
-    maybeCheckExtraTypes(logger, requestContextType);
-    checkUnresolvedKeyTypes(logger);
-  }
-
-  /**
-   * This method checks a RequestFactory interface.
-   * <p>
-   * This method may be called repeatedly on a single instance of the validator.
-   * Doing so will amortize type calculation costs. It does not perform any
-   * checks as to whether or not the RequestContext could actually be generated
-   * by the Generator.
-   * <p>
-   * Checks implemented:
-   * <ul>
-   * <li> <code>binaryName</code> implements RequestFactory</li>
-   * <li>All referenced RequestContext types are valid</li>
-   * </ul>
-   * 
-   * @param binaryName the binary name (e.g. {@link Class#getName()}) of the
-   *          RequestContext subtype
-   * @see #validateRequestContext(String)
-   */
-  public void validateRequestFactory(String binaryName) {
-    if (fastFail(binaryName)) {
-      return;
-    }
-
-    Type requestFactoryType = Type.getObjectType(BinaryName.toInternalName(binaryName));
-    ErrorContext logger = parentLogger.setType(requestFactoryType);
-
-    // Quick sanity check for calling code
-    if (!isAssignable(logger, Type.getType(RequestFactory.class), requestFactoryType)) {
-      logger.poison("%s is not a %s", print(requestFactoryType), RequestFactory.class
-          .getSimpleName());
-      return;
-    }
-
-    // Validate each RequestContext method in the RF
-    for (Method contextMethod : getMethodsInHierarchy(logger, requestFactoryType)) {
-      Type returnType = contextMethod.getReturnType();
-      if (isAssignable(logger, requestContextIntf, returnType)) {
-        validateRequestContext(returnType.getClassName());
-      }
-    }
-
-    maybeCheckExtraTypes(logger, requestFactoryType);
-  }
-
-  /**
-   * This method checks a ValueProxy interface against its peer domain object to
-   * determine if the server code would be able to process a request using the
-   * methods defined in the ValueProxy interface. It does not perform any checks
-   * as to whether or not the ValueProxy could actually be generated by the
-   * Generator.
-   * <p>
-   * This method may be called repeatedly on a single instance of the validator.
-   * Doing so will amortize type calculation costs.
-   * <p>
-   * Checks implemented:
-   * <ul>
-   * <li> <code>binaryName</code> implements ValueProxy</li>
-   * <li><code>binaryName</code> has a {@link ProxyFor} or {@link ProxyForName}
-   * annotation</li>
-   * <li>All property methods in the EntityProxy can be mapped onto an
-   * equivalent domain method (unless validation is skipped for the method)</li>
-   * <li>All referenced proxy types are valid</li>
-   * </ul>
-   * 
-   * @param binaryName the binary name (e.g. {@link Class#getName()}) of the
-   *          EntityProxy subtype
-   */
-  public void validateValueProxy(String binaryName) {
-    validateProxy(binaryName, valueProxyIntf, false);
-  }
-
-  /**
-   * Record the mapping of a domain type to a client type. Proxy types will be
-   * added to {@link #domainToClientType}.
-   */
-  private void addToDomainMap(ErrorContext logger, Type domainType, Type clientType) {
-    clientToDomainType.put(clientType, domainType);
-
-    if (isAssignable(logger, baseProxyIntf, clientType)) {
-      SortedSet<Type> list = domainToClientType.get(domainType);
-      if (list == null) {
-        list = new TreeSet<Type>(typeNameComparator);
-        domainToClientType.put(domainType, list);
-      }
-      list.add(clientType);
-    }
-  }
-
-  /**
-   * Check that a given method RequestContext method declaration can be mapped
-   * to the server's domain type.
-   */
-  private RFMethod checkClientMethodInDomain(ErrorContext logger, RFMethod method,
-      Type domainServiceType, boolean requireStaticMethodsForRequestType) {
-    logger = logger.setMethod(method);
-
-    // Create a "translated" method declaration to search for
-    // Request<BlahProxy> foo(int a, BarProxy bar) -> Blah foo(int a, Bar bar);
-    Type returnType = getReturnType(logger, method);
-    Method searchFor =
-        createDomainMethod(logger, new Method(method.getName(), returnType, method
-            .getArgumentTypes()));
-
-    RFMethod found =
-        findCompatibleServiceMethod(logger, domainServiceType, searchFor, !method
-            .isValidationSkipped());
-
-    if (found != null) {
-      boolean isInstance = isAssignable(logger, instanceRequestIntf, method.getReturnType());
-      if (isInstance && found.isDeclaredStatic()) {
-        logger.poison("The method %s is declared to return %s, but the"
-            + " service method is static", method.getName(), InstanceRequest.class
-            .getCanonicalName());
-      } else if (requireStaticMethodsForRequestType && !isInstance && !found.isDeclaredStatic()) {
-        logger.poison("The method %s is declared to return %s, but the"
-            + " service method is not static", method.getName(), Request.class.getCanonicalName());
-      }
-    }
-    return found;
-  }
-
-  /**
-   * Check that the domain object has <code>getId()</code> and
-   * <code>getVersion</code> methods.
-   */
-  private void checkIdAndVersion(ErrorContext logger, Type domainType) {
-    if (objectType.equals(domainType)) {
-      return;
-    }
-    logger = logger.setType(domainType);
-    String findMethodName = "find" + BinaryName.getShortClassName(domainType.getClassName());
-    Type keyType = null;
-    RFMethod findMethod = null;
-
-    boolean foundFind = false;
-    boolean foundId = false;
-    boolean foundVersion = false;
-    for (RFMethod method : getMethodsInHierarchy(logger, domainType)) {
-      if ("getId".equals(method.getName()) && method.getArgumentTypes().length == 0) {
-        foundId = true;
-        keyType = method.getReturnType();
-        if (!isResolvedKeyType(logger, keyType)) {
-          unresolvedKeyTypes.put(domainType, keyType);
-        }
-      } else if ("getVersion".equals(method.getName()) && method.getArgumentTypes().length == 0) {
-        foundVersion = true;
-        if (!isResolvedKeyType(logger, method.getReturnType())) {
-          unresolvedKeyTypes.put(domainType, method.getReturnType());
-        }
-      } else if (findMethodName.equals(method.getName()) && method.getArgumentTypes().length == 1) {
-        foundFind = true;
-        findMethod = method;
-      }
-      if (foundFind && foundId && foundVersion) {
-        break;
-      }
-    }
-    if (!foundId) {
-      logger.poison("There is no getId() method in type %s", print(domainType));
-    }
-    if (!foundVersion) {
-      logger.poison("There is no getVersion() method in type %s", print(domainType));
-    }
-
-    if (foundFind) {
-      if (keyType != null && !isAssignable(logger, findMethod.getArgumentTypes()[0], keyType)) {
-        logger.poison("The key type returned by %s getId()"
-            + " cannot be used as the argument to %s(%s)", print(keyType), findMethod.getName(),
-            print(findMethod.getArgumentTypes()[0]));
-      }
-      if (!findMethod.isDeclaredStatic()) {
-        logger.poison("The %s method must be static", findMethodName);
-      }
-    } else {
-      logger.poison("There is no %s method in type %s that returns %2$s", findMethodName,
-          print(domainType));
-    }
-  }
-
-  /**
-   * Ensure that the given property method on an EntityProxy exists on the
-   * domain object.
-   */
-  private void checkPropertyMethod(ErrorContext logger, RFMethod clientPropertyMethod,
-      Type domainType) {
-    logger = logger.setMethod(clientPropertyMethod);
-
-    findCompatiblePropertyMethod(logger, domainType, createDomainMethod(logger,
-        clientPropertyMethod), !clientPropertyMethod.isValidationSkipped());
-  }
-
-  private void checkUnresolvedKeyTypes(ErrorContext logger) {
-    unresolvedKeyTypes.values().removeAll(domainToClientType.keySet());
-    if (unresolvedKeyTypes.isEmpty()) {
-      return;
-    }
-
-    for (Map.Entry<Type, Type> type : unresolvedKeyTypes.entrySet()) {
-      logger.setType(type.getKey()).poison(
-          "The domain type %s uses  a non-simple key type (%s)"
-              + " in its getId() or getVersion() method that" + " does not have a proxy mapping.",
-          print(type.getKey()), print(type.getValue()));
-    }
-  }
-
-  /**
-   * Convert a method declaration using client types (e.g. FooProxy) to domain
-   * types (e.g. Foo).
-   */
-  private Method createDomainMethod(ErrorContext logger, Method clientMethod) {
-    Type[] args = clientMethod.getArgumentTypes();
-    for (int i = 0, j = args.length; i < j; i++) {
-      args[i] = getDomainType(logger, args[i], true);
-    }
-    Type returnType = getDomainType(logger, clientMethod.getReturnType(), true);
-    return new Method(clientMethod.getName(), returnType, args);
-  }
-
-  /**
-   * Common checks to quickly determine if a type needs to be checked.
-   */
-  private boolean fastFail(String binaryName) {
-    if (!Name.isBinaryName(binaryName)) {
-      parentLogger.poison("%s is not a binary name", binaryName);
-      return true;
-    }
-
-    // Allow the poisoned flag to be reset without losing data
-    if (badTypes.contains(binaryName)) {
-      parentLogger.poison("Type type %s was previously marked as bad", binaryName);
-      return true;
-    }
-
-    // Don't revalidate the same type
-    if (!validatedTypes.add(binaryName)) {
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Finds a compatible method declaration in <code>domainType</code>'s
-   * hierarchy that is assignment-compatible with the given Method.
-   */
-  private RFMethod findCompatibleMethod(final ErrorContext logger, Type domainType,
-      Method searchFor, boolean mustFind, boolean allowOverloads, boolean boxReturnTypes) {
-    String methodName = searchFor.getName();
-    Type[] clientArgs = searchFor.getArgumentTypes();
-    Type clientReturnType = searchFor.getReturnType();
-    if (boxReturnTypes) {
-      clientReturnType = maybeBoxType(clientReturnType);
-    }
-    // Pull all methods out of the domain type
-    Map<String, List<RFMethod>> domainLookup = new LinkedHashMap<String, List<RFMethod>>();
-    for (RFMethod method : getMethodsInHierarchy(logger, domainType)) {
-      List<RFMethod> list = domainLookup.get(method.getName());
-      if (list == null) {
-        list = new ArrayList<RFMethod>();
-        domainLookup.put(method.getName(), list);
-      }
-      list.add(method);
-    }
-
-    // Find the matching method in the domain object
-    List<RFMethod> methods = domainLookup.get(methodName);
-    if (methods == null) {
-      if (mustFind) {
-        logger.poison("Could not find any methods named %s in %s", methodName, print(domainType));
-      }
-      return null;
-    }
-    if (methods.size() > 1 && !allowOverloads) {
-      StringBuilder sb = new StringBuilder();
-      sb.append(String.format("Method overloads found in type %s named %s:\n", print(domainType),
-          methodName));
-      for (RFMethod method : methods) {
-        sb.append("  ").append(print(method)).append("\n");
-      }
-      logger.poison(sb.toString());
-      return null;
-    }
-
-    // Check each overloaded name
-    for (RFMethod domainMethod : methods) {
-      Type[] domainArgs = domainMethod.getArgumentTypes();
-      Type domainReturnType = domainMethod.getReturnType();
-      if (boxReturnTypes) {
-        /*
-         * When looking for the implementation of a Request<Integer>, we want to
-         * match either int or Integer, so we'll box the domain method's return
-         * type.
-         */
-        domainReturnType = maybeBoxType(domainReturnType);
-      }
-
-      /*
-       * Make sure the client args can be passed into the domain args and the
-       * domain return type into the client return type.
-       */
-      if (isAssignable(logger, domainArgs, clientArgs)
-          && isAssignable(logger, clientReturnType, domainReturnType)) {
-
-        logger.spam("Mapped client method " + print(searchFor) + " to " + print(domainMethod));
-        return domainMethod;
-      }
-    }
-    if (mustFind) {
-      logger.poison(messageCouldNotFindMethod(domainType, methods));
-    }
-    return null;
-  }
-
-  /**
-   * Finds a compatible method declaration in <code>domainType</code>'s
-   * hierarchy that is assignment-compatible with the given Method.
-   */
-  private RFMethod findCompatiblePropertyMethod(final ErrorContext logger, Type domainType,
-      Method searchFor, boolean mustFind) {
-    return findCompatibleMethod(logger, domainType, searchFor, mustFind, false, false);
-  }
-
-  /**
-   * Finds a compatible method declaration in <code>domainType</code>'s
-   * hierarchy that is assignment-compatible with the given Method.
-   */
-  private RFMethod findCompatibleServiceMethod(final ErrorContext logger, Type domainType,
-      Method searchFor, boolean mustFind) {
-    return findCompatibleMethod(logger, domainType, searchFor, mustFind, true, true);
-  }
-
-  /**
-   * This looks like it should be a utility method somewhere else, but I can't
-   * find it.
-   */
-  private Type getBoxedType(Type primitive) {
-    switch (primitive.getSort()) {
-      case Type.BOOLEAN:
-        return Type.getType(Boolean.class);
-      case Type.BYTE:
-        return Type.getType(Byte.class);
-      case Type.CHAR:
-        return Type.getType(Character.class);
-      case Type.DOUBLE:
-        return Type.getType(Double.class);
-      case Type.FLOAT:
-        return Type.getType(Float.class);
-      case Type.INT:
-        return Type.getType(Integer.class);
-      case Type.LONG:
-        return Type.getType(Long.class);
-      case Type.SHORT:
-        return Type.getType(Short.class);
-      case Type.VOID:
-        return Type.getType(Void.class);
-    }
-    throw new RuntimeException(primitive.getDescriptor() + " is not a primitive type");
-  }
-
-  /**
-   * Convert the type used in a client-side EntityProxy or RequestContext
-   * declaration to the equivalent domain type. Value types and supported
-   * collections are a pass-through. EntityProxy types will be resolved to their
-   * domain object type. RequestContext types will be resolved to their service
-   * object.
-   */
-  private Type getDomainType(ErrorContext logger, Type clientType, boolean requireMapping) {
-    Type domainType = clientToDomainType.get(clientType);
-    if (domainType != null) {
-      return domainType;
-    }
-    if (isValueType(logger, clientType) || isCollectionType(logger, clientType)) {
-      domainType = clientType;
-    } else if (entityProxyIntf.equals(clientType) || valueProxyIntf.equals(clientType)) {
-      domainType = objectType;
-    } else {
-      logger = logger.setType(clientType);
-      DomainMapper pv = new DomainMapper(logger);
-      visit(logger, clientType.getInternalName(), pv);
-      if (pv.getDomainInternalName() == null) {
-        if (requireMapping) {
-          logger.poison("%s has no mapping to a domain type (e.g. @%s or @%s)", print(clientType),
-              ProxyFor.class.getSimpleName(), Service.class.getSimpleName());
-        }
-        domainType = errorType;
-      } else {
-        domainType = Type.getObjectType(pv.getDomainInternalName());
-      }
-      if (pv.getLocatorInternalName() != null) {
-        Type locatorType = Type.getObjectType(pv.getLocatorInternalName());
-        clientToLocatorMap.put(clientType, locatorType);
-      }
-    }
-    addToDomainMap(logger, domainType, clientType);
-    if (domainType != errorType) {
-      maybeCheckProxyType(logger, clientType);
-    }
-    return domainType;
-  }
-
-  /**
-   * Collect all of the methods defined within a type hierarchy.
-   */
-  private Set<RFMethod> getMethodsInHierarchy(ErrorContext logger, Type domainType) {
-    Set<RFMethod> toReturn = methodsInHierarchy.get(domainType);
-    if (toReturn == null) {
-      logger = logger.setType(domainType);
-      toReturn = new MethodsInHierarchyCollector(logger).exec(domainType.getInternalName());
-      methodsInHierarchy.put(domainType, Collections.unmodifiableSet(toReturn));
-    }
-    return toReturn;
-  }
-
-  /**
-   * Examines a generic RequestContext method declaration and determines the
-   * expected domain return type. This implementation is limited in that it will
-   * not attempt to resolve type bounds since that would essentially require
-   * implementing TypeOracle. In the case where the type bound cannot be
-   * resolved, this method will return Object's type.
-   */
-  private Type getReturnType(ErrorContext logger, RFMethod method) {
-    logger = logger.setMethod(method);
-    final String[] returnType = {objectType.getInternalName()};
-    String signature = method.getSignature();
-
-    final int expectedCount;
-    if (method.getReturnType().equals(instanceRequestIntf)) {
-      expectedCount = 2;
-    } else if (method.getReturnType().equals(requestIntf)) {
-      expectedCount = 1;
-    } else {
-      logger.spam("Punting on " + signature);
-      return Type.getObjectType(returnType[0]);
-    }
-
-    // TODO(bobv): If a class-based TypeOracle is built, use that instead
-    new SignatureReader(signature).accept(new SignatureAdapter() {
-      @Override
-      public SignatureVisitor visitReturnType() {
-        return new SignatureAdapter() {
-          int count;
-
-          @Override
-          public SignatureVisitor visitTypeArgument(char wildcard) {
-            if (++count == expectedCount) {
-              return new SignatureAdapter() {
-                @Override
-                public void visitClassType(String name) {
-                  returnType[0] = name;
-                }
-              };
-            }
-            return super.visitTypeArgument(wildcard);
-          }
-        };
-      }
-    });
-
-    logger.spam("Extracted " + returnType[0]);
-    return Type.getObjectType(returnType[0]);
-  }
-
-  private List<Type> getSupertypes(ErrorContext logger, Type type) {
-    if (type.getSort() != Type.OBJECT) {
-      return Collections.emptyList();
-    }
-    List<Type> toReturn = supertypes.get(type);
-    if (toReturn != null) {
-      return toReturn;
-    }
-
-    logger = logger.setType(type);
-
-    toReturn = new SupertypeCollector(logger).exec(type);
-    supertypes.put(type, Collections.unmodifiableList(toReturn));
-    return toReturn;
-  }
-
-  private boolean isAssignable(ErrorContext logger, Type possibleSupertype, Type possibleSubtype) {
-    // Fast-path for same type
-    if (possibleSupertype.equals(possibleSubtype)) {
-      return true;
-    }
-
-    // Supertype calculation is cached
-    List<Type> allSupertypes = getSupertypes(logger, possibleSubtype);
-    return allSupertypes.contains(possibleSupertype);
-  }
-
-  private boolean isAssignable(ErrorContext logger, Type[] possibleSupertypes,
-      Type[] possibleSubtypes) {
-    // Check the same number of types
-    if (possibleSupertypes.length != possibleSubtypes.length) {
-      return false;
-    }
-    for (int i = 0, j = possibleSupertypes.length; i < j; i++) {
-      if (!isAssignable(logger, possibleSupertypes[i], possibleSubtypes[i])) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  private boolean isCollectionType(@SuppressWarnings("unused") ErrorContext logger, Type type) {
-    // keeping the logger arg just for internal consistency for our small minds
-    return "java/util/List".equals(type.getInternalName())
-        || "java/util/Set".equals(type.getInternalName());
-  }
-
-  /**
-   * Keep in sync with {@code ReflectiveServiceLayer.isKeyType()}.
-   */
-  private boolean isResolvedKeyType(ErrorContext logger, Type type) {
-    if (isValueType(logger, type)) {
-      return true;
-    }
-
-    // We have already seen a mapping for the key type
-    if (domainToClientType.containsKey(type)) {
-      return true;
-    }
-
-    return false;
-  }
-
-  private boolean isValueType(ErrorContext logger, Type type) {
-    if (type.getSort() != Type.OBJECT) {
-      return true;
-    }
-    if (valueTypes.contains(type)) {
-      return true;
-    }
-    logger = logger.setType(type);
-    if (isAssignable(logger, enumType, type)) {
-      return true;
-    }
-    return false;
-  }
-
-  private Type maybeBoxType(Type maybePrimitive) {
-    if (maybePrimitive.getSort() == Type.OBJECT) {
-      return maybePrimitive;
-    }
-    return getBoxedType(maybePrimitive);
-  }
-
-  /**
-   * Examines a type for an {@link ExtraTypes} annotation and processes the
-   * referred types.
-   */
-  private void maybeCheckExtraTypes(ErrorContext logger, Type type) {
-    maybeCheckProxyType(logger, new ExtraTypesCollector(logger.setType(type)).exec(type));
-  }
-
-  /**
-   * Examine an array of Types and call {@link #validateEntityProxy(String)} or
-   * {@link #validateValueProxy(String)} if the type is a proxy.
-   */
-  private void maybeCheckProxyType(ErrorContext logger, Type... types) {
-    for (Type type : types) {
-      if (isAssignable(logger, entityProxyIntf, type)) {
-        validateEntityProxy(type.getClassName());
-      } else if (isAssignable(logger, valueProxyIntf, type)) {
-        validateValueProxy(type.getClassName());
-      } else if (isAssignable(logger, baseProxyIntf, type)) {
-        logger.poison(
-            "Invalid type hierarchy for %s. Only types derived from %s or %s may be used.",
-            print(type), print(entityProxyIntf), print(valueProxyIntf));
-      }
-    }
-  }
-
-  /**
-   * Examine the arguments and return value of a method and check any
-   * EntityProxies referred.
-   */
-  private void maybeCheckReferredProxies(ErrorContext logger, RFMethod method) {
-    if (method.getSignature() != null) {
-      TypesInSignatureCollector collector = new TypesInSignatureCollector();
-      SignatureReader reader = new SignatureReader(method.getSignature());
-      reader.accept(collector);
-      maybeCheckProxyType(logger, collector.getFound());
-    } else {
-      Type[] argTypes = method.getArgumentTypes();
-      Type returnType = getReturnType(logger, method);
-
-      // Check EntityProxy args ond return types against the domain
-      maybeCheckProxyType(logger, argTypes);
-      maybeCheckProxyType(logger, returnType);
-    }
-  }
-
-  /**
-   * Returns {@code true} if the type is assignable to EntityProxy or ValueProxy
-   * and has a mapping to a domain type.
-   * 
-   * @see com.google.web.bindery.requestfactory.gwt.rebind.model.RequestFactoryModel#shouldAttemptProxyValidation()
-   */
-  private boolean shouldAttemptProxyValidation(ErrorContext logger, Type type) {
-    logger = logger.setType(type);
-    if (!isAssignable(logger, entityProxyIntf, type) && !isAssignable(logger, valueProxyIntf, type)) {
-      return false;
-    }
-    if (getDomainType(logger, type, false) == errorType) {
-      return false;
-    }
-    return true;
-  }
-
-  private void validateProxy(String binaryName, Type expectedType, boolean requireId) {
-    if (fastFail(binaryName)) {
-      return;
-    }
-
-    Type proxyType = Type.getObjectType(BinaryName.toInternalName(binaryName));
-    typeTokens.put(OperationKey.hash(binaryName), proxyType);
-    ErrorContext logger = parentLogger.setType(proxyType);
-
-    // Quick sanity check for calling code
-    if (!isAssignable(logger, expectedType, proxyType)) {
-      parentLogger.poison("%s is not a %s", print(proxyType), print(expectedType));
-      return;
-    }
-
-    // Check supertypes first
-    for (Type supertype : getSupertypes(logger, proxyType)) {
-      if (shouldAttemptProxyValidation(logger, supertype)) {
-        maybeCheckProxyType(logger, supertype);
-      }
-    }
-
-    // Find the domain type
-    Type domainType = getDomainType(logger, proxyType, false);
-    if (domainType == errorType) {
-      logger.poison("The type %s must be annotated with a @%s or @%s annotation", BinaryName
-          .toSourceName(binaryName), ProxyFor.class.getSimpleName(), ProxyForName.class
-          .getSimpleName());
-      return;
-    }
-
-    // Check for getId() and getVersion() in domain if no locator is specified
-    if (requireId) {
-      Type locatorType = clientToLocatorMap.get(proxyType);
-      if (locatorType == null) {
-        checkIdAndVersion(logger, domainType);
-      }
-    }
-
-    // Collect all methods in the client proxy type
-    Set<RFMethod> clientPropertyMethods = getMethodsInHierarchy(logger, proxyType);
-
-    // Find the equivalent domain getter/setter method
-    for (RFMethod clientPropertyMethod : clientPropertyMethods) {
-      // Ignore stableId(). Can't use descriptor due to overrides
-      if ("stableId".equals(clientPropertyMethod.getName())
-          && clientPropertyMethod.getArgumentTypes().length == 0) {
-        continue;
-      }
-      checkPropertyMethod(logger, clientPropertyMethod, domainType);
-      maybeCheckReferredProxies(logger, clientPropertyMethod);
-    }
-    maybeCheckExtraTypes(logger, proxyType);
-  }
-
-  /**
-   * Load the classfile for the given binary name and apply the provided
-   * visitor.
-   * 
-   * @return <code>true</code> if the visitor was successfully visited
-   */
-  private boolean visit(ErrorContext logger, String internalName, ClassVisitor visitor) {
-    assert Name.isInternalName(internalName) : "internalName";
-    logger.spam("Visiting " + internalName);
-    InputStream inputStream = null;
-    try {
-      inputStream = loader.getResourceAsStream(internalName + ".class");
-      if (inputStream == null) {
-        logger.poison("Could not find class file for " + internalName);
-        return false;
-      }
-      ClassReader reader = new ClassReader(inputStream);
-      reader.accept(visitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG
-          | ClassReader.SKIP_FRAMES);
-      return true;
-    } catch (IOException e) {
-      logger.poison("Unable to open " + internalName, e);
-    } finally {
-      if (inputStream != null) {
-        try {
-          inputStream.close();
-        } catch (IOException ignored) {
-        }
-      }
-    }
-    return false;
-  }
-}
diff --git a/user/src/com/google/web/bindery/requestfactory/server/RequestFactoryJarExtractor.java b/user/src/com/google/web/bindery/requestfactory/server/RequestFactoryJarExtractor.java
index c4c82c2..4289ce5 100644
--- a/user/src/com/google/web/bindery/requestfactory/server/RequestFactoryJarExtractor.java
+++ b/user/src/com/google/web/bindery/requestfactory/server/RequestFactoryJarExtractor.java
@@ -29,17 +29,18 @@
 import com.google.gwt.dev.asm.Type;
 import com.google.gwt.dev.asm.commons.Method;
 import com.google.gwt.dev.util.Name;
+import com.google.gwt.dev.util.Name.SourceOrBinaryName;
 import com.google.gwt.dev.util.Util;
 import com.google.web.bindery.event.shared.SimpleEventBus;
-import com.google.web.bindery.requestfactory.apt.RfApt;
-import com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidator.ClassLoaderLoader;
-import com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidator.ErrorContext;
-import com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidator.Loader;
+import com.google.web.bindery.requestfactory.apt.RfValidator;
+import com.google.web.bindery.requestfactory.apt.ValidationTool;
+import com.google.web.bindery.requestfactory.gwt.client.RequestBatcher;
 import com.google.web.bindery.requestfactory.shared.BaseProxy;
 import com.google.web.bindery.requestfactory.shared.DefaultProxyStore;
 import com.google.web.bindery.requestfactory.shared.EntityProxy;
 import com.google.web.bindery.requestfactory.shared.EntityProxyChange;
 import com.google.web.bindery.requestfactory.shared.EntityProxyId;
+import com.google.web.bindery.requestfactory.shared.ExtraTypes;
 import com.google.web.bindery.requestfactory.shared.InstanceRequest;
 import com.google.web.bindery.requestfactory.shared.JsonRpcContent;
 import com.google.web.bindery.requestfactory.shared.JsonRpcProxy;
@@ -63,11 +64,9 @@
 import com.google.web.bindery.requestfactory.shared.ValueProxy;
 import com.google.web.bindery.requestfactory.shared.WriteOperation;
 import com.google.web.bindery.requestfactory.vm.RequestFactorySource;
-import com.google.web.bindery.requestfactory.vm.impl.TypeTokenResolver;
 import com.google.web.bindery.requestfactory.vm.testing.UrlRequestTransport;
 
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -92,6 +91,7 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.zip.ZipEntry;
 
@@ -109,6 +109,26 @@
    */
 
   /**
+   * An implementation of {@link Loader} that uses a {@link ClassLoader} to
+   * retrieve the class files.
+   */
+  public static class ClassLoaderLoader implements Loader {
+    private final ClassLoader loader;
+
+    public ClassLoaderLoader(ClassLoader loader) {
+      this.loader = loader;
+    }
+
+    public boolean exists(String resource) {
+      return loader.getResource(resource) != null;
+    }
+
+    public InputStream getResourceAsStream(String resource) {
+      return loader.getResourceAsStream(resource);
+    }
+  }
+
+  /**
    * Describes a way to emit the contents of a classpath, typically into a JAR
    * or filesystem directory.
    */
@@ -155,6 +175,28 @@
   }
 
   /**
+   * Abstracts the mechanism by which class files are loaded.
+   * 
+   * @see ClassLoaderLoader
+   */
+  public interface Loader {
+    /**
+     * Returns true if the specified resource can be loaded.
+     * 
+     * @param resource a resource name (e.g. <code>com/example/Foo.class</code>)
+     */
+    boolean exists(String resource);
+
+    /**
+     * Returns an InputStream to access the specified resource, or
+     * <code>null</code> if no such resource exists.
+     * 
+     * @param resource a resource name (e.g. <code>com/example/Foo.class</code>)
+     */
+    InputStream getResourceAsStream(String resource);
+  }
+
+  /**
    * Controls what is emitted by the tool.
    */
   public enum Mode {
@@ -206,6 +248,104 @@
     protected abstract boolean matches(String target);
   }
 
+  /**
+   * Improves error messages by providing context for the user.
+   * <p>
+   * Visible for testing.
+   */
+  static class ErrorContext {
+    private static String print(Method method) {
+      StringBuilder sb = new StringBuilder();
+      sb.append(print(method.getReturnType())).append(" ").append(method.getName()).append("(");
+      for (Type t : method.getArgumentTypes()) {
+        sb.append(print(t)).append(" ");
+      }
+      sb.append(")");
+      return sb.toString();
+    }
+
+    private static String print(Type type) {
+      return SourceOrBinaryName.toSourceName(type.getClassName());
+    }
+
+    private final Logger logger;
+    private final ErrorContext parent;
+
+    private Type currentType;
+
+    private Method currentMethod;
+
+    public ErrorContext(Logger logger) {
+      this.logger = logger;
+      this.parent = null;
+    }
+
+    protected ErrorContext(ErrorContext parent) {
+      this.logger = parent.logger;
+      this.parent = parent;
+    }
+
+    public void poison(String msg, Object... args) {
+      poison();
+      logger.logp(Level.SEVERE, currentType(), currentMethod(), String.format(msg, args));
+    }
+
+    public void poison(String msg, Throwable t) {
+      poison();
+      logger.logp(Level.SEVERE, currentType(), currentMethod(), msg, t);
+    }
+
+    public ErrorContext setMethod(Method method) {
+      ErrorContext toReturn = fork();
+      toReturn.currentMethod = method;
+      return toReturn;
+    }
+
+    public ErrorContext setType(Type type) {
+      ErrorContext toReturn = fork();
+      toReturn.currentType = type;
+      return toReturn;
+    }
+
+    public void spam(String msg, Object... args) {
+      logger.logp(Level.FINEST, currentType(), currentMethod(), String.format(msg, args));
+    }
+
+    protected ErrorContext fork() {
+      return new ErrorContext(this);
+    }
+
+    private String currentMethod() {
+      if (currentMethod != null) {
+        return print(currentMethod);
+      }
+      if (parent != null) {
+        return parent.currentMethod();
+      }
+      return null;
+    }
+
+    private String currentType() {
+      if (currentType != null) {
+        return print(currentType);
+      }
+      if (parent != null) {
+        return parent.currentType();
+      }
+      return null;
+    }
+
+    /**
+     * Populate {@link RequestFactoryInterfaceValidator#badTypes} with the
+     * current context.
+     */
+    private void poison() {
+      if (parent != null) {
+        parent.poison();
+      }
+    }
+  }
+
   private class AnnotationProcessor implements AnnotationVisitor {
     private final String sourceType;
     private final AnnotationVisitor av;
@@ -631,11 +771,12 @@
   @SuppressWarnings("deprecation")
   private static final Class<?>[] SHARED_CLASSES = {
       BaseProxy.class, DefaultProxyStore.class, EntityProxy.class, EntityProxyChange.class,
-      EntityProxyId.class, InstanceRequest.class, JsonRpcContent.class, JsonRpcProxy.class,
-      JsonRpcService.class, JsonRpcWireName.class, Locator.class, ProxyFor.class,
-      ProxyForName.class, ProxySerializer.class, ProxyStore.class, Receiver.class, Request.class,
-      RequestContext.class, RequestFactory.class, RequestTransport.class, ServerFailure.class,
-      Service.class, ServiceLocator.class, ServiceName.class, ValueProxy.class,
+      EntityProxyId.class, ExtraTypes.class, InstanceRequest.class, JsonRpcContent.class,
+      JsonRpcProxy.class, JsonRpcService.class, JsonRpcWireName.class, Locator.class,
+      ProxyFor.class, ProxyForName.class, ProxySerializer.class, ProxyStore.class, Receiver.class,
+      Request.class, RequestBatcher.class, RequestContext.class, RequestFactory.class,
+      RequestTransport.class, ServerFailure.class, Service.class, ServiceLocator.class,
+      ServiceName.class, ValueProxy.class,
       com.google.web.bindery.requestfactory.shared.Violation.class, WriteOperation.class,
       RequestFactorySource.class, SimpleEventBus.class};
 
@@ -645,18 +786,20 @@
   private static final int MAX_THREADS = 4;
 
   static {
+    List<Class<?>> aptClasses =
+        Collections.unmodifiableList(Arrays.<Class<?>> asList(RfValidator.class,
+            ValidationTool.class));
     List<Class<?>> sharedClasses = Arrays.<Class<?>> asList(SHARED_CLASSES);
 
     List<Class<?>> clientClasses = new ArrayList<Class<?>>();
     clientClasses.addAll(sharedClasses);
-    clientClasses.add(RfApt.class);
     clientClasses.add(UrlRequestTransport.class);
 
     List<Class<?>> serverClasses = new ArrayList<Class<?>>();
     serverClasses.addAll(Arrays.<Class<?>> asList(SERVER_CLASSES));
     serverClasses.addAll(sharedClasses);
 
-    SEEDS.put("apt", Collections.unmodifiableList(Arrays.<Class<?>> asList(RfApt.class)));
+    SEEDS.put("apt", aptClasses);
     SEEDS.put("client", Collections.unmodifiableList(clientClasses));
     SEEDS.put("server", Collections.unmodifiableList(serverClasses));
 
@@ -676,9 +819,12 @@
      * lookup, since the gwt-user code is compiled separately from its tests.
      */
     try {
-      SEEDS.put("test" + CODE_AND_SOURCE, Collections.unmodifiableList(Arrays.<Class<?>> asList(
-          Class.forName("com.google.web.bindery.requestfactory.vm.RequestFactoryJreSuite"), Class
-              .forName("com.google.web.bindery.requestfactory.server.SimpleBar"))));
+      List<Class<?>> testClasses =
+          Collections.unmodifiableList(Arrays.<Class<?>> asList(Class
+              .forName("com.google.web.bindery.requestfactory.vm.RequestFactoryJreSuite"), Class
+              .forName("com.google.web.bindery.requestfactory.server.SimpleBar")));
+      SEEDS.put("test", testClasses);
+      SEEDS.put("test" + SOURCE_ONLY, testClasses);
     } catch (ClassNotFoundException ignored) {
     }
   }
@@ -699,11 +845,12 @@
       System.err.println("Unknown target: " + target);
       System.exit(1);
     }
-    Map<String, byte[]> resources = createResources(target, seeds);
+    Map<String, byte[]> resources = createResources(seeds);
     Mode mode = Mode.match(target);
     Logger errorContext = Logger.getLogger(RequestFactoryJarExtractor.class.getName());
-    ClassLoaderLoader classLoader =
-        new ClassLoaderLoader(Thread.currentThread().getContextClassLoader());
+    RequestFactoryJarExtractor.ClassLoaderLoader classLoader =
+        new RequestFactoryJarExtractor.ClassLoaderLoader(Thread.currentThread()
+            .getContextClassLoader());
     JarEmitter jarEmitter = new JarEmitter(new File(args[1]));
     RequestFactoryJarExtractor extractor =
         new RequestFactoryJarExtractor(errorContext, classLoader, jarEmitter, seeds, resources,
@@ -712,20 +859,14 @@
     System.exit(extractor.isExecutionFailed() ? 1 : 0);
   }
 
-  private static Map<String, byte[]> createResources(String target, List<Class<?>> seeds)
+  private static Map<String, byte[]> createResources(List<Class<?>> seeds)
       throws UnsupportedEncodingException, IOException {
     Map<String, byte[]> resources;
-    if (seeds.contains(RfApt.class)) {
+    if (seeds.contains(RfValidator.class)) {
       // Add the annotation processor manifest
       resources =
           Collections.singletonMap("META-INF/services/" + Processor.class.getCanonicalName(),
-              RfApt.class.getCanonicalName().getBytes("UTF-8"));
-    } else if (("test" + CODE_AND_SOURCE).equals(target)) {
-      // Combine all type token maps to run tests
-      ByteArrayOutputStream out = new ByteArrayOutputStream();
-      TypeTokenResolver resolver = TypeTokenResolver.loadFromClasspath();
-      resolver.store(out);
-      resources = Collections.singletonMap(TypeTokenResolver.TOKEN_MANIFEST, out.toByteArray());
+              RfValidator.class.getCanonicalName().getBytes("UTF-8"));
     } else {
       resources = Collections.emptyMap();
     }
@@ -746,8 +887,8 @@
    * 
    * @return <code>true</code> if the visitor was successfully visited
    */
-  private static boolean visit(ErrorContext logger, Loader loader, String internalName,
-      ClassVisitor visitor) {
+  private static boolean visit(RequestFactoryJarExtractor.ErrorContext logger,
+      RequestFactoryJarExtractor.Loader loader, String internalName, ClassVisitor visitor) {
     assert Name.isInternalName(internalName) : "internalName";
     logger.spam("Visiting " + internalName);
     InputStream inputStream = null;
@@ -778,8 +919,8 @@
   private final Emitter emitter;
   private final ExecutorService ex;
   private final BlockingQueue<Future<?>> inProcess = new LinkedBlockingQueue<Future<?>>();
-  private final ErrorContext logger;
-  private final Loader loader;
+  private final RequestFactoryJarExtractor.ErrorContext logger;
+  private final RequestFactoryJarExtractor.Loader loader;
   private final Mode mode;
   private final Map<String, byte[]> resources;
   private final List<Class<?>> seeds;
@@ -787,9 +928,9 @@
   private final Set<String> sources = new ConcurrentSkipListSet<String>();
   private final ExecutorService writerService;
 
-  public RequestFactoryJarExtractor(Logger logger, Loader loader, Emitter emitter,
-      List<Class<?>> seeds, Map<String, byte[]> resources, Mode mode) {
-    this.logger = new ErrorContext(logger);
+  public RequestFactoryJarExtractor(Logger logger, RequestFactoryJarExtractor.Loader loader,
+      Emitter emitter, List<Class<?>> seeds, Map<String, byte[]> resources, Mode mode) {
+    this.logger = new RequestFactoryJarExtractor.ErrorContext(logger);
     this.loader = loader;
     this.emitter = emitter;
     this.resources = resources;
diff --git a/user/src/com/google/web/bindery/requestfactory/server/ResolverServiceLayer.java b/user/src/com/google/web/bindery/requestfactory/server/ResolverServiceLayer.java
index e62d8b9..1c602bd 100644
--- a/user/src/com/google/web/bindery/requestfactory/server/ResolverServiceLayer.java
+++ b/user/src/com/google/web/bindery/requestfactory/server/ResolverServiceLayer.java
@@ -24,12 +24,12 @@
 import com.google.web.bindery.requestfactory.shared.RequestFactory;
 import com.google.web.bindery.requestfactory.shared.Service;
 import com.google.web.bindery.requestfactory.shared.ServiceName;
+import com.google.web.bindery.requestfactory.vm.impl.Deobfuscator;
 import com.google.web.bindery.requestfactory.vm.impl.OperationKey;
 
 import java.lang.reflect.Method;
 import java.util.List;
 import java.util.Set;
-import java.util.logging.Logger;
 
 /**
  * Implements all of the resolution methods in ServiceLayer.
@@ -37,24 +37,14 @@
 final class ResolverServiceLayer extends ServiceLayerDecorator {
 
   private static Deobfuscator deobfuscator;
-  private static final Logger log = Logger.getLogger(ServiceLayer.class.getName());
 
-  private static synchronized boolean updateDeobfuscator(ClassLoader classLoader, String binaryName) {
-    RequestFactoryInterfaceValidator validator =
-        new RequestFactoryInterfaceValidator(log,
-            new RequestFactoryInterfaceValidator.ClassLoaderLoader(classLoader));
-    validator.antidote();
-    validator.validateRequestFactory(binaryName);
-    if (validator.isPoisoned()) {
-      return false;
+  private static synchronized void updateDeobfuscator(Class<? extends RequestFactory> clazz,
+      ClassLoader resolveClassesWith) {
+    Deobfuscator.Builder builder = Deobfuscator.Builder.load(clazz, resolveClassesWith);
+    if (deobfuscator != null) {
+      builder.merge(deobfuscator);
     }
-    if (deobfuscator == null) {
-      deobfuscator = validator.getDeobfuscator();
-    } else {
-      deobfuscator =
-          new Deobfuscator.Builder().merge(deobfuscator).merge(validator.getDeobfuscator()).build();
-    }
-    return true;
+    deobfuscator = builder.build();
   }
 
   @Override
@@ -182,10 +172,9 @@
 
   @Override
   public Class<? extends RequestFactory> resolveRequestFactory(String binaryName) {
-    if (!updateDeobfuscator(getTop().getDomainClassLoader(), binaryName)) {
-      die(null, "The RequestFactory %s did not pass validation", binaryName);
-    }
-    return forName(binaryName).asSubclass(RequestFactory.class);
+    Class<? extends RequestFactory> toReturn = forName(binaryName).asSubclass(RequestFactory.class);
+    updateDeobfuscator(toReturn, getTop().getDomainClassLoader());
+    return toReturn;
   }
 
   @Override
diff --git a/user/src/com/google/web/bindery/requestfactory/shared/SkipInterfaceValidation.java b/user/src/com/google/web/bindery/requestfactory/shared/SkipInterfaceValidation.java
index c2b69c1..3bc051d 100644
--- a/user/src/com/google/web/bindery/requestfactory/shared/SkipInterfaceValidation.java
+++ b/user/src/com/google/web/bindery/requestfactory/shared/SkipInterfaceValidation.java
@@ -30,6 +30,6 @@
  */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.METHOD, ElementType.TYPE})
+@Target({ElementType.METHOD, ElementType.PACKAGE, ElementType.TYPE})
 public @interface SkipInterfaceValidation {
 }
diff --git a/user/src/com/google/web/bindery/requestfactory/shared/impl/ProxySerializerImpl.java b/user/src/com/google/web/bindery/requestfactory/shared/impl/ProxySerializerImpl.java
index f13942b..2b523cf 100644
--- a/user/src/com/google/web/bindery/requestfactory/shared/impl/ProxySerializerImpl.java
+++ b/user/src/com/google/web/bindery/requestfactory/shared/impl/ProxySerializerImpl.java
@@ -39,8 +39,7 @@
 /**
  * The default implementation of ProxySerializer.
  */
-class ProxySerializerImpl extends AbstractRequestContext implements
-    ProxySerializer {
+class ProxySerializerImpl extends AbstractRequestContext implements ProxySerializer {
 
   /**
    * Used internally to unwind the stack if data cannot be found in the backing
@@ -55,13 +54,15 @@
    * ValueProxy), we'll assign a synthetic id that is local to the store being
    * used.
    */
-  private final Map<SimpleProxyId<?>, SimpleProxyId<?>> syntheticIds = new HashMap<SimpleProxyId<?>, SimpleProxyId<?>>();
+  private final Map<SimpleProxyId<?>, SimpleProxyId<?>> syntheticIds =
+      new HashMap<SimpleProxyId<?>, SimpleProxyId<?>>();
 
   /**
    * The ids of proxies whose content has been reloaded.
    */
   private final Set<SimpleProxyId<?>> restored = new HashSet<SimpleProxyId<?>>();
-  private final Map<SimpleProxyId<?>, AutoBean<?>> serialized = new HashMap<SimpleProxyId<?>, AutoBean<?>>();
+  private final Map<SimpleProxyId<?>, AutoBean<?>> serialized =
+      new HashMap<SimpleProxyId<?>, AutoBean<?>>();
 
   public ProxySerializerImpl(AbstractRequestFactory factory, ProxyStore store) {
     super(factory, Dialect.STANDARD);
@@ -73,7 +74,7 @@
     if (store.get(key) == null) {
       return null;
     }
-    OperationMessage op = getOperation(proxyType, key);
+    OperationMessage op = getOperation(key);
     @SuppressWarnings("unchecked")
     SimpleProxyId<T> id = (SimpleProxyId<T>) getId(op);
     return doDeserialize(id);
@@ -123,13 +124,12 @@
         }
 
         @Override
-        public void endVisitCollectionProperty(String propertyName,
-            AutoBean<Collection<?>> value, CollectionPropertyContext ctx) {
+        public void endVisitCollectionProperty(String propertyName, AutoBean<Collection<?>> value,
+            CollectionPropertyContext ctx) {
           if (value == null) {
             return;
           }
-          if (isEntityType(ctx.getElementType())
-              || isValueType(ctx.getElementType())) {
+          if (isEntityType(ctx.getElementType()) || isValueType(ctx.getElementType())) {
             for (Object o : value.as()) {
               serialize((BaseProxy) o);
             }
@@ -150,23 +150,20 @@
   SimpleProxyId<BaseProxy> getId(IdMessage op) {
     if (Strength.SYNTHETIC.equals(op.getStrength())) {
       return getRequestFactory().allocateSyntheticId(
-          getRequestFactory().getTypeFromToken(op.getTypeToken()),
-          op.getSyntheticId());
+          getRequestFactory().getTypeFromToken(op.getTypeToken()), op.getSyntheticId());
     }
     return super.getId(op);
   }
 
   @Override
-  <Q extends BaseProxy> AutoBean<Q> getProxyForReturnPayloadGraph(
-      SimpleProxyId<Q> id) {
+  <Q extends BaseProxy> AutoBean<Q> getProxyForReturnPayloadGraph(SimpleProxyId<Q> id) {
     AutoBean<Q> toReturn = super.getProxyForReturnPayloadGraph(id);
     if (restored.add(id)) {
       /*
        * If we haven't seen the id before, use the data in the OperationMessage
        * to repopulate the properties of the canonical bean for this id.
        */
-      OperationMessage op = getOperation(id.getProxyClass(),
-          getRequestFactory().getHistoryToken(id));
+      OperationMessage op = getOperation(getRequestFactory().getHistoryToken(id));
       this.processReturnOperation(id, op);
       toReturn.setTag(Constants.STABLE_ID, super.getId(op));
     }
@@ -196,32 +193,29 @@
    * Load the OperationMessage containing the object state from the backing
    * store.
    */
-  private <T> OperationMessage getOperation(Class<T> proxyType, String key) {
+  private OperationMessage getOperation(String key) {
     Splittable data = store.get(key);
     if (data == null) {
       throw new NoDataException();
     }
 
-    OperationMessage op = AutoBeanCodex.decode(MessageFactoryHolder.FACTORY,
-        OperationMessage.class, data).as();
+    OperationMessage op =
+        AutoBeanCodex.decode(MessageFactoryHolder.FACTORY, OperationMessage.class, data).as();
     return op;
   }
 
   /**
    * Convert any non-persistent ids into store-local synthetic ids.
    */
-  private <T extends BaseProxy> SimpleProxyId<T> serializedId(
-      SimpleProxyId<T> stableId) {
+  private <T extends BaseProxy> SimpleProxyId<T> serializedId(SimpleProxyId<T> stableId) {
     assert !stableId.isSynthetic();
     if (stableId.isEphemeral()) {
       @SuppressWarnings("unchecked")
       SimpleProxyId<T> syntheticId = (SimpleProxyId<T>) syntheticIds.get(stableId);
       if (syntheticId == null) {
         int nextId = store.nextId();
-        assert nextId >= 0 : "ProxyStore.nextId() returned a negative number "
-            + nextId;
-        syntheticId = getRequestFactory().allocateSyntheticId(
-            stableId.getProxyClass(), nextId + 1);
+        assert nextId >= 0 : "ProxyStore.nextId() returned a negative number " + nextId;
+        syntheticId = getRequestFactory().allocateSyntheticId(stableId.getProxyClass(), nextId + 1);
         syntheticIds.put(stableId, syntheticId);
       }
       return syntheticId;
@@ -231,10 +225,9 @@
 
   private void serializeOneProxy(SimpleProxyId<?> idForSerialization,
       AutoBean<? extends BaseProxy> bean) {
-    AutoBean<OperationMessage> op = makeOperationMessage(
-        serializedId(BaseProxyCategory.stableId(bean)), bean, false);
+    AutoBean<OperationMessage> op =
+        makeOperationMessage(serializedId(BaseProxyCategory.stableId(bean)), bean, false);
 
-    store.put(getRequestFactory().getHistoryToken(idForSerialization),
-        AutoBeanCodex.encode(op));
+    store.put(getRequestFactory().getHistoryToken(idForSerialization), AutoBeanCodex.encode(op));
   }
 }
diff --git a/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestContext.java b/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestContext.java
index 6dcedca..86390c8 100644
--- a/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestContext.java
+++ b/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestContext.java
@@ -30,8 +30,8 @@
 import com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext;
 import com.google.web.bindery.requestfactory.shared.impl.RequestData;
 import com.google.web.bindery.requestfactory.shared.impl.SimpleProxyId;
+import com.google.web.bindery.requestfactory.vm.impl.Deobfuscator;
 import com.google.web.bindery.requestfactory.vm.impl.OperationKey;
-import com.google.web.bindery.requestfactory.vm.impl.TypeTokenResolver;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationHandler;
@@ -184,14 +184,14 @@
 
   static final Object[] NO_ARGS = new Object[0];
   private final Class<? extends RequestContext> context;
+  private final Deobfuscator deobfuscator;
   private final Dialect dialect;
-  private final TypeTokenResolver tokenResolver;
 
   protected InProcessRequestContext(InProcessRequestFactory factory, Dialect dialect,
       Class<? extends RequestContext> context) {
     super(factory, dialect);
     this.context = context;
-    this.tokenResolver = factory.getTypeTokenResolver();
+    this.deobfuscator = factory.getDeobfuscator();
     this.dialect = dialect;
   }
 
@@ -205,7 +205,7 @@
   @Override
   protected <T extends BaseProxy> AutoBean<T> createProxy(Class<T> clazz, SimpleProxyId<T> id,
       boolean useAppendedContexts) {
-    if (tokenResolver.isReferencedType(clazz.getName())) {
+    if (deobfuscator.isReferencedType(clazz.getName())) {
       return super.createProxy(clazz, id, useAppendedContexts);
     }
     throw new IllegalArgumentException("Unknown proxy type " + clazz.getName());
diff --git a/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestFactory.java b/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestFactory.java
index fc3802b..05b3f03 100644
--- a/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestFactory.java
+++ b/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestFactory.java
@@ -31,10 +31,9 @@
 import com.google.web.bindery.requestfactory.shared.impl.EntityProxyCategory;
 import com.google.web.bindery.requestfactory.shared.impl.ValueProxyCategory;
 import com.google.web.bindery.requestfactory.vm.InProcessRequestContext.RequestContextHandler;
+import com.google.web.bindery.requestfactory.vm.impl.Deobfuscator;
 import com.google.web.bindery.requestfactory.vm.impl.OperationKey;
-import com.google.web.bindery.requestfactory.vm.impl.TypeTokenResolver;
 
-import java.io.IOException;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -74,15 +73,17 @@
   }
 
   private final Class<? extends RequestFactory> requestFactoryInterface;
-  private final TypeTokenResolver deobfuscator;
+  private final Deobfuscator deobfuscator;
 
   public InProcessRequestFactory(Class<? extends RequestFactory> requestFactoryInterface) {
     this.requestFactoryInterface = requestFactoryInterface;
-    try {
-      deobfuscator = TypeTokenResolver.loadFromClasspath();
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
+    deobfuscator =
+        Deobfuscator.Builder.load(requestFactoryInterface,
+            Thread.currentThread().getContextClassLoader()).build();
+  }
+
+  public Deobfuscator getDeobfuscator() {
+    return deobfuscator;
   }
 
   @Override
@@ -131,8 +132,4 @@
   protected String getTypeToken(Class<? extends BaseProxy> clazz) {
     return isEntityType(clazz) || isValueType(clazz) ? OperationKey.hash(clazz.getName()) : null;
   }
-
-  TypeTokenResolver getTypeTokenResolver() {
-    return deobfuscator;
-  }
 }
diff --git a/user/src/com/google/web/bindery/requestfactory/vm/impl/Deobfuscator.java b/user/src/com/google/web/bindery/requestfactory/vm/impl/Deobfuscator.java
new file mode 100644
index 0000000..5c16de1
--- /dev/null
+++ b/user/src/com/google/web/bindery/requestfactory/vm/impl/Deobfuscator.java
@@ -0,0 +1,188 @@
+/*
+ * 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.web.bindery.requestfactory.vm.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provides access to payload deobfuscation services for server and JVM-based
+ * clients. The deobfuscation data is baked into GWT-based clients by the
+ * generator.
+ */
+public class Deobfuscator {
+  /**
+   * Creates Deobfuscators.
+   */
+  public static class Builder {
+    /**
+     * Load a pre-computed Builder from the classpath. The builder
+     * implementation is expected to have been generated by the annotation
+     * processor as part of the build process.
+     * 
+     * @see com.google.web.bindery.requestfactory.apt.DeobfuscatorBuilder
+     * @see com.google.web.bindery.requestfactory.server.ResolverServiceLayer
+     */
+    public static Builder load(Class<?> clazz, ClassLoader resolveClassesWith) {
+      Throwable ex;
+      try {
+        Class<?> found;
+        try {
+          // Used by the server
+          found = Class.forName(clazz.getName() + GENERATED_SUFFIX, false, resolveClassesWith);
+        } catch (ClassNotFoundException ignored) {
+          // Used by JRE-only clients
+          found = Class.forName(clazz.getName() + GENERATED_SUFFIX_LITE, false, resolveClassesWith);
+        }
+        Class<? extends Builder> builderClass = found.asSubclass(Builder.class);
+        Builder builder = builderClass.newInstance();
+        return builder;
+      } catch (ClassNotFoundException e) {
+        throw new RuntimeException("The RequestFactory ValidationTool must be run for the "
+            + clazz.getCanonicalName() + " RequestFactory type");
+      } catch (InstantiationException e) {
+        ex = e;
+      } catch (IllegalAccessException e) {
+        ex = e;
+      }
+      throw new RuntimeException(ex);
+    }
+
+    private Deobfuscator d = new Deobfuscator();
+
+    {
+      d.domainToClientType = new HashMap<String, List<String>>();
+      d.operationData = new HashMap<OperationKey, OperationData>();
+      d.typeTokens = new HashMap<String, String>();
+    }
+
+    public Deobfuscator build() {
+      Deobfuscator toReturn = d;
+      toReturn.domainToClientType = Collections.unmodifiableMap(toReturn.domainToClientType);
+      toReturn.operationData = Collections.unmodifiableMap(toReturn.operationData);
+      toReturn.referencedTypes =
+          Collections.unmodifiableSet(new HashSet<String>(toReturn.typeTokens.values()));
+      toReturn.typeTokens = Collections.unmodifiableMap(toReturn.typeTokens);
+      d = null;
+      return toReturn;
+    }
+
+    public Builder merge(Deobfuscator existing) {
+      d.domainToClientType.putAll(existing.domainToClientType);
+      d.operationData.putAll(existing.operationData);
+      // referencedTypes recomputed in build()
+      d.typeTokens.putAll(existing.typeTokens);
+      return this;
+    }
+
+    public Builder withClientToDomainMappings(String domainBinaryName, List<String> value) {
+      List<String> clientBinaryNames;
+      switch (value.size()) {
+        case 0:
+          clientBinaryNames = Collections.emptyList();
+          break;
+        case 1:
+          clientBinaryNames = Collections.singletonList(value.get(0));
+          break;
+        default:
+          clientBinaryNames = Collections.unmodifiableList(new ArrayList<String>(value));
+      }
+      d.domainToClientType.put(domainBinaryName, clientBinaryNames);
+      return this;
+    }
+
+    public Builder withOperation(OperationKey key, OperationData data) {
+      d.operationData.put(key, data);
+      return this;
+    }
+
+    public Builder withRawTypeToken(String token, String binaryName) {
+      d.typeTokens.put(token, binaryName);
+      return this;
+    }
+  }
+
+  private static final String GENERATED_SUFFIX = "DeobfuscatorBuilder";
+  private static final String GENERATED_SUFFIX_LITE = GENERATED_SUFFIX + "Lite";
+
+  /**
+   * Maps domain types (e.g Foo) to client proxy types (e.g. FooAProxy,
+   * FooBProxy).
+   */
+  private Map<String, List<String>> domainToClientType;
+  private Map<OperationKey, OperationData> operationData;
+  private Set<String> referencedTypes;
+  /**
+   * Map of obfuscated ids to binary class names.
+   */
+  private Map<String, String> typeTokens;
+
+  Deobfuscator() {
+  }
+
+  /**
+   * Returns the client proxy types whose {@code @ProxyFor} is exactly
+   * {@code binaryTypeName}. Ordered such that the most-derived types will be
+   * iterated over first.
+   */
+  public List<String> getClientProxies(String binaryTypeName) {
+    return domainToClientType.get(binaryTypeName);
+  }
+
+  /**
+   * Returns a method descriptor that should be invoked on the service object.
+   */
+  public String getDomainMethodDescriptor(String operation) {
+    OperationData data = getData(operation);
+    return data == null ? null : data.getDomainMethodDescriptor();
+  }
+
+  public String getRequestContext(String operation) {
+    OperationData data = getData(operation);
+    return data == null ? null : data.getRequestContext();
+  }
+
+  public String getRequestContextMethodDescriptor(String operation) {
+    OperationData data = getData(operation);
+    return data == null ? null : data.getClientMethodDescriptor();
+  }
+
+  public String getRequestContextMethodName(String operation) {
+    OperationData data = getData(operation);
+    return data == null ? null : data.getMethodName();
+  }
+
+  /**
+   * Returns a type's binary name based on an obfuscated token.
+   */
+  public String getTypeFromToken(String token) {
+    return typeTokens.get(token);
+  }
+
+  public boolean isReferencedType(String name) {
+    return referencedTypes.contains(name);
+  }
+
+  private OperationData getData(String operation) {
+    OperationData data = operationData.get(new OperationKey(operation));
+    return data;
+  }
+}
diff --git a/user/src/com/google/web/bindery/requestfactory/server/OperationData.java b/user/src/com/google/web/bindery/requestfactory/vm/impl/OperationData.java
similarity index 87%
rename from user/src/com/google/web/bindery/requestfactory/server/OperationData.java
rename to user/src/com/google/web/bindery/requestfactory/vm/impl/OperationData.java
index 09a2aa6..04225bf 100644
--- a/user/src/com/google/web/bindery/requestfactory/server/OperationData.java
+++ b/user/src/com/google/web/bindery/requestfactory/vm/impl/OperationData.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.web.bindery.requestfactory.server;
+package com.google.web.bindery.requestfactory.vm.impl;
 
 import com.google.gwt.dev.asm.Type;
 import com.google.gwt.dev.asm.commons.Method;
@@ -21,7 +21,7 @@
 /**
  * Describes operations that the client may ask the server to perform.
  */
-class OperationData {
+public class OperationData {
   /**
    * Creates {@link OperationData} instances.
    */
@@ -49,22 +49,22 @@
       return toReturn;
     }
 
-    public Builder setClientMethodDescriptor(String clientMethodDescriptor) {
+    public Builder withClientMethodDescriptor(String clientMethodDescriptor) {
       d.clientMethodDescriptor = clientMethodDescriptor;
       return this;
     }
 
-    public Builder setDomainMethodDescriptor(String domainMethodDescriptor) {
+    public Builder withDomainMethodDescriptor(String domainMethodDescriptor) {
       d.domainMethodDescriptor = domainMethodDescriptor;
       return this;
     }
 
-    public Builder setMethodName(String methodName) {
+    public Builder withMethodName(String methodName) {
       d.methodName = methodName;
       return this;
     }
 
-    public Builder setRequestContext(String requestContext) {
+    public Builder withRequestContext(String requestContext) {
       d.requestContextBinaryName = requestContext;
       return this;
     }
diff --git a/user/src/com/google/web/bindery/requestfactory/vm/impl/TypeTokenResolver.java b/user/src/com/google/web/bindery/requestfactory/vm/impl/TypeTokenResolver.java
deleted file mode 100644
index 5699c9a..0000000
--- a/user/src/com/google/web/bindery/requestfactory/vm/impl/TypeTokenResolver.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * 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.web.bindery.requestfactory.vm.impl;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-/**
- * Resolves payload type tokens to binary class names.
- */
-public class TypeTokenResolver {
-  /**
-   * Constructs {@link TypeTokenResolver} instances.
-   */
-  public static class Builder {
-    private TypeTokenResolver d = new TypeTokenResolver();
-
-    /**
-     * To be removed as well.
-     */
-    public Builder addTypeToken(String token, String binaryName) {
-      d.typeTokens.put(token, binaryName);
-      return this;
-    }
-
-    public TypeTokenResolver build() {
-      TypeTokenResolver toReturn = d;
-      toReturn.typeTokens = Collections.unmodifiableMap(toReturn.typeTokens);
-      toReturn.referencedTypes =
-          Collections.unmodifiableSet(new HashSet<String>(toReturn.typeTokens.values()));
-      d = null;
-      return toReturn;
-    }
-
-    /**
-     * Adds data from a single InputStream to the state accumulated by the
-     * Builder.
-     */
-    public void load(InputStream in) throws IOException {
-      Properties props = new Properties();
-      props.load(in);
-      for (Map.Entry<Object, Object> entry : props.entrySet()) {
-        addTypeToken(entry.getKey().toString(), entry.getValue().toString());
-      }
-      in.close();
-    }
-  }
-
-  public static final String TOKEN_MANIFEST = "META-INF/requestFactory/typeTokens";
-
-  /**
-   * Loads all resources on path {@value #TOKEN_MANIFEST} and creates a
-   * TypeTokenResolver.
-   */
-  public static TypeTokenResolver loadFromClasspath() throws IOException {
-    Builder builder;
-    boolean mustLoad = true;
-    try {
-      // Look for a pre-cooked Builder type
-      Class<?> maybeBuilderImpl =
-          Class.forName(TypeTokenResolver.class.getName() + "BuilderImpl", false, Thread
-              .currentThread().getContextClassLoader());
-      builder = maybeBuilderImpl.asSubclass(Builder.class).newInstance();
-      mustLoad = false;
-    } catch (ClassNotFoundException ignored) {
-      // Try manifest-based approach
-      builder = new Builder();
-    } catch (InstantiationException e) {
-      throw new RuntimeException("Could not instantiate TypeTokenResolverImpl", e);
-    } catch (IllegalAccessException e) {
-      throw new RuntimeException("Could not instantiate TypeTokenResolverImpl", e);
-    }
-    Enumeration<URL> locations =
-        Thread.currentThread().getContextClassLoader().getResources(TOKEN_MANIFEST);
-    if (mustLoad && !locations.hasMoreElements()) {
-      throw new RuntimeException("No token manifest found.  Did the RequestFactory annotation"
-          + " processor run? Check classpath for " + TOKEN_MANIFEST + " file and ensure that"
-          + " your proxy types are compiled with the requestfactory-apt.jar on javac's classpath.");
-    }
-    while (locations.hasMoreElements()) {
-      builder.load(locations.nextElement().openStream());
-    }
-    return builder.build();
-  }
-
-  /**
-   * The values of {@link #typeTokens}.
-   */
-  private Set<String> referencedTypes;
-
-  /**
-   * Map of obfuscated ids to binary class names.
-   */
-  private Map<String, String> typeTokens = new HashMap<String, String>();
-
-  public SortedMap<String, String> getAllTypeTokens() {
-    return new TreeMap<String, String>(typeTokens);
-  }
-
-  public String getTypeFromToken(String typeToken) {
-    return typeTokens.get(typeToken);
-  }
-
-  public boolean isReferencedType(String binaryName) {
-    return referencedTypes.contains(binaryName);
-  }
-
-  /**
-   * Closes the OutputStream.
-   */
-  public void store(OutputStream out) throws IOException {
-    Properties props = new Properties();
-    props.putAll(typeTokens);
-    props.store(out, "GENERATED FILE -- DO NOT EDIT");
-    out.close();
-  }
-}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/DiagnosticComparator.java b/user/test/com/google/web/bindery/requestfactory/apt/DiagnosticComparator.java
new file mode 100644
index 0000000..80b1938
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/DiagnosticComparator.java
@@ -0,0 +1,43 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.util.Comparator;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+/**
+ * Orders Diagnostic objects by filename, position, and message.
+ */
+class DiagnosticComparator implements Comparator<Diagnostic<? extends JavaFileObject>> {
+  @Override
+  public int compare(Diagnostic<? extends JavaFileObject> o1,
+      Diagnostic<? extends JavaFileObject> o2) {
+    int c;
+    if (o1.getSource() != null && o2.getSource() != null) {
+      c = o1.getSource().toUri().toString().compareTo(o2.getSource().toUri().toString());
+      if (c != 0) {
+        return c;
+      }
+    }
+    long p = o1.getPosition() - o2.getPosition();
+    if (p != 0) {
+      return Long.signum(p);
+    }
+    return o1.getMessage(null).compareTo(o2.getMessage(null));
+  }
+}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyCheckDomainMapping.java b/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyCheckDomainMapping.java
new file mode 100644
index 0000000..6a1ee98
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyCheckDomainMapping.java
@@ -0,0 +1,70 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.EntityProxy;
+import com.google.web.bindery.requestfactory.shared.ProxyFor;
+
+@Expected({
+    @Expect(method = "domainGetIdStatic"),
+    @Expect(method = "domainGetVersionStatic"),
+    @Expect(method = "domainFindNotStatic", args = "Domain"),
+    @Expect(method = "domainMethodWrongModifier", args = {"false", "getFoo"}),
+    @Expect(method = "domainNoDefaultConstructor", args = {
+        "Domain", "EntityProxyCheckDomainMapping", "RequestContext"}, warning = true)})
+@ProxyFor(EntityProxyCheckDomainMapping.Domain.class)
+@SuppressWarnings("requestfactory")
+interface EntityProxyCheckDomainMapping extends EntityProxy {
+  public static class Domain {
+    public static String getFoo() {
+      return null;
+    }
+
+    public static String getId() {
+      return null;
+    }
+
+    public static String getVersion() {
+      return null;
+    }
+
+    public Domain(@SuppressWarnings("unused") boolean ignored) {
+    }
+
+    public Domain findDomain(@SuppressWarnings("unused") String id) {
+      return null;
+    }
+  }
+
+  String getFoo();
+
+  @Expect(method = "domainMissingMethod", args = "java.lang.String getMissingProperty()")
+  String getMissingProperty();
+
+  @Expected({
+      @Expect(method = "methodNoDomainPeer", args = {"java.lang.Object", "false"}, warning = true),
+      @Expect(method = "untransportableType", args = "java.lang.Object")})
+  Object getUntransportable();
+
+  @Expect(method = "methodNoDomainPeer", args = {"java.lang.Object", "true"}, warning = true)
+  void setUntransportable(
+      @Expect(method = "untransportableType", args = "java.lang.Object") Object obj);
+
+  @Expected({
+      @Expect(method = "proxyOnlyGettersSetters"),
+      @Expect(method = "domainMissingMethod", args = "java.lang.String notAProperty()")})
+  String notAProperty();
+}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyMismatchedFind.java b/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyMismatchedFind.java
new file mode 100644
index 0000000..ad943b8
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyMismatchedFind.java
@@ -0,0 +1,40 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.EntityProxy;
+import com.google.web.bindery.requestfactory.shared.ProxyFor;
+
+@Expect(method = "domainMissingFind", args = {
+    "com.google.web.bindery.requestfactory.apt.EntityProxyMismatchedFind.Domain", "Domain",
+    "java.lang.String", "EntityProxyMismatchedFind"}, warning = true)
+@ProxyFor(EntityProxyMismatchedFind.Domain.class)
+@SuppressWarnings("requestfactory")
+interface EntityProxyMismatchedFind extends EntityProxy {
+  public static class Domain {
+    public static Domain findDomain(@SuppressWarnings("unused") Integer id) {
+      return null;
+    }
+
+    public String getId() {
+      return null;
+    }
+
+    public String getVersion() {
+      return null;
+    }
+  }
+}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyMissingDomainLocatorMethods.java b/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyMissingDomainLocatorMethods.java
new file mode 100644
index 0000000..a222e01
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyMissingDomainLocatorMethods.java
@@ -0,0 +1,28 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.EntityProxy;
+import com.google.web.bindery.requestfactory.shared.ProxyFor;
+
+@Expected({
+    @Expect(method = "domainNoGetId", args = "com.google.web.bindery.requestfactory.apt.EntityProxyMissingDomainLocatorMethods.Domain"),
+    @Expect(method = "domainNoGetVersion", args = "com.google.web.bindery.requestfactory.apt.EntityProxyMissingDomainLocatorMethods.Domain")})
+@ProxyFor(EntityProxyMissingDomainLocatorMethods.Domain.class)
+interface EntityProxyMissingDomainLocatorMethods extends EntityProxy {
+  public static class Domain {
+  }
+}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyMissingDomainType.java b/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyMissingDomainType.java
new file mode 100644
index 0000000..2282bc8
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/EntityProxyMissingDomainType.java
@@ -0,0 +1,24 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.EntityProxy;
+import com.google.web.bindery.requestfactory.shared.ProxyForName;
+
+@Expect(method = "proxyMissingDomainType", args = "does.not.exist", warning = true)
+@ProxyForName("does.not.exist")
+interface EntityProxyMissingDomainType extends EntityProxy {
+}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/Expect.java b/user/test/com/google/web/bindery/requestfactory/apt/Expect.java
new file mode 100644
index 0000000..953b2b5
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/Expect.java
@@ -0,0 +1,43 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This annotation is applied to any element that is expected to be the target
+ * of an error or a warning from the validator.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@interface Expect {
+  /**
+   * The arguments to be passed to {@code method}.
+   */
+  String[] args() default {};
+
+  /**
+   * The name of a method defined in {@link Messages}.
+   */
+  String method();
+
+  /**
+   * Specifies whether the diagnostic will be a warning or an error.
+   */
+  boolean warning() default false;
+}
\ No newline at end of file
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/ExpectCollector.java b/user/test/com/google/web/bindery/requestfactory/apt/ExpectCollector.java
new file mode 100644
index 0000000..31f7cde
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/ExpectCollector.java
@@ -0,0 +1,115 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementScanner6;
+import javax.tools.Diagnostic.Kind;
+
+/**
+ * This is a trivial scanner that collects {@code @Expect} declarations on a
+ * type. It does not perform any type-chasing or supertype traversal. The named
+ * method on the {@link Messages} class is invoked with the provided arguments
+ * and the resulting message is emitted to the {@link Messager}.
+ */
+@SupportedAnnotationTypes({
+    "com.google.web.bindery.requestfactory.apt.Expect",
+    "com.google.web.bindery.requestfactory.apt.Expected"})
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+class ExpectCollector extends AbstractProcessor {
+  class Scanner extends ElementScanner6<Void, Void> {
+
+    private final Messager messager;
+
+    public Scanner(Messager messager) {
+      this.messager = messager;
+    }
+
+    @Override
+    public Void scan(Element e, Void p) {
+      Expect expect = e.getAnnotation(Expect.class);
+      if (expect != null) {
+        addExpect(expect, e);
+      }
+      Expected expected = e.getAnnotation(Expected.class);
+      if (expected != null) {
+        for (Expect v : expected.value()) {
+          addExpect(v, e);
+        }
+      }
+      return super.scan(e, p);
+    }
+
+    private void addExpect(Expect expect, Element accumulator) {
+      Method toInvoke = null;
+      for (Method m : Messages.class.getDeclaredMethods()) {
+        if (m.getName().equals(expect.method())) {
+          toInvoke = m;
+          break;
+        }
+      }
+      if (toInvoke == null) {
+        throw new RuntimeException("No method named " + expect.method());
+      }
+      String[] originalArgs = expect.args();
+      Object[] args = new Object[originalArgs.length];
+      for (int i = 0, j = args.length; i < j; i++) {
+        // Special case for domainMethodWrongModifier
+        if (boolean.class.equals(toInvoke.getParameterTypes()[i])) {
+          args[i] = Boolean.valueOf(originalArgs[i]);
+        } else {
+          args[i] = originalArgs[i];
+        }
+      }
+      String message;
+      Throwable ex;
+      try {
+        message = (String) toInvoke.invoke(null, args);
+        if (expect.warning()) {
+          message += Messages.warnSuffix();
+        }
+        messager.printMessage(expect.warning() ? Kind.WARNING : Kind.ERROR, message, accumulator);
+        return;
+      } catch (IllegalArgumentException e) {
+        ex = e;
+      } catch (IllegalAccessException e) {
+        ex = e;
+      } catch (InvocationTargetException e) {
+        ex = e.getCause();
+      }
+      throw new RuntimeException("Could not get test message", ex);
+    }
+  }
+
+  @Override
+  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    Scanner scanner = new Scanner(processingEnv.getMessager());
+    scanner.scan(roundEnv.getElementsAnnotatedWith(Expect.class), null);
+    scanner.scan(roundEnv.getElementsAnnotatedWith(Expected.class), null);
+    return false;
+  }
+}
\ No newline at end of file
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/Expected.java b/user/test/com/google/web/bindery/requestfactory/apt/Expected.java
new file mode 100644
index 0000000..5e73483
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/Expected.java
@@ -0,0 +1,27 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Allows several {@link Expect} annotations to be applied to an element.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@interface Expected {
+  Expect[] value();
+}
\ No newline at end of file
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/MyRequestContext.java b/user/test/com/google/web/bindery/requestfactory/apt/MyRequestContext.java
new file mode 100644
index 0000000..7f6b579
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/MyRequestContext.java
@@ -0,0 +1,75 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.EntityProxy;
+import com.google.web.bindery.requestfactory.shared.InstanceRequest;
+import com.google.web.bindery.requestfactory.shared.JsonRpcProxy;
+import com.google.web.bindery.requestfactory.shared.ProxyFor;
+import com.google.web.bindery.requestfactory.shared.ProxyForName;
+import com.google.web.bindery.requestfactory.shared.Request;
+import com.google.web.bindery.requestfactory.shared.RequestContext;
+import com.google.web.bindery.requestfactory.shared.ValueProxy;
+
+/*
+ * No error about a missing mapping expected because this type isn't referenced
+ * from a RequestFactory.
+ */
+interface MyRequestContext extends RequestContext {
+  @Expect(method = "proxyMustBeAnnotated", args = "ProxyMissingAnnotation")
+  interface ProxyMissingAnnotation extends EntityProxy {
+  }
+
+  @Expected({
+      @Expect(method = "proxyMissingDomainType", args = "bad", warning = true),
+      @Expect(method = "redundantAnnotation", args = "ProxyForName"),
+      @Expect(method = "redundantAnnotation", args = "JsonRpcProxy")})
+  @ProxyFor(ProxyWithRedundantAnnotations.Domain.class)
+  @ProxyForName("bad")
+  @JsonRpcProxy
+  interface ProxyWithRedundantAnnotations extends ValueProxy {
+    static class Domain {
+    }
+  }
+
+  /**
+   * Because this is not referenced from the context, it shouldn't generate an
+   * error.
+   */
+  interface UnusedProxyBase extends EntityProxy {
+  }
+
+  @Expect(method = "untransportableType", args = "java.lang.Object")
+  InstanceRequest<ProxyWithRedundantAnnotations, Object> badInstanceReturn();
+
+  @Expect(method = "contextRequiredReturnTypes", args = {"Request", "InstanceRequest"})
+  String badMethod();
+
+  Request<Void> badParam(@Expect(method = "untransportableType", args = "java.lang.Object") Object o);
+
+  @Expect(method = "untransportableType", args = "java.lang.Object")
+  Request<Object> badReturn();
+
+  Request<ProxyMissingAnnotation> forceAnnotation();
+
+  @Expect(method = "rawType")
+  @SuppressWarnings("rawtypes")
+  InstanceRequest rawInstance();
+
+  @Expect(method = "rawType")
+  @SuppressWarnings("rawtypes")
+  Request rawRequest();
+}
\ No newline at end of file
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/MyRequestFactory.java b/user/test/com/google/web/bindery/requestfactory/apt/MyRequestFactory.java
new file mode 100644
index 0000000..e5444c3
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/MyRequestFactory.java
@@ -0,0 +1,53 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.JsonRpcService;
+import com.google.web.bindery.requestfactory.shared.RequestContext;
+import com.google.web.bindery.requestfactory.shared.RequestFactory;
+import com.google.web.bindery.requestfactory.shared.Service;
+import com.google.web.bindery.requestfactory.shared.ServiceName;
+import com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext;
+
+interface MyRequestFactory extends RequestFactory {
+
+  @Expect(method = "contextMustBeAnnotated", args = "ReferencedContextWithoutMapping")
+  interface ReferencedContextWithoutMapping extends RequestContext {
+  }
+
+  // No error expected
+  interface UnreferencedContextWithoutMapping extends RequestContext {
+  }
+
+  @Expected({
+      @Expect(method = "redundantAnnotation", args = "ServiceName"),
+      @Expect(method = "redundantAnnotation", args = "JsonRpcService")})
+  @Service(Object.class)
+  @ServiceName("java.lang.Object")
+  @JsonRpcService
+  interface UnreferencedContextWithRedundantMapping extends RequestContext {
+  }
+
+  @Expect(method = "factoryMustReturnInterface", args = "AbstractRequestContext")
+  AbstractRequestContext concreteContext();
+
+  ReferencedContextWithoutMapping shouldError();
+
+  @Expected({
+      @Expect(method = "factoryNoMethodParameters"),
+      @Expect(method = "factoryMustBeAssignable", args = "RequestContext")})
+  String stringMethod(String bad);
+}
\ No newline at end of file
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/RequestContextMissingDomainType.java b/user/test/com/google/web/bindery/requestfactory/apt/RequestContextMissingDomainType.java
new file mode 100644
index 0000000..57de96a
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/RequestContextMissingDomainType.java
@@ -0,0 +1,24 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.RequestContext;
+import com.google.web.bindery.requestfactory.shared.ServiceName;
+
+@Expect(method = "contextMissingDomainType", args = "does.not.exist", warning = true)
+@ServiceName("does.not.exist")
+interface RequestContextMissingDomainType extends RequestContext {
+}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/RequestContextUsingUnmappedProxy.java b/user/test/com/google/web/bindery/requestfactory/apt/RequestContextUsingUnmappedProxy.java
new file mode 100644
index 0000000..ddb0efd
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/RequestContextUsingUnmappedProxy.java
@@ -0,0 +1,33 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.Request;
+import com.google.web.bindery.requestfactory.shared.RequestContext;
+import com.google.web.bindery.requestfactory.shared.Service;
+
+@Service(RequestContextUsingUnmappedProxy.Domain.class)
+interface RequestContextUsingUnmappedProxy extends RequestContext {
+  public static class Domain {
+  }
+
+  @Expected({
+      @Expect(method = "methodNoDomainPeer", args = {
+          "com.google.web.bindery.requestfactory.apt.EntityProxyMissingDomainType", "false"}, warning = true),
+      @Expect(method = "methodNoDomainPeer", args = {
+          "com.google.web.bindery.requestfactory.apt.EntityProxyMissingDomainType", "true"}, warning = true)})
+  Request<EntityProxyMissingDomainType> cannotVerify(EntityProxyMissingDomainType proxy);
+}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/RequestContextWithMismatchedBoxes.java b/user/test/com/google/web/bindery/requestfactory/apt/RequestContextWithMismatchedBoxes.java
new file mode 100644
index 0000000..ee854aa
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/RequestContextWithMismatchedBoxes.java
@@ -0,0 +1,60 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.ProxyFor;
+import com.google.web.bindery.requestfactory.shared.Request;
+import com.google.web.bindery.requestfactory.shared.RequestContext;
+import com.google.web.bindery.requestfactory.shared.Service;
+import com.google.web.bindery.requestfactory.shared.ValueProxy;
+
+/**
+ * Checks that proxy property accessors match exactly and that context method
+ * arguments must match exactly.
+ */
+@Service(RequestContextWithMismatchedBoxes.Domain.class)
+interface RequestContextWithMismatchedBoxes extends RequestContext {
+  @Expect(method = "domainMissingMethod", args = "java.lang.Void checkBoxed(int)")
+  Request<Void> checkBoxed(int value);
+
+  @Expect(method = "domainMissingMethod", args = "java.lang.Void checkPrimitive(java.lang.Integer)")
+  Request<Void> checkPrimitive(Integer value);
+
+  @ProxyFor(Domain.class)
+  interface ProxyMismatchedGetterA extends ValueProxy {
+    @Expect(method = "domainMissingMethod", args = "int getBoxed()")
+    int getBoxed();
+
+    @Expect(method = "domainMissingMethod", args = "java.lang.Integer getPrimitive()")
+    Integer getPrimitive();
+  }
+
+  static class Domain {
+    static void checkBoxed(@SuppressWarnings("unused") Integer value) {
+    }
+
+    static void checkPrimitive(@SuppressWarnings("unused") int value) {
+    }
+
+    Integer getBoxed() {
+      return null;
+    }
+
+    int getPrimitive() {
+      return 0;
+    }
+  }
+}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/RequestContextWithMismatchedInstance.java b/user/test/com/google/web/bindery/requestfactory/apt/RequestContextWithMismatchedInstance.java
new file mode 100644
index 0000000..26c428d
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/RequestContextWithMismatchedInstance.java
@@ -0,0 +1,61 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.EntityProxy;
+import com.google.web.bindery.requestfactory.shared.InstanceRequest;
+import com.google.web.bindery.requestfactory.shared.ProxyFor;
+import com.google.web.bindery.requestfactory.shared.Request;
+import com.google.web.bindery.requestfactory.shared.RequestContext;
+import com.google.web.bindery.requestfactory.shared.Service;
+
+/**
+ * Tests Request and InstanceRequest methods bound to methods with the wrong
+ * static modifier.
+ */
+@Expected({
+    @Expect(method = "domainMethodWrongModifier", args = {"true", "instanceMethod"}),
+    @Expect(method = "domainMethodWrongModifier", args = {"false", "staticMethod"})})
+@Service(RequestContextWithMismatchedInstance.Domain.class)
+interface RequestContextWithMismatchedInstance extends RequestContext {
+  static class Domain {
+    public static Domain findDomain(@SuppressWarnings("unused") String id) {
+      return null;
+    }
+
+    public static void staticMethod() {
+    }
+
+    public String getId() {
+      return null;
+    }
+
+    public String getVersion() {
+      return null;
+    }
+
+    public void instanceMethod() {
+    }
+  }
+
+  @ProxyFor(Domain.class)
+  interface Proxy extends EntityProxy {
+  }
+
+  Request<Void> instanceMethod();
+
+  InstanceRequest<Proxy, Void> staticMethod();
+}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/RfValidatorTest.java b/user/test/com/google/web/bindery/requestfactory/apt/RfValidatorTest.java
new file mode 100644
index 0000000..a6c3ec7
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/RfValidatorTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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.web.bindery.requestfactory.apt;
+
+import com.google.gwt.dev.util.Util;
+import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryPolymorphicTest;
+import com.google.web.bindery.requestfactory.shared.LoggingRequest;
+import com.google.web.bindery.requestfactory.shared.SimpleRequestFactory;
+import com.google.web.bindery.requestfactory.shared.TestRequestFactory;
+import com.google.web.bindery.requestfactory.shared.impl.FindRequest;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.TreeSet;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+/**
+ * Integration test of {@link RfValidator} using the Java6 tools API to invoke
+ * the Java compiler. This test requires that the gwt-user source is available
+ * on the classpath.
+ */
+public class RfValidatorTest extends TestCase {
+  /**
+   * Provides access to a source file from the classpath.
+   */
+  private static class UriJavaFileObject extends SimpleJavaFileObject {
+    public static UriJavaFileObject create(Class<?> toLoad) {
+      try {
+        String path = toLoad.getName().replace('.', '/') + ".java";
+        /*
+         * SimpleJavaFileObject does not like the URI's created from jar URLs
+         * since their path does not start with a leading forward-slash. The
+         * choice of "classpath" as the scheme is arbitrary and meaningless.
+         */
+        URI fakeLocation = new URI("classpath:/" + path);
+        return new UriJavaFileObject(fakeLocation, Thread.currentThread().getContextClassLoader()
+            .getResource(path));
+      } catch (URISyntaxException e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+    private final URL contents;
+
+    public UriJavaFileObject(URI fakeLocation, URL contents) throws URISyntaxException {
+      super(fakeLocation, JavaFileObject.Kind.SOURCE);
+      this.contents = contents;
+    }
+
+    @Override
+    public CharSequence getCharContent(boolean ignored) throws IOException {
+      return Util.readStreamAsString(contents.openStream());
+    }
+  }
+
+  /**
+   * Smoke test to ensure that appropriate errors and warnings are emitted.
+   */
+  public void testErrorsAndWarnings() throws IOException {
+    testGeneratedMessages(EntityProxyCheckDomainMapping.class);
+    testGeneratedMessages(EntityProxyMismatchedFind.class);
+    testGeneratedMessages(EntityProxyMissingDomainLocatorMethods.class);
+    testGeneratedMessages(EntityProxyMissingDomainType.class);
+    testGeneratedMessages(MyRequestContext.class);
+    testGeneratedMessages(MyRequestFactory.class);
+    testGeneratedMessages(RequestContextMissingDomainType.class);
+    testGeneratedMessages(RequestContextUsingUnmappedProxy.class,
+        EntityProxyMissingDomainType.class);
+    testGeneratedMessages(RequestContextWithMismatchedBoxes.class);
+    testGeneratedMessages(RequestContextWithMismatchedInstance.class);
+  }
+
+  /**
+   * The target classes for this method don't contain any {@code @Expect}
+   * annotations, so this test will verify that they are error- and
+   * warning-free.
+   */
+  public void testTestClasses() throws IOException {
+    testGeneratedMessages(RequestFactoryPolymorphicTest.class);
+    testGeneratedMessages(FindRequest.class);
+    testGeneratedMessages(LoggingRequest.class);
+    testGeneratedMessages(SimpleRequestFactory.class);
+    testGeneratedMessages(TestRequestFactory.class);
+  }
+
+  /**
+   * The target classes for this method don't contain any {@code @Expect}
+   * annotations, so this test will verify that they are error- and
+   * warning-free.
+   * 
+   * @throws IOException
+   */
+  public void testTestClassesClientOnly() throws IOException {
+    testGeneratedMessages(true, RequestFactoryPolymorphicTest.class);
+    testGeneratedMessages(true, FindRequest.class);
+    testGeneratedMessages(true, LoggingRequest.class);
+    testGeneratedMessages(true, SimpleRequestFactory.class);
+    testGeneratedMessages(true, TestRequestFactory.class);
+  }
+
+  private void assertEquals(TreeSet<Diagnostic<? extends JavaFileObject>> expected,
+      TreeSet<Diagnostic<? extends JavaFileObject>> actual) {
+    List<Diagnostic<?>> unmatched = new ArrayList<Diagnostic<?>>();
+
+    // Remove actual elements from expect, saving any unexpected elements
+    for (Diagnostic<? extends JavaFileObject> d : actual) {
+      if (!expected.remove(d)) {
+        unmatched.add(d);
+      }
+    }
+
+    assertTrue("Did not see expected errors: " + expected + "\n\nLeftovers :" + unmatched, expected
+        .isEmpty());
+    assertTrue("Unexpected errors: " + unmatched, unmatched.isEmpty());
+  }
+
+  private void testGeneratedMessages(Class<?>... classes) throws IOException {
+    testGeneratedMessages(false, classes);
+  }
+
+  /**
+   * Run the annotation processor over one or more classes and verify that the
+   * appropriate messages are generated.
+   */
+  private void testGeneratedMessages(boolean clientOnly, Class<?>... classes) throws IOException {
+    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+    if (compiler == null) {
+      // This test is being run without a full JDK
+      return;
+    }
+
+    // Don't spray files in random locations
+    File tempFile = File.createTempFile(RfValidatorTest.class.getSimpleName(), ".jar");
+    tempFile.deleteOnExit();
+    JavaFileManager fileManager =
+        new ValidationTool.JarOrDirectoryOutputFileManager(tempFile, compiler
+            .getStandardFileManager(null, null, null));
+
+    List<JavaFileObject> files = new ArrayList<JavaFileObject>(classes.length);
+    for (Class<?> clazz : classes) {
+      JavaFileObject obj = UriJavaFileObject.create(clazz);
+      files.add(obj);
+    }
+    StringWriter errorWriter = new StringWriter();
+    RfValidator rfValidator = new RfValidator();
+    rfValidator.setForceErrors(true);
+    rfValidator.setClientOnly(clientOnly);
+
+    DiagnosticCollector<JavaFileObject> expectedCollector =
+        new DiagnosticCollector<JavaFileObject>();
+    CompilationTask expectedTask =
+        compiler.getTask(errorWriter, fileManager, expectedCollector, Arrays.asList("-proc:only"),
+            null, files);
+    expectedTask.setProcessors(Arrays.asList(new ExpectCollector()));
+    expectedTask.call();
+
+    DiagnosticCollector<JavaFileObject> actualCollector = new DiagnosticCollector<JavaFileObject>();
+    CompilationTask actualTask =
+        compiler.getTask(errorWriter, fileManager, actualCollector, Arrays.asList("-proc:only"),
+            null, files);
+    actualTask.setProcessors(Arrays.asList(rfValidator));
+    actualTask.call();
+
+    TreeSet<Diagnostic<? extends JavaFileObject>> expected =
+        new TreeSet<Diagnostic<? extends JavaFileObject>>(new DiagnosticComparator());
+    expected.addAll(expectedCollector.getDiagnostics());
+    TreeSet<Diagnostic<? extends JavaFileObject>> actual =
+        new TreeSet<Diagnostic<? extends JavaFileObject>>(new DiagnosticComparator());
+    actual.addAll(actualCollector.getDiagnostics());
+    assertEquals(expected, actual);
+  }
+}
diff --git a/user/test/com/google/web/bindery/requestfactory/apt/package-info.java b/user/test/com/google/web/bindery/requestfactory/apt/package-info.java
new file mode 100644
index 0000000..d2eab38
--- /dev/null
+++ b/user/test/com/google/web/bindery/requestfactory/apt/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+/**
+ * By disabling the following annotation, a manual check can be made against the
+ * various {@link Expect} annotations and the IDE's behavior.
+ */
+@SkipInterfaceValidation
+package com.google.web.bindery.requestfactory.apt;
+
+import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation;
+
diff --git a/user/test/com/google/web/bindery/requestfactory/gwt/RequestFactoryGwtJreSuite.java b/user/test/com/google/web/bindery/requestfactory/gwt/RequestFactoryGwtJreSuite.java
index 5a2f008..2505961 100644
--- a/user/test/com/google/web/bindery/requestfactory/gwt/RequestFactoryGwtJreSuite.java
+++ b/user/test/com/google/web/bindery/requestfactory/gwt/RequestFactoryGwtJreSuite.java
@@ -15,6 +15,7 @@
  */
 package com.google.web.bindery.requestfactory.gwt;
 
+import com.google.web.bindery.requestfactory.apt.RfValidatorTest;
 import com.google.web.bindery.requestfactory.gwt.rebind.model.RequestFactoryModelTest;
 
 import junit.framework.Test;
@@ -33,6 +34,7 @@
     TestSuite suite = new TestSuite(
         "requestfactory package tests that require the JRE and gwt-user");
     suite.addTestSuite(RequestFactoryModelTest.class);
+    suite.addTestSuite(RfValidatorTest.class);
 
     return suite;
   }
diff --git a/user/test/com/google/web/bindery/requestfactory/server/BoxesAndPrimitivesJreTest.java b/user/test/com/google/web/bindery/requestfactory/server/BoxesAndPrimitivesJreTest.java
index 7ba01ad..fb15660 100644
--- a/user/test/com/google/web/bindery/requestfactory/server/BoxesAndPrimitivesJreTest.java
+++ b/user/test/com/google/web/bindery/requestfactory/server/BoxesAndPrimitivesJreTest.java
@@ -15,111 +15,20 @@
  */
 package com.google.web.bindery.requestfactory.server;
 
-import com.google.gwt.dev.asm.Type;
-import com.google.gwt.dev.asm.commons.Method;
-import com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidatorTest.VisibleErrorContext;
 import com.google.web.bindery.requestfactory.shared.BoxesAndPrimitivesTest;
-import com.google.web.bindery.requestfactory.shared.EntityProxy;
-import com.google.web.bindery.requestfactory.shared.ProxyFor;
-import com.google.web.bindery.requestfactory.shared.Request;
-import com.google.web.bindery.requestfactory.shared.RequestContext;
-import com.google.web.bindery.requestfactory.shared.Service;
-import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation;
-
-import java.util.Arrays;
-import java.util.logging.Logger;
 
 /**
- * A JRE version of {@link BoxesAndPrimitivesTest} with additional validation
- * tests.
+ * A JRE version of {@link BoxesAndPrimitivesTest}.
  */
-@SkipInterfaceValidation
 public class BoxesAndPrimitivesJreTest extends BoxesAndPrimitivesTest {
 
-  @Service(ServiceImpl.class)
-  interface ContextMismatchedParameterA extends RequestContext {
-    Request<Void> checkBoxed(int value);
-  }
-
-  @Service(ServiceImpl.class)
-  interface ContextMismatchedParameterB extends RequestContext {
-    Request<Void> checkPrimitive(Integer value);
-  }
-
-  @ProxyFor(Entity.class)
-  interface ProxyMismatchedGetterA extends EntityProxy {
-    int getBoxed();
-  }
-
-  @ProxyFor(Entity.class)
-  interface ProxyMismatchedGetterB extends EntityProxy {
-    Integer getPrimitive();
-  }
-
-  private VisibleErrorContext errors;
-  private RequestFactoryInterfaceValidator v;
-
   @Override
   public String getModuleName() {
     return null;
   }
 
-  public void test() {
-    RequestFactoryInterfaceValidator v = new RequestFactoryInterfaceValidator(
-        Logger.getAnonymousLogger(),
-        new RequestFactoryInterfaceValidator.ClassLoaderLoader(
-            getClass().getClassLoader()));
-    v.validateRequestFactory(Factory.class.getName());
-    assertFalse(v.isPoisoned());
-  }
-
-  /**
-   * Tests that mismatched primitive verses boxed getters are correctly
-   * reported.
-   */
-  public void testMismatchedGetters() {
-    v.validateEntityProxy(ProxyMismatchedGetterA.class.getName());
-    v.validateEntityProxy(ProxyMismatchedGetterB.class.getName());
-    assertTrue(v.isPoisoned());
-
-    String getBoxedMessage = RequestFactoryInterfaceValidator.messageCouldNotFindMethod(
-        Type.getType(Entity.class),
-        Arrays.asList(new Method("getBoxed", "()Ljava/lang/Integer;")));
-    String getPrimitiveMessage = RequestFactoryInterfaceValidator.messageCouldNotFindMethod(
-        Type.getType(Entity.class),
-        Arrays.asList(new Method("getPrimitive", "()I")));
-    assertEquals(Arrays.asList(getBoxedMessage, getPrimitiveMessage),
-        errors.logs);
-  }
-
-  /**
-   * Tests that mismatched parameter types are correctly reported.
-   */
-  public void testMismatchedParameters() {
-    v.validateRequestContext(ContextMismatchedParameterA.class.getName());
-    v.validateRequestContext(ContextMismatchedParameterB.class.getName());
-
-    String checkBoxedMessage = RequestFactoryInterfaceValidator.messageCouldNotFindMethod(
-        Type.getType(ServiceImpl.class),
-        Arrays.asList(new Method("checkBoxed", "(Ljava/lang/Integer;)V")));
-    String checkPrimitiveMessage = RequestFactoryInterfaceValidator.messageCouldNotFindMethod(
-        Type.getType(ServiceImpl.class),
-        Arrays.asList(new Method("checkPrimitive", "(I)V")));
-    assertEquals(Arrays.asList(checkBoxedMessage, checkPrimitiveMessage),
-        errors.logs);
-  }
-
   @Override
   protected Factory createFactory() {
     return RequestFactoryJreTest.createInProcess(Factory.class);
   }
-
-  @Override
-  protected void gwtSetUp() {
-    super.gwtSetUp();
-    errors = new VisibleErrorContext(Logger.getAnonymousLogger());
-    v = new RequestFactoryInterfaceValidator(errors,
-        new RequestFactoryInterfaceValidator.ClassLoaderLoader(
-            getClass().getClassLoader()));
-  }
 }
diff --git a/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryInterfaceValidatorTest.java b/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryInterfaceValidatorTest.java
deleted file mode 100644
index 934ee07..0000000
--- a/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryInterfaceValidatorTest.java
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.web.bindery.requestfactory.server;
-
-import com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidator.ClassLoaderLoader;
-import com.google.web.bindery.requestfactory.shared.EntityProxy;
-import com.google.web.bindery.requestfactory.shared.InstanceRequest;
-import com.google.web.bindery.requestfactory.shared.Locator;
-import com.google.web.bindery.requestfactory.shared.ProxyFor;
-import com.google.web.bindery.requestfactory.shared.ProxyForName;
-import com.google.web.bindery.requestfactory.shared.Request;
-import com.google.web.bindery.requestfactory.shared.RequestContext;
-import com.google.web.bindery.requestfactory.shared.RequestFactory;
-import com.google.web.bindery.requestfactory.shared.Service;
-import com.google.web.bindery.requestfactory.shared.ServiceName;
-import com.google.web.bindery.requestfactory.shared.SimpleRequestFactory;
-import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation;
-import com.google.web.bindery.requestfactory.shared.ValueProxy;
-import com.google.web.bindery.requestfactory.shared.impl.FindRequest;
-
-import junit.framework.TestCase;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * JRE tests for {@link RequestFactoryInterfaceValidator}.
- */
-@SkipInterfaceValidation
-public class RequestFactoryInterfaceValidatorTest extends TestCase {
-  static class ClinitEntity {
-    static ClinitEntity findClinitEntity(@SuppressWarnings("unused") String key) {
-      return null;
-    }
-
-    static ClinitEntity request() {
-      return null;
-    }
-
-    Object OBJECT = new Object();
-
-    String getId() {
-      return null;
-    }
-
-    int getVersion() {
-      return 0;
-    }
-  }
-  @ProxyFor(ClinitEntity.class)
-  interface ClinitEntityProxy extends EntityProxy {
-    Object OBJECT = new Object();
-  }
-  @Service(ClinitEntity.class)
-  interface ClinitRequestContext extends RequestContext {
-    Object OBJECT = new Object();
-
-    Request<ClinitEntityProxy> request();
-  }
-
-  interface ClinitRequestFactory extends RequestFactory {
-    Object OBJECT = new Object();
-
-    ClinitRequestContext context();
-  }
-
-  static class Domain {
-    static int fooStatic(@SuppressWarnings("unused") int a) {
-      return 0;
-    }
-
-    int foo(@SuppressWarnings("unused") int a) {
-      return 0;
-    }
-
-    java.sql.Date getSqlDate() {
-      return null;
-    }
-  }
-
-  @ProxyFor(Domain.class)
-  interface DomainProxy extends EntityProxy {
-  }
-
-  interface DomainProxyMissingAnnotation extends EntityProxy {
-  }
-
-  static class DomainWithOverloads {
-    void foo() {
-    }
-
-    void foo(@SuppressWarnings("unused") int a) {
-    }
-
-    String getId() {
-      return null;
-    }
-
-    int getVersion() {
-      return 0;
-    }
-  }
-
-  @ProxyFor(DomainWithOverloads.class)
-  interface DomainWithOverloadsProxy extends EntityProxy {
-    void foo();
-  }
-
-  @ProxyFor(Domain.class)
-  interface DomainWithSqlDateProxy extends EntityProxy {
-    java.sql.Date getSqlDate();
-  }
-
-  /**
-   * Tests that the validator reports non-static finder methods.
-   */
-  static class EntityWithInstanceFind {
-    public String getId() {
-      return null;
-    }
-
-    public int getVersion() {
-      return 0;
-    }
-
-    /**
-     * This method should be static.
-     */
-    EntityWithInstanceFind findEntityWithInstanceFind(@SuppressWarnings("unused") String key) {
-      return null;
-    }
-  }
-
-  @ProxyFor(EntityWithInstanceFind.class)
-  interface EntityWithInstanceFindProxy extends EntityProxy {
-  }
-
-  class Foo {
-  }
-
-  @ProxyFor(HasListDomain.class)
-  interface HasList extends EntityProxy {
-    List<ReachableOnlyThroughReturnedList> getList();
-
-    void setList(List<ReachableOnlyThroughParamaterList> list);
-  }
-
-  static class HasListDomain extends Domain {
-    public String getId() {
-      return null;
-    }
-
-    public int getVersion() {
-      return 0;
-    }
-
-    List<Domain> getList() {
-      return null;
-    }
-
-    void setList(@SuppressWarnings("unused") List<Domain> value) {
-    }
-  }
-
-  /**
-   * An entity type without the usual boilerplate.
-   */
-  class LocatorEntity {
-  }
-
-  class LocatorEntityLocator extends Locator<LocatorEntity, String> {
-    @Override
-    public LocatorEntity create(Class<? extends LocatorEntity> clazz) {
-      return null;
-    }
-
-    @Override
-    public LocatorEntity find(Class<? extends LocatorEntity> clazz, String id) {
-      return null;
-    }
-
-    @Override
-    public Class<LocatorEntity> getDomainType() {
-      return null;
-    }
-
-    @Override
-    public String getId(LocatorEntity domainObject) {
-      return null;
-    }
-
-    @Override
-    public Class<String> getIdType() {
-      return null;
-    }
-
-    @Override
-    public Object getVersion(LocatorEntity domainObject) {
-      return null;
-    }
-  }
-
-  @ProxyFor(value = LocatorEntity.class, locator = LocatorEntityLocator.class)
-  interface LocatorEntityProxy extends EntityProxy {
-  }
-
-  @ProxyForName(value = "com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidatorTest.LocatorEntity", locator = "badLocator")
-  interface LocatorEntityProxyWithBadLocator extends EntityProxy {
-  }
-
-  @ProxyForName(value = "badDomainType", locator = "com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidatorTest.LocatorEntityProxyWithBadServiceName")
-  interface LocatorEntityProxyWithBadServiceName extends EntityProxy {
-  }
-
-  @ProxyFor(value = Value.class)
-  interface MyValueProxy extends ValueProxy {
-  }
-
-  @ProxyFor(Domain.class)
-  interface ReachableOnlyThroughParamaterList extends EntityProxy {
-  }
-
-  @ProxyFor(Domain.class)
-  interface ReachableOnlyThroughReturnedList extends EntityProxy {
-  }
-
-  interface RequestContextMissingAnnotation extends RequestContext {
-  }
-
-  @Service(Domain.class)
-  interface ServiceRequestMismatchedArity extends RequestContext {
-    InstanceRequest<DomainProxy, Integer> foo(int a, int b);
-
-    Request<Integer> fooStatic(int a, int b);
-  }
-
-  @Service(Domain.class)
-  interface ServiceRequestMismatchedParam extends RequestContext {
-    Request<Integer> foo(long a);
-  }
-  @Service(Domain.class)
-  interface ServiceRequestMismatchedReturn extends RequestContext {
-    Request<Long> foo(int a);
-  }
-
-  @Service(Domain.class)
-  interface ServiceRequestMismatchedStatic extends RequestContext {
-    Request<Integer> foo(int a);
-
-    InstanceRequest<DomainProxy, Integer> fooStatic(int a);
-  }
-
-  @Service(Domain.class)
-  interface ServiceRequestMissingMethod extends RequestContext {
-    Request<Integer> doesNotExist(int a);
-  }
-
-  @Service(Domain.class)
-  interface SkipValidationChecksReferredProxies extends ValueProxy {
-    @SkipInterfaceValidation
-    // still validates other proxies
-    DomainProxyMissingAnnotation getDomainProxyMissingAnnotation();
-  }
-
-  @Service(Domain.class)
-  interface SkipValidationContext extends RequestContext {
-    @SkipInterfaceValidation
-    Request<Integer> doesNotExist(int a);
-
-    @SkipInterfaceValidation
-    Request<Long> foo(int a);
-  }
-
-  @Service(Domain.class)
-  interface SkipValidationProxy extends ValueProxy {
-    @SkipInterfaceValidation
-    boolean doesNotExist();
-  }
-
-  @ProxyFor(Domain.class)
-  @ProxyForName("Domain")
-  @Service(Domain.class)
-  @ServiceName("Domain")
-  interface TooManyAnnotations extends RequestContext {
-  }
-
-  static class UnexpectedIdAndVersionDomain {
-    Random getId() {
-      return null;
-    }
-
-    Random getVersion() {
-      return null;
-    }
-  }
-
-  @ProxyFor(UnexpectedIdAndVersionDomain.class)
-  interface UnexpectedIdAndVersionProxy extends EntityProxy {
-  }
-
-  static class Value {
-  }
-
-  static class VisibleErrorContext extends RequestFactoryInterfaceValidator.ErrorContext {
-    final List<String> logs;
-
-    public VisibleErrorContext(Logger logger) {
-      super(logger);
-      logs = new ArrayList<String>();
-    }
-
-    public VisibleErrorContext(VisibleErrorContext that) {
-      super(that);
-      this.logs = that.logs;
-    }
-
-    @Override
-    public void poison(String msg, Object... args) {
-      logs.add(String.format(msg, args));
-      super.poison(msg, args);
-    }
-
-    @Override
-    public void poison(String msg, Throwable t) {
-      logs.add(msg);
-      super.poison(msg, t);
-    }
-
-    @Override
-    protected VisibleErrorContext fork() {
-      return new VisibleErrorContext(this);
-    }
-  }
-
-  RequestFactoryInterfaceValidator v;;
-
-  private static final boolean DUMP_PAYLOAD = Boolean.getBoolean("gwt.rpc.dumpPayload");;
-
-  private VisibleErrorContext errors;
-
-  /**
-   * Ensure that calling {@link RequestFactoryInterfaceValidator#antidote()}
-   * doesn't cause information to be lost.
-   */
-  public void testAntidote() {
-    v.validateRequestContext(RequestContextMissingAnnotation.class.getName());
-    assertTrue(v.isPoisoned());
-    v.antidote();
-    assertFalse(v.isPoisoned());
-    v.validateRequestContext(RequestContextMissingAnnotation.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testBadLocatorName() {
-    v.validateEntityProxy(LocatorEntityProxyWithBadLocator.class.getName());
-    assertTrue(v.isPoisoned());
-    assertTrue(errors.logs.contains("Cannot find locator named badLocator"));
-  }
-
-  public void testBadServiceName() {
-    v.validateEntityProxy(LocatorEntityProxyWithBadServiceName.class.getName());
-    assertTrue(v.isPoisoned());
-    assertTrue(errors.logs.contains("Cannot find domain type named badDomainType"));
-  }
-
-  /**
-   * Test that subclasses of {@code java.util.Date} are not transportable.
-   */
-  public void testDateSubclass() {
-    v.validateEntityProxy(DomainWithSqlDateProxy.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testFindMustBeStatic() {
-    v.validateEntityProxy(EntityWithInstanceFindProxy.class.getName());
-    assertTrue(v.isPoisoned());
-    assertTrue(errors.logs.contains("The findEntityWithInstanceFind method must be static"));
-  }
-
-  /**
-   * Test the {@link FindRequest} context used to implement find().
-   */
-  public void testFindRequestContext() {
-    v.validateRequestContext(FindRequest.class.getName());
-  }
-
-  /**
-   * Make sure that proxy types referenced through type parameters of method
-   * return types and paramaters types are examined.
-   */
-  public void testFollowingTypeParameters() {
-    v.validateEntityProxy(HasList.class.getName());
-    Deobfuscator d = v.getDeobfuscator();
-    assertNotNull(d.getClientProxies(HasListDomain.class.getName()));
-    assertTrue(d.getClientProxies(Domain.class.getName()).contains(
-        ReachableOnlyThroughParamaterList.class.getName()));
-    assertTrue(d.getClientProxies(Domain.class.getName()).contains(
-        ReachableOnlyThroughReturnedList.class.getName()));
-  }
-
-  /**
-   * Ensure that the &lt;clinit> methods don't interfere with validation.
-   */
-  public void testIntecfacesWithClinits() {
-    v.validateRequestFactory(ClinitRequestFactory.class.getName());
-    assertFalse(v.isPoisoned());
-  }
-
-  public void testLocatorProxy() {
-    v.validateEntityProxy(LocatorEntityProxy.class.getName());
-    assertFalse(v.isPoisoned());
-  }
-
-  public void testMismatchedArity() {
-    v.validateRequestContext(ServiceRequestMismatchedArity.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testMismatchedParamType() {
-    v.validateRequestContext(ServiceRequestMismatchedParam.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testMismatchedReturnType() {
-    v.validateRequestContext(ServiceRequestMismatchedReturn.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testMismatchedStatic() {
-    v.validateRequestContext(ServiceRequestMismatchedStatic.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testMissingDomainAnnotations() {
-    v.validateEntityProxy(DomainProxyMissingAnnotation.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testMissingIdAndVersion() {
-    v.validateEntityProxy(DomainProxy.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testMissingMethod() {
-    v.validateRequestContext(ServiceRequestMissingMethod.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testMissingServiceAnnotations() {
-    v.validateRequestContext(RequestContextMissingAnnotation.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testOverloadedMethod() {
-    v.validateEntityProxy(DomainWithOverloadsProxy.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testSkipValidationChecksReferredProxies() {
-    v.validateValueProxy(SkipValidationChecksReferredProxies.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testSkipValidationContext() {
-    v.validateRequestContext(SkipValidationContext.class.getName());
-    assertFalse(v.isPoisoned());
-  }
-
-  public void testSkipValidationProxy() {
-    v.validateValueProxy(SkipValidationProxy.class.getName());
-    assertFalse(v.isPoisoned());
-  }
-
-  /**
-   * Perform a full test of the RequestFactory used for most tests.
-   */
-  public void testTestCodeFactories() {
-    v.validateRequestFactory(SimpleRequestFactory.class.getName());
-    assertFalse(v.isPoisoned());
-  }
-
-  public void testTooManyAnnotations() {
-    v.validateRequestContext(TooManyAnnotations.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testUnexpectedIdAndVersion() {
-    v.validateEntityProxy(UnexpectedIdAndVersionProxy.class.getName());
-    assertTrue(v.isPoisoned());
-  }
-
-  public void testValueType() {
-    v.validateValueProxy(MyValueProxy.class.getName());
-    assertFalse(v.isPoisoned());
-  }
-
-  @Override
-  protected void setUp() throws Exception {
-    Logger logger = Logger.getLogger("");
-    logger.setLevel(DUMP_PAYLOAD ? Level.ALL : Level.OFF);
-    errors = new VisibleErrorContext(logger);
-    v =
-        new RequestFactoryInterfaceValidator(errors, new ClassLoaderLoader(Thread.currentThread()
-            .getContextClassLoader()));
-  }
-}
diff --git a/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryJreTest.java b/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryJreTest.java
index ad762f4..04a3685 100644
--- a/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryJreTest.java
+++ b/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryJreTest.java
@@ -19,17 +19,11 @@
 import com.google.web.bindery.event.shared.SimpleEventBus;
 import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryTest;
 import com.google.web.bindery.requestfactory.server.testing.InProcessRequestTransport;
-import com.google.web.bindery.requestfactory.shared.BaseProxy;
 import com.google.web.bindery.requestfactory.shared.RequestFactory;
-import com.google.web.bindery.requestfactory.shared.SimpleBarProxy;
-import com.google.web.bindery.requestfactory.shared.SimpleFooProxy;
 import com.google.web.bindery.requestfactory.shared.SimpleRequestFactory;
 import com.google.web.bindery.requestfactory.vm.RequestFactorySource;
-import com.google.web.bindery.requestfactory.vm.impl.OperationKey;
-import com.google.web.bindery.requestfactory.vm.impl.TypeTokenResolver;
 import com.google.web.bindery.requestfactory.vm.testing.UrlRequestTransport;
 
-import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 
@@ -37,8 +31,7 @@
  * Runs the RequestFactory tests in-process.
  */
 public class RequestFactoryJreTest extends RequestFactoryTest {
-  private static final String TEST_SERVER_ADDRESS = System
-      .getProperty("RequestFactory.testUrl");
+  private static final String TEST_SERVER_ADDRESS = System.getProperty("RequestFactory.testUrl");
 
   public static <T extends RequestFactory> T createInProcess(Class<T> clazz) {
     EventBus eventBus = new SimpleEventBus();
@@ -63,20 +56,8 @@
     return null;
   }
 
-  public void testTypeTokenResolver() throws IOException {
-    TypeTokenResolver resolver = TypeTokenResolver.loadFromClasspath();
-    testResolver(resolver, SimpleBarProxy.class);
-    testResolver(resolver, SimpleFooProxy.class);
-  }
-
   @Override
   protected SimpleRequestFactory createFactory() {
     return createInProcess(SimpleRequestFactory.class);
   }
-
-  private void testResolver(TypeTokenResolver resolver, Class<? extends BaseProxy> type) {
-    String token = OperationKey.hash(type.getName());
-    String typeName = resolver.getTypeFromToken(token);
-    assertEquals(type.getName(), typeName);
-  }
 }
diff --git a/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryPolymorphicJreTest.java b/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryPolymorphicJreTest.java
index bcf5a23..e10c68a 100644
--- a/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryPolymorphicJreTest.java
+++ b/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryPolymorphicJreTest.java
@@ -16,11 +16,10 @@
 package com.google.web.bindery.requestfactory.server;
 
 import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryPolymorphicTest;
-import com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidator.ClassLoaderLoader;
 import com.google.web.bindery.requestfactory.shared.BaseProxy;
+import com.google.web.bindery.requestfactory.vm.impl.Deobfuscator;
 
 import java.util.List;
-import java.util.logging.Logger;
 
 /**
  * A JRE version of {@link RequestFactoryPolymorphicTest} that includes
@@ -120,11 +119,7 @@
   @Override
   protected void gwtSetUp() throws Exception {
     super.gwtSetUp();
-    Logger logger = Logger.getLogger(getClass().getName());
-    ClassLoaderLoader loader = new ClassLoaderLoader(getClass().getClassLoader());
-    RequestFactoryInterfaceValidator v = new RequestFactoryInterfaceValidator(logger, loader);
-    v.validateRequestFactory(Factory.class.getName());
-    deobfuscator = v.getDeobfuscator();
+    deobfuscator = Deobfuscator.Builder.load(Factory.class, getClass().getClassLoader()).build();
   }
 
   private void check(Class<?> domainType, Class<? extends BaseProxy> declaredReturnType,
diff --git a/user/test/com/google/web/bindery/requestfactory/server/SimpleBar.java b/user/test/com/google/web/bindery/requestfactory/server/SimpleBar.java
index 5b8e40c..e313263 100644
--- a/user/test/com/google/web/bindery/requestfactory/server/SimpleBar.java
+++ b/user/test/com/google/web/bindery/requestfactory/server/SimpleBar.java
@@ -15,10 +15,9 @@
  */
 package com.google.web.bindery.requestfactory.server;
 
-import com.google.gwt.dev.util.collect.HashSet;
-
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
diff --git a/user/test/com/google/web/bindery/requestfactory/shared/TestFooPolymorphicRequest.java b/user/test/com/google/web/bindery/requestfactory/shared/TestFooPolymorphicRequest.java
index 5662c40..350b8c9 100644
--- a/user/test/com/google/web/bindery/requestfactory/shared/TestFooPolymorphicRequest.java
+++ b/user/test/com/google/web/bindery/requestfactory/shared/TestFooPolymorphicRequest.java
@@ -17,7 +17,8 @@
 
 /**
  * Just to test the
- * {@link com.google.web.bindery.requestfactory.gwt.rebind.RequestFactoryGenerator} code.
+ * {@link com.google.web.bindery.requestfactory.gwt.rebind.RequestFactoryGenerator}
+ * code.
  */
 @Service(com.google.web.bindery.requestfactory.server.SimpleFoo.class)
 public interface TestFooPolymorphicRequest extends RequestContext {
diff --git a/user/test/com/google/web/bindery/requestfactory/vm/RequestFactoryJreSuite.java b/user/test/com/google/web/bindery/requestfactory/vm/RequestFactoryJreSuite.java
index ba26e92..f0cb5a2 100644
--- a/user/test/com/google/web/bindery/requestfactory/vm/RequestFactoryJreSuite.java
+++ b/user/test/com/google/web/bindery/requestfactory/vm/RequestFactoryJreSuite.java
@@ -22,7 +22,6 @@
 import com.google.web.bindery.requestfactory.server.LocatorJreTest;
 import com.google.web.bindery.requestfactory.server.RequestFactoryChainedContextJreTest;
 import com.google.web.bindery.requestfactory.server.RequestFactoryExceptionPropagationJreTest;
-import com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidatorTest;
 import com.google.web.bindery.requestfactory.server.RequestFactoryJreTest;
 import com.google.web.bindery.requestfactory.server.RequestFactoryPolymorphicJreTest;
 import com.google.web.bindery.requestfactory.server.RequestFactoryUnicodeEscapingJreTest;
@@ -49,7 +48,6 @@
     suite.addTestSuite(LocatorJreTest.class);
     suite.addTestSuite(RequestFactoryChainedContextJreTest.class);
     suite.addTestSuite(RequestFactoryExceptionPropagationJreTest.class);
-    suite.addTestSuite(RequestFactoryInterfaceValidatorTest.class);
     suite.addTestSuite(RequestFactoryJreTest.class);
     suite.addTestSuite(RequestFactoryPolymorphicJreTest.class);
     suite.addTestSuite(RequestFactoryUnicodeEscapingJreTest.class);
