diff --git a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/console/Console.java b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/console/Console.java
new file mode 100644
index 0000000..0db3125
--- /dev/null
+++ b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/console/Console.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.sample.dynatablerf.console;
+
+import com.google.gwt.event.shared.SimpleEventBus;
+import com.google.gwt.requestfactory.server.testing.RequestFactoryMagic;
+import com.google.gwt.requestfactory.shared.Receiver;
+import com.google.gwt.sample.dynatablerf.shared.AddressProxy;
+import com.google.gwt.sample.dynatablerf.shared.DynaTableRequestFactory;
+import com.google.gwt.sample.dynatablerf.shared.PersonProxy;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A proof-of-concept to demonstrate how RequestFactory can be used from
+ * non-client code.
+ */
+public class Console {
+  public static void main(String[] args) {
+    String url = "http://localhost:8888/gwtRequest";
+    if (args.length == 1) {
+      url = args[0];
+    }
+    try {
+      new Console(new URI(url)).exec();
+      System.exit(0);
+    } catch (URISyntaxException e) {
+      System.err.println("Could not parse argument");
+    }
+    System.exit(1);
+  }
+
+  private final DynaTableRequestFactory rf;
+
+  private Console(URI uri) {
+    /*
+     * Instantiation of the RequestFactory interface uses the
+     * RequestFactoryMagic class instead of GWT.create().
+     */
+    this.rf = RequestFactoryMagic.create(DynaTableRequestFactory.class);
+    // Initialization follows the same pattern as client code
+    rf.initialize(new SimpleEventBus(), new HttpClientTransport(uri));
+  }
+
+  /**
+   * Making a request from non-GWT code is similar. The implementation of the
+   * demonstration HttpClientTransport issues the requests synchronously. A
+   * different transport system might use asynchronous callbacks.
+   */
+  private void exec() {
+    rf.schoolCalendarRequest().getPeople(0, 100,
+        Arrays.asList(true, true, true, true, true, true, true)).with("address").fire(
+        new Receiver<List<PersonProxy>>() {
+          @Override
+          public void onSuccess(List<PersonProxy> response) {
+            // Print each record to the console
+            for (PersonProxy person : response) {
+              AddressProxy address = person.getAddress();
+              String addressBlob = address.getStreet() + " "
+                  + address.getCity() + " " + address.getState() + " "
+                  + address.getZip();
+              System.out.printf("%-40s%40s\n%80s\n\n", person.getName(),
+                  person.getDescription(), addressBlob);
+            }
+          }
+        });
+  }
+}
diff --git a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/console/HttpClientTransport.java b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/console/HttpClientTransport.java
new file mode 100644
index 0000000..4325979
--- /dev/null
+++ b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/console/HttpClientTransport.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.sample.dynatablerf.console;
+
+import com.google.gwt.dev.util.Util;
+import com.google.gwt.requestfactory.shared.RequestTransport;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+
+/**
+ * This is a simple implementation of {@link RequestTransport} that uses
+ * HttpClient. It is not suitable for production use, but demonstrates the
+ * minimum functionality necessary to implement a custom RequestTransport.
+ */
+class HttpClientTransport implements RequestTransport {
+  private final URI uri;
+
+  public HttpClientTransport(URI uri) {
+    this.uri = uri;
+  }
+
+  @Override
+  public void send(String payload, TransportReceiver receiver) {
+    HttpClient client = new DefaultHttpClient();
+    HttpPost post = new HttpPost();
+    post.setHeader("Content-Type", "application/json;charset=UTF-8");
+    post.setURI(uri);
+    Throwable ex;
+    try {
+      post.setEntity(new StringEntity(payload, "UTF-8"));
+      HttpResponse response = client.execute(post);
+      if (200 == response.getStatusLine().getStatusCode()) {
+        String contents = Util.readStreamAsString(response.getEntity().getContent());
+        receiver.onTransportSuccess(contents);
+      } else {
+        receiver.onTransportFailure(response.getStatusLine().getReasonPhrase());
+      }
+      return;
+    } catch (UnsupportedEncodingException e) {
+      ex = e;
+    } catch (ClientProtocolException e) {
+      ex = e;
+    } catch (IOException e) {
+      ex = e;
+    }
+    receiver.onTransportFailure(ex.getMessage());
+  }
+}
\ No newline at end of file
diff --git a/tools/api-checker/config/gwt20_21userApi.conf b/tools/api-checker/config/gwt20_21userApi.conf
index a384fed..697b3cc 100644
--- a/tools/api-checker/config/gwt20_21userApi.conf
+++ b/tools/api-checker/config/gwt20_21userApi.conf
@@ -66,6 +66,7 @@
 :**/server/**\
 :**/tools/**\
 :user/src/com/google/gwt/regexp/shared/**\
+:user/src/com/google/gwt/autobean/shared/impl/StringQuoter.java\
 :user/src/com/google/gwt/core/client/impl/WeakMapping.java\
 :user/src/com/google/gwt/junit/*.java\
 :user/src/com/google/gwt/junit/client/GWTTestCase.java\
@@ -75,6 +76,7 @@
 :user/src/com/google/gwt/resources/css\
 :user/src/com/google/gwt/resources/ext\
 :user/src/com/google/gwt/resources/rg\
+:user/src/com/google/gwt/requestfactory/shared/impl/MessageFactoryHolder.java\
 :user/src/com/google/gwt/rpc/client/impl/ClientWriterFactory.java\
 :user/src/com/google/gwt/rpc/client/impl/EscapeUtil.java\
 :user/src/com/google/gwt/rpc/linker\
diff --git a/user/src/com/google/gwt/autobean/AutoBean.gwt.xml b/user/src/com/google/gwt/autobean/AutoBean.gwt.xml
new file mode 100644
index 0000000..cc23165
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/AutoBean.gwt.xml
@@ -0,0 +1,24 @@
+<?xml version="1.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.
+-->
+
+<!-- AutoBean framework -->
+<module>
+  <inherits name="com.google.gwt.core.Core" />
+  <inherits name="com.google.gwt.user.User" />
+  <source path="client" />
+  <source path="shared" />
+  <super-source path="super" />
+  <generate-with class="com.google.gwt.autobean.rebind.AutoBeanFactoryGenerator">
+    <when-type-assignable class="com.google.gwt.autobean.shared.AutoBeanFactory" />
+  </generate-with>
+</module>
\ No newline at end of file
diff --git a/user/src/com/google/gwt/editor/client/impl/AbstractAutoBeanFactory.java b/user/src/com/google/gwt/autobean/client/impl/AbstractAutoBeanFactory.java
similarity index 90%
rename from user/src/com/google/gwt/editor/client/impl/AbstractAutoBeanFactory.java
rename to user/src/com/google/gwt/autobean/client/impl/AbstractAutoBeanFactory.java
index 695efd4..a04e5f6 100644
--- a/user/src/com/google/gwt/editor/client/impl/AbstractAutoBeanFactory.java
+++ b/user/src/com/google/gwt/autobean/client/impl/AbstractAutoBeanFactory.java
@@ -13,10 +13,10 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.client.impl;
+package com.google.gwt.autobean.client.impl;
 
-import com.google.gwt.editor.client.AutoBean;
-import com.google.gwt.editor.client.AutoBeanFactory;
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanFactory;
 
 import java.util.HashMap;
 import java.util.Map;
diff --git a/user/src/com/google/gwt/autobean/client/impl/JsoSplittable.java b/user/src/com/google/gwt/autobean/client/impl/JsoSplittable.java
new file mode 100644
index 0000000..f3a0bb2
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/client/impl/JsoSplittable.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.client.impl;
+
+import com.google.gwt.autobean.shared.Splittable;
+import com.google.gwt.autobean.shared.impl.StringQuoter;
+import com.google.gwt.core.client.JavaScriptObject;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Implements the EntityCodex.Splittable interface
+ */
+public final class JsoSplittable extends JavaScriptObject implements Splittable {
+  /**
+   * This type is only used in DevMode because we can't treat Strings as JSOs.
+   */
+  public static class StringSplittable implements Splittable {
+    private final String value;
+
+    public StringSplittable(String value) {
+      this.value = value;
+    }
+
+    public String asString() {
+      return value;
+    }
+
+    public Splittable get(int index) {
+      throw new UnsupportedOperationException();
+    }
+
+    public Splittable get(String key) {
+      throw new UnsupportedOperationException();
+    }
+
+    public String getPayload() {
+      return StringQuoter.quote(value);
+    }
+
+    public List<String> getPropertyKeys() {
+      return Collections.emptyList();
+    }
+
+    public boolean isNull(int index) {
+      throw new UnsupportedOperationException();
+    }
+
+    public boolean isNull(String key) {
+      throw new UnsupportedOperationException();
+    }
+
+    public int size() {
+      return 0;
+    }
+  }
+
+  public static Splittable create(Object object) {
+    if (object instanceof String) {
+      return new StringSplittable((String) object);
+    }
+    return create0(object);
+  }
+
+  private static native Splittable create0(Object object) /*-{
+    return object;
+  }-*/;
+
+  protected JsoSplittable() {
+  }
+
+  public native String asString() /*-{
+    return String(this);
+  }-*/;
+
+  public Splittable get(int index) {
+    return create(get0(index));
+  }
+
+  public Splittable get(String key) {
+    return create(get0(key));
+  }
+
+  public String getPayload() {
+    throw new UnsupportedOperationException(
+        "Cannot convert JsoSplittable to payload");
+  }
+
+  public List<String> getPropertyKeys() {
+    List<String> toReturn = new ArrayList<String>();
+    getPropertyKeys0(toReturn);
+    return Collections.unmodifiableList(toReturn);
+  }
+
+  public native boolean isNull(int index) /*-{
+    return this[index] == null;
+  }-*/;
+
+  public native boolean isNull(String key) /*-{
+    return this[key] == null;
+  }-*/;
+
+  public native int size() /*-{
+    return this.length;
+  }-*/;
+
+  private native Object get0(int index) /*-{
+    return Object(this[index]);
+  }-*/;
+
+  private native Object get0(String key) /*-{
+    return Object(this[key]);
+  }-*/;
+
+  private native void getPropertyKeys0(List<String> list) /*-{
+    for (key in this) {
+      if (this.hasOwnProperty(key)) {
+        list.@java.util.List::add(Ljava/lang/Object;)(key);
+      }
+    }
+  }-*/;
+}
diff --git a/user/src/com/google/gwt/editor/rebind/AutoBeanFactoryGenerator.java b/user/src/com/google/gwt/autobean/rebind/AutoBeanFactoryGenerator.java
similarity index 85%
rename from user/src/com/google/gwt/editor/rebind/AutoBeanFactoryGenerator.java
rename to user/src/com/google/gwt/autobean/rebind/AutoBeanFactoryGenerator.java
index 0c0dae5..febc68d 100644
--- a/user/src/com/google/gwt/editor/rebind/AutoBeanFactoryGenerator.java
+++ b/user/src/com/google/gwt/autobean/rebind/AutoBeanFactoryGenerator.java
@@ -13,8 +13,22 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.rebind;
+package com.google.gwt.autobean.rebind;
 
+import com.google.gwt.autobean.client.impl.AbstractAutoBeanFactory;
+import com.google.gwt.autobean.rebind.model.AutoBeanFactoryMethod;
+import com.google.gwt.autobean.rebind.model.AutoBeanFactoryModel;
+import com.google.gwt.autobean.rebind.model.AutoBeanMethod;
+import com.google.gwt.autobean.rebind.model.AutoBeanMethod.Action;
+import com.google.gwt.autobean.rebind.model.AutoBeanType;
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanUtils;
+import com.google.gwt.autobean.shared.AutoBeanVisitor;
+import com.google.gwt.autobean.shared.AutoBeanVisitor.CollectionPropertyContext;
+import com.google.gwt.autobean.shared.AutoBeanVisitor.MapPropertyContext;
+import com.google.gwt.autobean.shared.AutoBeanVisitor.PropertyContext;
+import com.google.gwt.autobean.shared.impl.AbstractAutoBean;
+import com.google.gwt.autobean.shared.impl.AbstractAutoBean.OneShotContext;
 import com.google.gwt.core.client.impl.WeakMapping;
 import com.google.gwt.core.ext.Generator;
 import com.google.gwt.core.ext.GeneratorContext;
@@ -26,18 +40,6 @@
 import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
 import com.google.gwt.core.ext.typeinfo.JType;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.editor.client.AutoBean;
-import com.google.gwt.editor.client.AutoBeanUtils;
-import com.google.gwt.editor.client.AutoBeanVisitor;
-import com.google.gwt.editor.client.AutoBeanVisitor.PropertyContext;
-import com.google.gwt.editor.client.impl.AbstractAutoBean;
-import com.google.gwt.editor.client.impl.AbstractAutoBean.OneShotContext;
-import com.google.gwt.editor.client.impl.AbstractAutoBeanFactory;
-import com.google.gwt.editor.rebind.model.AutoBeanFactoryMethod;
-import com.google.gwt.editor.rebind.model.AutoBeanFactoryModel;
-import com.google.gwt.editor.rebind.model.AutoBeanMethod;
-import com.google.gwt.editor.rebind.model.AutoBeanMethod.Action;
-import com.google.gwt.editor.rebind.model.AutoBeanType;
 import com.google.gwt.editor.rebind.model.ModelUtils;
 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
@@ -183,6 +185,10 @@
     sw.indentln("return new %s(this, deep);", type.getSimpleSourceName());
     sw.println("}");
 
+    // public Class<Intf> getType() {return Intf.class;}
+    sw.println("public Class<%1$s> getType() {return %1$s.class;}",
+        type.getPeerType().getQualifiedSourceName());
+
     if (type.isSimpleBean()) {
       writeCreateSimpleBean(sw, type);
     }
@@ -501,24 +507,55 @@
         }
       }
 
+      // The type of property influences the visitation
+      String valueExpression = String.format(
+          "%1$s value = (%1$s) %2$s.getAutoBean(as().%3$s());",
+          AbstractAutoBean.class.getCanonicalName(),
+          AutoBeanUtils.class.getCanonicalName(), method.getMethod().getName());
+      String visitMethod;
+      Class<?> propertyContextType;
+      if (method.isCollection()) {
+        propertyContextType = CollectionPropertyContext.class;
+        visitMethod = "Collection";
+      } else if (method.isMap()) {
+        propertyContextType = MapPropertyContext.class;
+        visitMethod = "Map";
+      } else if (method.isValueType()) {
+        propertyContextType = PropertyContext.class;
+        valueExpression = String.format("Object value = as().%s();",
+            method.getMethod().getName());
+        visitMethod = "Value";
+      } else {
+        visitMethod = "Reference";
+        propertyContextType = PropertyContext.class;
+      }
+
       // Make the PropertyContext that lets us call the setter
       String propertyContextName = method.getPropertyName() + "PropertyContext";
       sw.println("class %s implements %s {", propertyContextName,
-          PropertyContext.class.getCanonicalName());
+          propertyContextType.getCanonicalName());
       sw.indent();
       sw.println("public boolean canSet() { return %s; }", type.isSimpleBean()
           || setter != null);
-      // Will return the collection's element type or null if not a collection
-      sw.println("public Class<?> getElementType() { return %s; }",
-          method.isCollection()
-              ? (method.getElementType().getQualifiedSourceName() + ".class")
-              : "null");
+      if (method.isCollection()) {
+        // Will return the collection's element type or null if not a collection
+        sw.println("public Class<?> getElementType() { return %s; }",
+            method.getElementType().getQualifiedSourceName() + ".class");
+      } else if (method.isMap()) {
+        // Will return the map's value type
+        sw.println("public Class<?> getValueType() { return %s; }",
+            method.getValueType().getQualifiedSourceName() + ".class");
+        // Will return the map's key type
+        sw.println("public Class<?> getKeyType() { return %s; }",
+            method.getKeyType().getQualifiedSourceName() + ".class");
+      }
       // Return the property type
       sw.println("public Class<?> getType() { return %s.class; }",
           method.getMethod().getReturnType().getQualifiedSourceName());
       sw.println("public void set(Object obj) { ");
       if (setter != null) {
         // Prefer the setter if one exists
+        // as().setFoo((Foo) obj);
         sw.indentln(
             "as().%s((%s) obj);",
             setter.getMethod().getName(),
@@ -532,36 +569,25 @@
       sw.println("}");
       sw.outdent();
       sw.println("}");
+
+      sw.print("{");
+      sw.indent();
       sw.println("%1$s %1$s = new %1$s();", propertyContextName);
 
-      if (method.isValueType()) {
-        // visitor.visitValueProperty("foo", as().getFoo(), ctx);
-        sw.println("visitor.visitValueProperty(\"%s\", as().%s(), %s);",
-            method.getPropertyName(), method.getMethod().getName(),
-            propertyContextName);
-        // visitor.endVisitValueProperty("foo", as().getFoo(), ctx);
-        sw.println("visitor.endVisitValueProperty(\"%s\", as().%s(), %s);",
-            method.getPropertyName(), method.getMethod().getName(),
-            propertyContextName);
-      } else {
-        sw.println("{");
-        sw.indent();
-        // AbstractAutoBean auto=(cast)AutoBeanUtils.getAutoBean(as().getFoo());
-        sw.println("%1$s auto = (%1$s) %2$s.getAutoBean(as().%3$s());",
-            AbstractAutoBean.class.getCanonicalName(),
-            AutoBeanUtils.class.getCanonicalName(),
-            method.getMethod().getName());
-        // if (visitor.visitReferenceProperty("foo", auto, ctx))
-        sw.println("if (visitor.visitReferenceProperty(\"%s\", auto, %s))",
-            method.getPropertyName(), propertyContextName);
+      // Call the visit methods
+      sw.println(valueExpression);
+      // if (visitor.visitReferenceProperty("foo", value, ctx))
+      sw.println("if (visitor.visit%sProperty(\"%s\", value, %s))",
+          visitMethod, method.getPropertyName(), propertyContextName);
+      if (!method.isValueType()) {
         // Cycle-detection in AbstractAutoBean.traverse
-        sw.indentln("if (auto != null) { auto.traverse(visitor, ctx); }");
-        // visitor.endVisitorReferenceProperty("foo", auto' ctx);
-        sw.println("visitor.endVisitReferenceProperty(\"%s\", auto, %s);",
-            method.getPropertyName(), propertyContextName);
-        sw.outdent();
-        sw.println("}");
+        sw.indentln("if (value != null) { value.traverse(visitor, ctx); }");
       }
+      // visitor.endVisitorReferenceProperty("foo", value, ctx);
+      sw.println("visitor.endVisit%sProperty(\"%s\", value, %s);", visitMethod,
+          method.getPropertyName(), propertyContextName);
+      sw.outdent();
+      sw.print("}");
     }
     sw.outdent();
     sw.println("}");
diff --git a/user/src/com/google/gwt/editor/rebind/model/AutoBeanFactoryMethod.java b/user/src/com/google/gwt/autobean/rebind/model/AutoBeanFactoryMethod.java
similarity index 97%
rename from user/src/com/google/gwt/editor/rebind/model/AutoBeanFactoryMethod.java
rename to user/src/com/google/gwt/autobean/rebind/model/AutoBeanFactoryMethod.java
index 1584d0b..ee9cdae 100644
--- a/user/src/com/google/gwt/editor/rebind/model/AutoBeanFactoryMethod.java
+++ b/user/src/com/google/gwt/autobean/rebind/model/AutoBeanFactoryMethod.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.rebind.model;
+package com.google.gwt.autobean.rebind.model;
 
 import com.google.gwt.core.ext.typeinfo.JClassType;
 import com.google.gwt.core.ext.typeinfo.JMethod;
diff --git a/user/src/com/google/gwt/editor/rebind/model/AutoBeanFactoryModel.java b/user/src/com/google/gwt/autobean/rebind/model/AutoBeanFactoryModel.java
similarity index 93%
rename from user/src/com/google/gwt/editor/rebind/model/AutoBeanFactoryModel.java
rename to user/src/com/google/gwt/autobean/rebind/model/AutoBeanFactoryModel.java
index c8d6646..55c727c 100644
--- a/user/src/com/google/gwt/editor/rebind/model/AutoBeanFactoryModel.java
+++ b/user/src/com/google/gwt/autobean/rebind/model/AutoBeanFactoryModel.java
@@ -13,8 +13,13 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.rebind.model;
+package com.google.gwt.autobean.rebind.model;
 
+import com.google.gwt.autobean.rebind.model.AutoBeanMethod.Action;
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanFactory;
+import com.google.gwt.autobean.shared.AutoBeanFactory.Category;
+import com.google.gwt.autobean.shared.AutoBeanFactory.NoWrap;
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JClassType;
@@ -24,11 +29,7 @@
 import com.google.gwt.core.ext.typeinfo.JParameterizedType;
 import com.google.gwt.core.ext.typeinfo.JType;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.editor.client.AutoBean;
-import com.google.gwt.editor.client.AutoBeanFactory;
-import com.google.gwt.editor.client.AutoBeanFactory.Category;
-import com.google.gwt.editor.client.AutoBeanFactory.NoWrap;
-import com.google.gwt.editor.rebind.model.AutoBeanMethod.Action;
+import com.google.gwt.editor.rebind.model.ModelUtils;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -75,9 +76,10 @@
      * so we'll extract them here.
      */
     JClassType objectType = oracle.getJavaLangObject();
-    objectMethods = Arrays.asList(objectType.findMethod("equals",
-        new JType[] {objectType}), objectType.findMethod("hashCode",
-        EMPTY_JTYPE), objectType.findMethod("toString", EMPTY_JTYPE));
+    objectMethods = Arrays.asList(
+        objectType.findMethod("equals", new JType[]{objectType}),
+        objectType.findMethod("hashCode", EMPTY_JTYPE),
+        objectType.findMethod("toString", EMPTY_JTYPE));
 
     // Process annotations
     {
@@ -90,12 +92,11 @@
         categoryTypes = null;
       }
 
+      noWrapTypes = new ArrayList<JClassType>();
+      noWrapTypes.add(oracle.findType(AutoBean.class.getCanonicalName()));
       NoWrap noWrapAnnotation = factoryType.getAnnotation(NoWrap.class);
       if (noWrapAnnotation != null) {
-        noWrapTypes = new ArrayList<JClassType>(noWrapAnnotation.value().length);
         processClassArrayAnnotation(noWrapAnnotation.value(), noWrapTypes);
-      } else {
-        noWrapTypes = null;
       }
     }
 
@@ -184,6 +185,10 @@
     return Collections.unmodifiableCollection(peers.values());
   }
 
+  public List<JClassType> getCategoryTypes() {
+    return categoryTypes;
+  }
+
   public List<AutoBeanFactoryMethod> getMethods() {
     return Collections.unmodifiableList(methods);
   }
@@ -358,6 +363,7 @@
     AutoBeanType toReturn = peers.get(beanType);
     if (toReturn == null) {
       AutoBeanType.Builder builder = new AutoBeanType.Builder();
+      builder.setOwnerFactory(this);
       builder.setPeerType(beanType);
       builder.setMethods(computeMethods(beanType));
       builder.setInterceptor(findInterceptor(beanType));
@@ -390,7 +396,8 @@
 
     // Check using base types to account for erasure semantics
     JParameterizedType expectedFirst = oracle.getParameterizedType(
-        autoBeanInterface, new JClassType[] {ModelUtils.ensureBaseType(beanType)});
+        autoBeanInterface,
+        new JClassType[]{ModelUtils.ensureBaseType(beanType)});
     return expectedFirst.isAssignableTo(paramAsClass);
   }
 
diff --git a/user/src/com/google/gwt/editor/rebind/model/AutoBeanMethod.java b/user/src/com/google/gwt/autobean/rebind/model/AutoBeanMethod.java
similarity index 69%
rename from user/src/com/google/gwt/editor/rebind/model/AutoBeanMethod.java
rename to user/src/com/google/gwt/autobean/rebind/model/AutoBeanMethod.java
index 3cc2b45..ddb02b8 100644
--- a/user/src/com/google/gwt/editor/rebind/model/AutoBeanMethod.java
+++ b/user/src/com/google/gwt/autobean/rebind/model/AutoBeanMethod.java
@@ -13,13 +13,16 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.rebind.model;
+package com.google.gwt.autobean.rebind.model;
 
+import com.google.gwt.autobean.shared.AutoBean.PropertyName;
 import com.google.gwt.core.ext.typeinfo.JClassType;
 import com.google.gwt.core.ext.typeinfo.JMethod;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.editor.rebind.model.ModelUtils;
 
 import java.util.Collection;
+import java.util.Map;
 
 /**
  * Describes a method implemented by an AutoBean.
@@ -40,10 +43,15 @@
     public AutoBeanMethod build() {
       if (toReturn.action.equals(Action.GET)
           || toReturn.action.equals(Action.SET)) {
-        String name = toReturn.method.getName();
-        // setFoo
-        toReturn.propertyName = Character.toLowerCase(name.charAt(3))
-            + (name.length() >= 5 ? name.substring(4) : "");
+        PropertyName annotation = toReturn.method.getAnnotation(PropertyName.class);
+        if (annotation != null) {
+          toReturn.propertyName = annotation.value();
+        } else {
+          String name = toReturn.method.getName();
+          // setFoo
+          toReturn.propertyName = Character.toLowerCase(name.charAt(3))
+              + (name.length() >= 5 ? name.substring(4) : "");
+        }
       }
 
       try {
@@ -65,12 +73,19 @@
           method.getReturnType());
 
       if (!toReturn.isValueType) {
-        // See if it's a collection
+        // See if it's a collection or a map
         JClassType returnClass = method.getReturnType().isClassOrInterface();
         JClassType collectionInterface = oracle.findType(Collection.class.getCanonicalName());
+        JClassType mapInterface = oracle.findType(Map.class.getCanonicalName());
         if (collectionInterface.isAssignableFrom(returnClass)) {
-          toReturn.elementType = ModelUtils.findParameterizationOf(
-              collectionInterface, returnClass)[0];
+          JClassType[] parameterizations = ModelUtils.findParameterizationOf(
+              collectionInterface, returnClass);
+          toReturn.elementType = parameterizations[0];
+        } else if (mapInterface.isAssignableFrom(returnClass)) {
+          JClassType[] parameterizations = ModelUtils.findParameterizationOf(
+              mapInterface, returnClass);
+          toReturn.keyType = parameterizations[0];
+          toReturn.valueType = parameterizations[1];
         }
       }
     }
@@ -86,11 +101,13 @@
 
   private Action action;
   private JClassType elementType;
+  private JClassType keyType;
   private JMethod method;
   private boolean isNoWrap;
   private boolean isValueType;
   private String propertyName;
   private JMethod staticImpl;
+  private JClassType valueType;
 
   private AutoBeanMethod() {
   }
@@ -103,6 +120,10 @@
     return elementType;
   }
 
+  public JClassType getKeyType() {
+    return keyType;
+  }
+
   public JMethod getMethod() {
     return method;
   }
@@ -120,10 +141,18 @@
     return staticImpl;
   }
 
+  public JClassType getValueType() {
+    return valueType;
+  }
+
   public boolean isCollection() {
     return elementType != null;
   }
 
+  public boolean isMap() {
+    return keyType != null;
+  }
+
   public boolean isNoWrap() {
     return isNoWrap;
   }
diff --git a/user/src/com/google/gwt/editor/rebind/model/AutoBeanType.java b/user/src/com/google/gwt/autobean/rebind/model/AutoBeanType.java
similarity index 74%
rename from user/src/com/google/gwt/editor/rebind/model/AutoBeanType.java
rename to user/src/com/google/gwt/autobean/rebind/model/AutoBeanType.java
index 605047b..1697a9f 100644
--- a/user/src/com/google/gwt/editor/rebind/model/AutoBeanType.java
+++ b/user/src/com/google/gwt/autobean/rebind/model/AutoBeanType.java
@@ -13,11 +13,11 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.rebind.model;
+package com.google.gwt.autobean.rebind.model;
 
+import com.google.gwt.autobean.rebind.model.AutoBeanMethod.Action;
 import com.google.gwt.core.ext.typeinfo.JClassType;
 import com.google.gwt.core.ext.typeinfo.JMethod;
-import com.google.gwt.editor.rebind.model.AutoBeanMethod.Action;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -33,9 +33,15 @@
    * Builder.
    */
   public static class Builder {
+    private boolean affectedByCategories;
+    private String beanSimpleSourceName;
+    private String categorySuffix;
     private AutoBeanType toReturn = new AutoBeanType();
 
     public AutoBeanType build() {
+      // Different implementations necessary for category-affected impls
+      toReturn.simpleSourceName = beanSimpleSourceName
+          + (affectedByCategories ? categorySuffix : "");
       try {
         return toReturn;
       } finally {
@@ -44,6 +50,7 @@
     }
 
     public void setInterceptor(JMethod interceptor) {
+      affectedByCategories = interceptor != null;
       toReturn.interceptor = interceptor;
     }
 
@@ -64,10 +71,12 @@
 
       toReturn.simpleBean = true;
       for (AutoBeanMethod method : methods) {
-        if (method.getAction().equals(Action.CALL)
-            && method.getStaticImpl() == null) {
-          toReturn.simpleBean = false;
-          break;
+        if (method.getAction().equals(Action.CALL)) {
+          if (method.getStaticImpl() == null) {
+            toReturn.simpleBean = false;
+          } else {
+            affectedByCategories = true;
+          }
         }
       }
     }
@@ -76,6 +85,18 @@
       toReturn.noWrap = noWrap;
     }
 
+    public void setOwnerFactory(AutoBeanFactoryModel autoBeanFactoryModel) {
+      if (autoBeanFactoryModel.getCategoryTypes() == null) {
+        return;
+      }
+      StringBuilder sb = new StringBuilder();
+      for (JClassType category : autoBeanFactoryModel.getCategoryTypes()) {
+        sb.append("_").append(
+            category.getQualifiedSourceName().replace('.', '_'));
+      }
+      categorySuffix = sb.toString();
+    }
+
     public void setPeerType(JClassType type) {
       assert type.isParameterized() == null && type.isRawType() == null;
       toReturn.peerType = type;
@@ -84,7 +105,7 @@
         packageName = "emul." + packageName;
       }
       toReturn.packageName = packageName;
-      toReturn.simpleSourceName = type.getName().replace('.', '_') + "AutoBean";
+      beanSimpleSourceName = type.getName().replace('.', '_') + "AutoBean";
     }
   }
 
diff --git a/user/src/com/google/gwt/autobean/server/AutoBeanFactoryMagic.java b/user/src/com/google/gwt/autobean/server/AutoBeanFactoryMagic.java
new file mode 100644
index 0000000..e7a7071
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/AutoBeanFactoryMagic.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanFactory;
+import com.google.gwt.autobean.shared.AutoBeanFactory.Category;
+import com.google.gwt.autobean.shared.AutoBeanFactory.NoWrap;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+
+/**
+ * Generates JVM-compatible implementations of AutoBeanFactory and AutoBean
+ * types.
+ * <p>
+ * NB: This implementation is excessively dynamic, however, the inability to
+ * create a TypeOracle fram a ClassLoader prevents re-using the existing model
+ * code. If the model code could be reused, it would be straightforward to
+ * simply generate implementations of the various interfaces.
+ * <p>
+ * This implementation is written assuming that the AutoBeanFactory and
+ * associated declarations will validate if compiled and used with the
+ * AutoBeanFactoyModel.
+ */
+public class AutoBeanFactoryMagic {
+  /**
+   * Create an instance of an AutoBeanFactory.
+   * 
+   * @param <F> the factory type
+   * @param clazz the Class representing the factory interface
+   * @return an instance of the AutoBeanFactory
+   */
+  public static <F extends AutoBeanFactory> F create(Class<F> clazz) {
+    Configuration.Builder builder = new Configuration.Builder();
+    Category cat = clazz.getAnnotation(Category.class);
+    if (cat != null) {
+      builder.setCategories(cat.value());
+    }
+    NoWrap noWrap = clazz.getAnnotation(NoWrap.class);
+    if (noWrap != null) {
+      builder.setNoWrap(noWrap.value());
+    }
+
+    return makeProxy(clazz, new FactoryHandler(builder.build()));
+  }
+
+  /**
+   * Create an instance of an AutoBean directly.
+   * 
+   * @param <T> the interface type implemented by the AutoBean
+   * @param clazz the interface type implemented by the AutoBean
+   * @return an instance of an AutoBean
+   */
+  public static <T> AutoBean<T> createBean(Class<T> clazz,
+      Configuration configuration) {
+    return new ProxyAutoBean<T>(clazz, configuration);
+  }
+
+  /**
+   * Utility method to crete a new {@link Proxy} instance.
+   * 
+   * @param <T> the interface type to be implemented by the Proxy
+   * @param intf the Class representing the interface type
+   * @param handler the implementation of the interface
+   * @return a Proxy instance
+   */
+  static <T> T makeProxy(Class<T> intf, InvocationHandler handler) {
+    return intf.cast(Proxy.newProxyInstance(
+        Thread.currentThread().getContextClassLoader(), new Class<?>[]{intf},
+        handler));
+  }
+}
diff --git a/user/src/com/google/gwt/autobean/server/BeanMethod.java b/user/src/com/google/gwt/autobean/server/BeanMethod.java
new file mode 100644
index 0000000..43b13e2
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/BeanMethod.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import com.google.gwt.autobean.server.impl.TypeUtils;
+import com.google.gwt.autobean.shared.AutoBean;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * Breakout of method types that an AutoBean shim interface can implement. The
+ * order of the values of the enum is important.
+ */
+enum BeanMethod {
+  /**
+   * Methods defined in Object.
+   */
+  OBJECT {
+    @Override
+    Object invoke(SimpleBeanHandler<?> handler, Method method, Object[] args)
+        throws Throwable {
+      if (CALL.matches(handler, method)) {
+        return CALL.invoke(handler, method, args);
+      }
+      return method.invoke(handler, args);
+    }
+
+    @Override
+    boolean matches(SimpleBeanHandler<?> handler, Method method) {
+      return method.getDeclaringClass().equals(Object.class);
+    }
+  },
+  /**
+   * Getters.
+   */
+  GET {
+    @Override
+    Object invoke(SimpleBeanHandler<?> handler, Method method, Object[] args) {
+      Object toReturn = handler.getBean().getValues().get(
+          method.getName().substring(3));
+      if (toReturn == null && method.getReturnType().isPrimitive()) {
+        toReturn = TypeUtils.getDefaultPrimitiveValue(method.getReturnType());
+      }
+      return toReturn;
+    }
+
+    @Override
+    boolean matches(SimpleBeanHandler<?> handler, Method method) {
+      return method.getName().startsWith("get")
+          && method.getParameterTypes().length == 0
+          && !method.getReturnType().equals(Void.TYPE);
+    }
+  },
+  /**
+   * Setters.
+   */
+  SET {
+    @Override
+    Object invoke(SimpleBeanHandler<?> handler, Method method, Object[] args) {
+      handler.getBean().getValues().put(method.getName().substring(3), args[0]);
+      return null;
+    }
+
+    @Override
+    boolean matches(SimpleBeanHandler<?> handler, Method method) {
+      return method.getName().startsWith("set")
+          && method.getParameterTypes().length == 1
+          && method.getReturnType().equals(Void.TYPE);
+    }
+  },
+  /**
+   * Domain methods.
+   */
+  CALL {
+    @Override
+    Object invoke(SimpleBeanHandler<?> handler, Method method, Object[] args)
+        throws Throwable {
+      if (args == null) {
+        args = EMPTY_OBJECT;
+      }
+
+      Method found = findMethod(handler, method);
+      if (found != null) {
+        Object[] realArgs = new Object[args.length + 1];
+        realArgs[0] = handler.getBean();
+        System.arraycopy(args, 0, realArgs, 1, args.length);
+        return found.invoke(null, realArgs);
+      }
+      throw new RuntimeException("Could not find category implementation of "
+          + method.toGenericString());
+    }
+
+    @Override
+    boolean matches(SimpleBeanHandler<?> handler, Method method) {
+      return handler.getBean().isWrapper()
+          || !handler.getBean().getConfiguration().getCategories().isEmpty()
+          && findMethod(handler, method) != null;
+    }
+  };
+
+  private static final Object[] EMPTY_OBJECT = new Object[0];
+
+  static Method findMethod(SimpleBeanHandler<?> handler, Method method) {
+    Class<?>[] declaredParams = method.getParameterTypes();
+    Class<?>[] searchParams = new Class<?>[declaredParams.length + 1];
+    searchParams[0] = AutoBean.class;
+    System.arraycopy(declaredParams, 0, searchParams, 1, declaredParams.length);
+
+    for (Class<?> clazz : handler.getBean().getConfiguration().getCategories()) {
+      try {
+        Method found = clazz.getMethod(method.getName(), searchParams);
+        if (Modifier.isStatic(found.getModifiers())) {
+          return found;
+        }
+      } catch (NoSuchMethodException expected) {
+      } catch (IllegalArgumentException e) {
+        throw new RuntimeException(e);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Invoke the method.
+   */
+  abstract Object invoke(SimpleBeanHandler<?> handler, Method method,
+      Object[] args) throws Throwable;
+
+  /**
+   * Convenience method, not valid for {@link BeanMethod#CALL}.
+   */
+  boolean matches(Method method) {
+    return matches(null, method);
+  }
+
+  /**
+   * Determine if the method maches the given type.
+   */
+  abstract boolean matches(SimpleBeanHandler<?> handler, Method method);
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/autobean/server/BeanPropertyContext.java b/user/src/com/google/gwt/autobean/server/BeanPropertyContext.java
new file mode 100644
index 0000000..f0014b7
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/BeanPropertyContext.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import com.google.gwt.autobean.server.impl.TypeUtils;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+/**
+ * A property context that allows setters to be called on a simple peer,
+ * regardless of whether or not the interface actually has a setter.
+ */
+class BeanPropertyContext extends MethodPropertyContext {
+  private final String propertyName;
+  private final Map<String, Object> map;
+
+  public BeanPropertyContext(ProxyAutoBean<?> bean, Method getter) {
+    super(getter);
+    propertyName = getter.getName().substring(3);
+    map = bean.getPropertyMap();
+  }
+
+  @Override
+  public boolean canSet() {
+    return true;
+  }
+
+  @Override
+  public void set(Object value) {
+    map.put(propertyName, TypeUtils.maybeAutobox(getType()).cast(value));
+  }
+}
diff --git a/user/src/com/google/gwt/autobean/server/Configuration.java b/user/src/com/google/gwt/autobean/server/Configuration.java
new file mode 100644
index 0000000..31942e9
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/Configuration.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import com.google.gwt.autobean.shared.AutoBean;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Used by {@link AutoBeanFactoryMagic#createBean()}.
+ */
+public class Configuration {
+  /**
+   * Builds {@link Configuration} objects.
+   */
+  public static class Builder {
+    private Configuration toReturn = new Configuration();
+
+    public Configuration build() {
+      toReturn.noWrap.add(AutoBean.class);
+      toReturn.noWrap = Collections.unmodifiableSet(toReturn.noWrap);
+      try {
+        return toReturn;
+      } finally {
+        toReturn = null;
+      }
+    }
+
+    public Builder setCategories(Class<?>... categories) {
+      toReturn.categories = Collections.unmodifiableList(new ArrayList<Class<?>>(
+          Arrays.asList(categories)));
+      return this;
+    }
+
+    public Builder setNoWrap(Class<?>... noWrap) {
+      toReturn.noWrap.addAll(Arrays.asList(noWrap));
+      return this;
+    }
+  }
+
+  private List<Class<?>> categories = Collections.emptyList();
+
+  private Set<Class<?>> noWrap = new HashSet<Class<?>>();
+
+  private Configuration() {
+  }
+
+  public List<Class<?>> getCategories() {
+    return categories;
+  }
+
+  public Set<Class<?>> getNoWrap() {
+    return noWrap;
+  }
+}
diff --git a/user/src/com/google/gwt/autobean/server/FactoryHandler.java b/user/src/com/google/gwt/autobean/server/FactoryHandler.java
new file mode 100644
index 0000000..8e2ceaf
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/FactoryHandler.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import com.google.gwt.autobean.shared.AutoBeanUtils;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+
+/**
+ * Handles dispatches on AutoBeanFactory interfaces.
+ */
+class FactoryHandler implements InvocationHandler {
+  private final Configuration configuration;
+
+  /**
+   * Constructor.
+   * 
+   * @param categories the classes specified by a Category annotation
+   */
+  public FactoryHandler(Configuration configuration) {
+    this.configuration = configuration;
+  }
+
+  /**
+   * Handles both declared factory methods as well as the dynamic create
+   * methods.
+   */
+  public Object invoke(Object proxy, Method method, Object[] args)
+      throws Throwable {
+
+    Class<?> beanType;
+    Object toWrap = null;
+    if (method.getName().equals("create")) {
+      // Dynamic create. Guaranteed to have at least one argument
+      // create(clazz); or create(clazz, toWrap);
+      beanType = (Class<?>) args[0];
+      if (args.length == 2) {
+        toWrap = args[1];
+      }
+    } else {
+      // Declared factory method, use the parameterization
+      // AutoBean<Foo> foo(); or Autobean<foo> foo(Foo toWrap);
+      ParameterizedType returnType = (ParameterizedType) method.getGenericReturnType();
+      beanType = (Class<?>) returnType.getActualTypeArguments()[0];
+
+      if (args != null && args.length == 1) {
+        toWrap = args[0];
+      }
+    }
+
+    // Return any existing wrapper
+    ProxyAutoBean<Object> toReturn = (ProxyAutoBean<Object>) AutoBeanUtils.getAutoBean(toWrap);
+    if (toReturn == null) {
+      // Create the implementation bean
+      if (toWrap == null) {
+        toReturn = new ProxyAutoBean<Object>(beanType, configuration);
+      } else {
+        toReturn = new ProxyAutoBean<Object>(beanType, configuration, toWrap);
+      }
+    }
+
+    return toReturn;
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/autobean/server/GetterPropertyContext.java b/user/src/com/google/gwt/autobean/server/GetterPropertyContext.java
new file mode 100644
index 0000000..ed904ea
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/GetterPropertyContext.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Used by {@link ProxyAutoBean#traverseProperties()}.
+ */
+class GetterPropertyContext extends MethodPropertyContext {
+  private final Method setter;
+  private final Object shim;
+
+  GetterPropertyContext(ProxyAutoBean<?> bean, Method getter) {
+    super(getter);
+    this.shim = bean.as();
+
+    // Look for the setter method.
+    Method found;
+    try {
+      found = bean.getBeanType().getMethod(
+          "set" + getter.getName().substring(3), getter.getReturnType());
+    } catch (NoSuchMethodException expected) {
+      found = null;
+    }
+    setter = found;
+  }
+
+  @Override
+  public boolean canSet() {
+    return setter != null;
+  }
+
+  @Override
+  public void set(Object value) {
+    if (!canSet()) {
+      throw new UnsupportedOperationException("No setter");
+    }
+    try {
+      setter.setAccessible(true);
+      setter.invoke(shim, value);
+    } catch (IllegalArgumentException e) {
+      throw new RuntimeException(e);
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    } catch (InvocationTargetException e) {
+      throw new RuntimeException(e.getCause());
+    }
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/autobean/server/MethodPropertyContext.java b/user/src/com/google/gwt/autobean/server/MethodPropertyContext.java
new file mode 100644
index 0000000..ac2653b
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/MethodPropertyContext.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import com.google.gwt.autobean.server.impl.TypeUtils;
+import com.google.gwt.autobean.shared.AutoBeanVisitor.CollectionPropertyContext;
+import com.google.gwt.autobean.shared.AutoBeanVisitor.MapPropertyContext;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * A base type to handle analyzing the return value of a getter method. The
+ * accessor methods are implemented in subtypes.
+ */
+abstract class MethodPropertyContext implements CollectionPropertyContext,
+    MapPropertyContext {
+  private final Class<?> keyType;
+  private final Class<?> valueType;
+  private final Class<?> elementType;
+  private final Class<?> type;
+
+  public MethodPropertyContext(Method getter) {
+    this.type = getter.getReturnType();
+
+    // Compute collection element type
+    if (Collection.class.isAssignableFrom(getType())) {
+      elementType = TypeUtils.ensureBaseType(TypeUtils.getSingleParameterization(
+          Collection.class, getter.getGenericReturnType(),
+          getter.getReturnType()));
+      keyType = valueType = null;
+    } else if (Map.class.isAssignableFrom(getType())) {
+      Type[] types = TypeUtils.getParameterization(Map.class,
+          getter.getGenericReturnType());
+      keyType = TypeUtils.ensureBaseType(types[0]);
+      valueType = TypeUtils.ensureBaseType(types[1]);
+      elementType = null;
+    } else {
+      elementType = keyType = valueType = null;
+    }
+  }
+
+  public abstract boolean canSet();
+
+  public Class<?> getElementType() {
+    return elementType;
+  }
+
+  public Class<?> getKeyType() {
+    return keyType;
+  }
+
+  public Class<?> getType() {
+    return type;
+  }
+
+  public Class<?> getValueType() {
+    return valueType;
+  }
+
+  public abstract void set(Object value);
+}
diff --git a/user/src/com/google/gwt/autobean/server/ProxyAutoBean.java b/user/src/com/google/gwt/autobean/server/ProxyAutoBean.java
new file mode 100644
index 0000000..b30b36c
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/ProxyAutoBean.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import com.google.gwt.autobean.server.impl.TypeUtils;
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanUtils;
+import com.google.gwt.autobean.shared.AutoBeanVisitor;
+import com.google.gwt.autobean.shared.impl.AbstractAutoBean;
+import com.google.gwt.core.client.impl.WeakMapping;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An implementation of an AutoBean that uses reflection.
+ * 
+ * @param <T> the type of interface being wrapped
+ */
+class ProxyAutoBean<T> extends AbstractAutoBean<T> {
+  private final Class<T> beanType;
+  private final Configuration configuration;
+  private final List<Method> getters;
+  private final T shim;
+
+  // These constructors mirror the generated constructors.
+  @SuppressWarnings("unchecked")
+  public ProxyAutoBean(Class<?> beanType, Configuration configuration) {
+    super();
+    this.beanType = (Class<T>) beanType;
+    this.configuration = configuration;
+    this.getters = calculateGetters();
+    this.shim = createShim();
+  }
+
+  @SuppressWarnings("unchecked")
+  public ProxyAutoBean(Class<?> beanType, Configuration configuration, T toWrap) {
+    super(toWrap);
+    if (Proxy.isProxyClass(toWrap.getClass())) {
+      System.out.println("blah");
+    }
+    this.beanType = (Class<T>) beanType;
+    this.configuration = configuration;
+    this.getters = calculateGetters();
+    this.shim = createShim();
+  }
+
+  private ProxyAutoBean(ProxyAutoBean<T> toClone, boolean deep) {
+    super(toClone, deep);
+    this.beanType = toClone.beanType;
+    this.configuration = toClone.configuration;
+    this.getters = toClone.getters;
+    this.shim = createShim();
+  }
+
+  @Override
+  public T as() {
+    return shim;
+  }
+
+  @Override
+  public AutoBean<T> clone(boolean deep) {
+    return new ProxyAutoBean<T>(this, deep);
+  }
+
+  public Configuration getConfiguration() {
+    return configuration;
+  }
+
+  public Class<T> getType() {
+    return beanType;
+  }
+
+  /**
+   * Allow access by {@link ShimHandler}.
+   */
+  @Override
+  protected void call(String method, Object returned, Object... parameters) {
+    super.call(method, returned, parameters);
+  }
+
+  /**
+   * Allow access by {@link ShimHandler}.
+   */
+  @Override
+  protected void checkFrozen() {
+    super.checkFrozen();
+  }
+
+  /**
+   * Allow access by {@link ShimHandler}.
+   */
+  @Override
+  protected void checkWrapped() {
+    super.checkWrapped();
+  }
+
+  @Override
+  protected T createSimplePeer() {
+    return AutoBeanFactoryMagic.makeProxy(beanType, new SimpleBeanHandler<T>(
+        this));
+  }
+
+  /**
+   * Allow access by {@link ShimHandler}.
+   */
+  @Override
+  protected <V> V get(String method, V toReturn) {
+    return super.get(method, toReturn);
+  }
+
+  /**
+   * Allow access by {@link BeanMethod}.
+   */
+  protected Map<String, Object> getValues() {
+    return values;
+  }
+
+  /**
+   * Allow access by {@link ShimHandler}.
+   */
+  protected T getWrapped() {
+    return super.getWrapped();
+  }
+
+  /**
+   * Allow access by {@link ShimHandler}.
+   */
+  @Override
+  protected void set(String method, Object value) {
+    super.set(method, value);
+  }
+
+  // TODO: Port to model-based when class-based TypeOracle is available.
+  @Override
+  protected void traverseProperties(AutoBeanVisitor visitor, OneShotContext ctx) {
+    for (final Method getter : getters) {
+      String name;
+      PropertyName annotation = getter.getAnnotation(PropertyName.class);
+      if (annotation != null) {
+        name = annotation.value();
+      } else {
+        name = getter.getName();
+        name = Character.toLowerCase(name.charAt(3))
+            + (name.length() >= 5 ? name.substring(4) : "");
+      }
+
+      // Use the shim to handle automatic wrapping
+      Object value;
+      try {
+        getter.setAccessible(true);
+        value = getter.invoke(shim);
+      } catch (IllegalArgumentException e) {
+        throw new RuntimeException(e);
+      } catch (IllegalAccessException e) {
+        throw new RuntimeException(e);
+      } catch (InvocationTargetException e) {
+        throw new RuntimeException(e.getCause());
+      }
+
+      // Create the context used for the property visitation
+      MethodPropertyContext x = isUsingSimplePeer() ? new BeanPropertyContext(
+          this, getter) : new GetterPropertyContext(this, getter);
+
+      if (TypeUtils.isValueType(x.getType())) {
+        if (visitor.visitValueProperty(name, value, x)) {
+        }
+        visitor.endVisitValueProperty(name, value, x);
+      } else if (Collection.class.isAssignableFrom(x.getType())) {
+        // Workaround for generics bug in mac javac 1.6.0_22
+        @SuppressWarnings("rawtypes")
+        AutoBean temp = AutoBeanUtils.getAutoBean((Collection) value);
+        @SuppressWarnings("unchecked")
+        AutoBean<Collection<?>> bean = (AutoBean<Collection<?>>) temp;
+        if (visitor.visitCollectionProperty(name, bean, x)) {
+          if (value != null) {
+            ((ProxyAutoBean<?>) bean).traverse(visitor, ctx);
+          }
+        }
+        visitor.endVisitCollectionProperty(name, bean, x);
+      } else if (Map.class.isAssignableFrom(x.getType())) {
+        // Workaround for generics bug in mac javac 1.6.0_22
+        @SuppressWarnings("rawtypes")
+        AutoBean temp = AutoBeanUtils.getAutoBean((Map) value);
+        @SuppressWarnings("unchecked")
+        AutoBean<Map<?, ?>> bean = (AutoBean<Map<?, ?>>) temp;
+        if (visitor.visitMapProperty(name, bean, x)) {
+          if (value != null) {
+            ((ProxyAutoBean<?>) bean).traverse(visitor, ctx);
+          }
+        }
+        visitor.endVisitMapProperty(name, bean, x);
+      } else {
+        ProxyAutoBean<?> bean = (ProxyAutoBean<?>) AutoBeanUtils.getAutoBean(value);
+        if (visitor.visitReferenceProperty(name, bean, x)) {
+          if (value != null) {
+            bean.traverse(visitor, ctx);
+          }
+        }
+        visitor.endVisitReferenceProperty(name, bean, x);
+      }
+    }
+  }
+
+  Class<?> getBeanType() {
+    return beanType;
+  }
+
+  Map<String, Object> getPropertyMap() {
+    return values;
+  }
+
+  private List<Method> calculateGetters() {
+    List<Method> toReturn = new ArrayList<Method>();
+    for (Method method : beanType.getMethods()) {
+      if (BeanMethod.GET.matches(method)) {
+        toReturn.add(method);
+      }
+    }
+    return Collections.unmodifiableList(toReturn);
+  }
+
+  private T createShim() {
+    T toReturn = AutoBeanFactoryMagic.makeProxy(beanType, new ShimHandler<T>(
+        this, getWrapped()));
+    WeakMapping.set(toReturn, AutoBean.class.getName(), this);
+    return toReturn;
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/autobean/server/ShimHandler.java b/user/src/com/google/gwt/autobean/server/ShimHandler.java
new file mode 100644
index 0000000..12e365d
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/ShimHandler.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import com.google.gwt.autobean.server.impl.TypeUtils;
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanUtils;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * Implements an AutoBean's shim interface that intercepts calls to the backing
+ * object.
+ * 
+ * @param <T> the interface type of the AutoBean
+ */
+class ShimHandler<T> implements InvocationHandler {
+  private final ProxyAutoBean<T> bean;
+  private final Method interceptor;
+  private final T toWrap;
+
+  public ShimHandler(ProxyAutoBean<T> bean, T toWrap) {
+    this.bean = bean;
+    this.toWrap = toWrap;
+
+    Method maybe = null;
+    for (Class<?> clazz : bean.getConfiguration().getCategories()) {
+      try {
+        maybe = clazz.getMethod("__intercept", AutoBean.class, Object.class);
+        break;
+      } catch (SecurityException expected) {
+      } catch (NoSuchMethodException expected) {
+      }
+    }
+    interceptor = maybe;
+  }
+
+  @Override
+  public boolean equals(Object couldBeShim) {
+    if (couldBeShim == null) {
+      return false;
+    }
+    // Handles the foo.equals(foo) case
+    if (Proxy.isProxyClass(couldBeShim.getClass())
+        && this == Proxy.getInvocationHandler(couldBeShim)) {
+      return true;
+    }
+    return bean.getWrapped().equals(couldBeShim);
+  }
+
+  @Override
+  public int hashCode() {
+    return bean.getWrapped().hashCode();
+  }
+
+  public Object invoke(Object proxy, Method method, Object[] args)
+      throws Throwable {
+    method.setAccessible(true);
+    Object toReturn;
+    String name = method.getName();
+    bean.checkWrapped();
+    method.setAccessible(true);
+    if (BeanMethod.OBJECT.matches(method)) {
+      return method.invoke(this, args);
+    } else if (BeanMethod.GET.matches(method)) {
+      toReturn = method.invoke(toWrap, args);
+      toReturn = bean.get(name, toReturn);
+    } else if (BeanMethod.SET.matches(method)) {
+      bean.checkFrozen();
+      toReturn = method.invoke(toWrap, args);
+      bean.set(name, args[0]);
+    } else {
+      // XXX How should freezing and calls work together?
+      // bean.checkFrozen();
+      toReturn = method.invoke(toWrap, args);
+      bean.call(name, toReturn, args);
+    }
+    Class<?> intf = method.getReturnType();
+    if (!Object.class.equals(intf)) {
+      // XXX Need to deal with resolving generic T return types
+      toReturn = maybeWrap(intf, toReturn);
+    }
+    if (interceptor != null) {
+      toReturn = interceptor.invoke(null, bean, toReturn);
+    }
+    return toReturn;
+  }
+
+  @Override
+  public String toString() {
+    return bean.getWrapped().toString();
+  }
+
+  private Object maybeWrap(Class<?> intf, Object toReturn) {
+    if (toReturn == null) {
+      return null;
+    }
+    if (TypeUtils.isValueType(intf)
+        || TypeUtils.isValueType(toReturn.getClass())
+        || AutoBeanUtils.getAutoBean(toReturn) != null
+        || bean.getConfiguration().getNoWrap().contains(intf)) {
+      return toReturn;
+    }
+    if (toReturn.getClass().isArray()) {
+      for (int i = 0, j = Array.getLength(toReturn); i < j; i++) {
+        Object value = Array.get(toReturn, i);
+        if (value != null) {
+          Array.set(toReturn, i, maybeWrap(value.getClass(), value));
+        }
+      }
+      return toReturn;
+    }
+    ProxyAutoBean<Object> newBean = new ProxyAutoBean<Object>(intf,
+        bean.getConfiguration(), toReturn);
+    return newBean.as();
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/autobean/server/SimpleBeanHandler.java b/user/src/com/google/gwt/autobean/server/SimpleBeanHandler.java
new file mode 100644
index 0000000..a15d27b
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/SimpleBeanHandler.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+/**
+ * Dynamic implementation of an AutoBean's simple peer object.
+ * 
+ * @param <T> the type of interface the shim allows access to
+ */
+class SimpleBeanHandler<T> implements InvocationHandler {
+  private final ProxyAutoBean<T> bean;
+
+  public SimpleBeanHandler(ProxyAutoBean<T> bean) {
+    this.bean = bean;
+  }
+
+  public ProxyAutoBean<T> getBean() {
+    return bean;
+  }
+
+  /**
+   * Delegates most work to {@link BeanMethod}.
+   */
+  public Object invoke(Object proxy, Method method, Object[] args)
+      throws Throwable {
+    for (BeanMethod type : BeanMethod.values()) {
+      if (type.matches(this, method)) {
+        Object toReturn = type.invoke(this, method, args);
+        return toReturn;
+      }
+    }
+    throw new RuntimeException("Unhandled invocation " + method.getName());
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/autobean/server/impl/JsonSplittable.java b/user/src/com/google/gwt/autobean/server/impl/JsonSplittable.java
new file mode 100644
index 0000000..6b9f22e
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/impl/JsonSplittable.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server.impl;
+
+import com.google.gwt.autobean.shared.Splittable;
+import com.google.gwt.autobean.shared.impl.StringQuoter;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Uses the org.json packages to slice and dice request payloads.
+ */
+public class JsonSplittable implements Splittable {
+  public static Splittable create(String payload) {
+    try {
+      switch (payload.charAt(0)) {
+        case '{':
+          return new JsonSplittable(new JSONObject(payload));
+        case '[':
+          return new JsonSplittable(new JSONArray(payload));
+        case '"':
+          return new JsonSplittable(
+              new JSONArray("[" + payload + "]").getString(0));
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+          return new JsonSplittable(payload);
+        default:
+          throw new RuntimeException("Could not parse payload: payload[0] = "
+              + payload.charAt(0));
+      }
+    } catch (JSONException e) {
+      throw new RuntimeException("Could not parse payload", e);
+    }
+  }
+
+  private final JSONArray array;
+  private final JSONObject obj;
+
+  private final String string;
+
+  private JsonSplittable(JSONArray array) {
+    this.array = array;
+    this.obj = null;
+    this.string = null;
+  }
+
+  private JsonSplittable(JSONObject obj) {
+    this.array = null;
+    this.obj = obj;
+    this.string = null;
+  }
+
+  private JsonSplittable(String string) {
+    this.array = null;
+    this.obj = null;
+    this.string = string;
+  }
+
+  public String asString() {
+    return string;
+  }
+
+  public Splittable get(int index) {
+    try {
+      return makeSplittable(array.get(index));
+    } catch (JSONException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public Splittable get(String key) {
+    try {
+      return makeSplittable(obj.get(key));
+    } catch (JSONException e) {
+      throw new RuntimeException(key, e);
+    }
+  }
+
+  public String getPayload() {
+    if (obj != null) {
+      return obj.toString();
+    }
+    if (array != null) {
+      return array.toString();
+    }
+    if (string != null) {
+      return StringQuoter.quote(string);
+    }
+    throw new RuntimeException("No data in this JsonSplittable");
+  }
+
+  public List<String> getPropertyKeys() {
+    String[] names = JSONObject.getNames(obj);
+    if (names == null) {
+      return Collections.emptyList();
+    } else {
+      return Collections.unmodifiableList(Arrays.asList(names));
+    }
+  }
+
+  public boolean isNull(int index) {
+    return array.isNull(index);
+  }
+
+  public boolean isNull(String key) {
+    // Treat undefined and null as the same
+    return !obj.has(key) || obj.isNull(key);
+  }
+
+  public int size() {
+    return array.length();
+  }
+
+  private JsonSplittable makeSplittable(Object object) {
+    if (object instanceof JSONObject) {
+      return new JsonSplittable((JSONObject) object);
+    }
+    if (object instanceof JSONArray) {
+      return new JsonSplittable((JSONArray) object);
+    }
+    return new JsonSplittable(object.toString());
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/autobean/server/impl/TypeUtils.java b/user/src/com/google/gwt/autobean/server/impl/TypeUtils.java
new file mode 100644
index 0000000..d4d954b
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/server/impl/TypeUtils.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server.impl;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Shared code for answering question about Class objects. This is a
+ * server-compatible analog to ModelUtils.
+ */
+public class TypeUtils {
+  static final Map<Class<?>, Class<?>> AUTOBOX_MAP;
+  static final Map<Class<?>, Object> DEFAULT_PRIMITIVE_VALUES;
+  @SuppressWarnings("unchecked")
+  static final Set<Class<?>> VALUE_TYPES = Collections.unmodifiableSet(new HashSet<Class<?>>(
+      Arrays.asList(Boolean.class, Character.class, Class.class, Date.class,
+          Enum.class, Number.class, String.class, Void.class)));
+
+  static {
+    Map<Class<?>, Object> temp = new HashMap<Class<?>, Object>();
+    temp.put(boolean.class, false);
+    temp.put(byte.class, (byte) 0);
+    temp.put(char.class, (char) 0);
+    temp.put(double.class, (double) 0);
+    temp.put(float.class, (float) 0);
+    temp.put(int.class, (int) 0);
+    temp.put(long.class, (long) 0);
+    temp.put(short.class, (short) 0);
+    temp.put(void.class, null);
+
+    DEFAULT_PRIMITIVE_VALUES = Collections.unmodifiableMap(temp);
+  }
+
+  static {
+    Map<Class<?>, Class<?>> autoBoxMap = new HashMap<Class<?>, Class<?>>();
+    autoBoxMap.put(byte.class, Byte.class);
+    autoBoxMap.put(char.class, Character.class);
+    autoBoxMap.put(double.class, Double.class);
+    autoBoxMap.put(float.class, Float.class);
+    autoBoxMap.put(int.class, Integer.class);
+    autoBoxMap.put(long.class, Long.class);
+    autoBoxMap.put(short.class, Short.class);
+    autoBoxMap.put(void.class, Void.class);
+    AUTOBOX_MAP = Collections.unmodifiableMap(autoBoxMap);
+  }
+
+  /**
+   * Similar to ModelUtils#ensureBaseType(JType) but for the reflection API.
+   */
+  public static Class<?> ensureBaseType(Type type) {
+    if (type instanceof Class<?>) {
+      return (Class<?>) type;
+    }
+    if (type instanceof GenericArrayType) {
+      return Array.newInstance(
+          ensureBaseType(((GenericArrayType) type).getGenericComponentType()),
+          0).getClass();
+    }
+    if (type instanceof ParameterizedType) {
+      return ensureBaseType(((ParameterizedType) type).getRawType());
+    }
+    if (type instanceof TypeVariable<?>) {
+      return ensureBaseType(((TypeVariable<?>) type).getBounds()[0]);
+    }
+    if (type instanceof WildcardType) {
+      WildcardType wild = (WildcardType) type;
+      return ensureBaseType(wild.getUpperBounds()[0]);
+    }
+    throw new RuntimeException("Cannot handle " + type.getClass().getName());
+  }
+
+  /**
+   * Given a primitive Class type, return a default value.
+   */
+  public static Object getDefaultPrimitiveValue(Class<?> clazz) {
+    assert clazz.isPrimitive() : "Expecting primitive type";
+    return DEFAULT_PRIMITIVE_VALUES.get(clazz);
+  }
+
+  public static Type[] getParameterization(Class<?> intf, Type... types) {
+    for (Type type : types) {
+      if (type == null) {
+        continue;
+      } else if (type instanceof ParameterizedType) {
+        ParameterizedType param = (ParameterizedType) type;
+        Type[] actualTypeArguments = param.getActualTypeArguments();
+        Class<?> base = ensureBaseType(param.getRawType());
+        Type[] typeParameters = base.getTypeParameters();
+
+        Map<Type, Type> map = new HashMap<Type, Type>();
+        for (int i = 0, j = typeParameters.length; i < j; i++) {
+          map.put(typeParameters[i], actualTypeArguments[i]);
+        }
+        Type[] lookFor = intf.equals(base) ? intf.getTypeParameters()
+            : getParameterization(intf, base.getGenericInterfaces());
+        List<Type> toReturn = new ArrayList<Type>();
+        for (int i = 0, j = lookFor.length; i < j; i++) {
+          Type found = map.get(lookFor[i]);
+          if (found != null) {
+            toReturn.add(found);
+          }
+        }
+        return toReturn.toArray(new Type[toReturn.size()]);
+      } else if (type instanceof Class<?>) {
+        Class<?> clazz = (Class<?>) type;
+        if (intf.equals(clazz)) {
+          return intf.getTypeParameters();
+        }
+        Type[] found = getParameterization(intf, clazz.getGenericSuperclass());
+        if (found != null) {
+          return found;
+        }
+        found = getParameterization(intf, clazz.getGenericInterfaces());
+        if (found != null) {
+          return found;
+        }
+      }
+    }
+    return null;
+  }
+
+  public static Type getSingleParameterization(Class<?> intf, Type... types) {
+    Type[] found = getParameterization(intf, types);
+    return found == null ? null : found[0];
+  }
+
+  public static boolean isValueType(Class<?> clazz) {
+    if (clazz.isPrimitive() || VALUE_TYPES.contains(clazz)) {
+      return true;
+    }
+    for (Class<?> c : VALUE_TYPES) {
+      if (c.isAssignableFrom(clazz)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public static Class<?> maybeAutobox(Class<?> domainType) {
+    Class<?> autoBoxType = AUTOBOX_MAP.get(domainType);
+    return autoBoxType == null ? domainType : autoBoxType;
+  }
+
+  private TypeUtils() {
+  }
+}
diff --git a/user/src/com/google/gwt/editor/client/AutoBean.java b/user/src/com/google/gwt/autobean/shared/AutoBean.java
similarity index 73%
rename from user/src/com/google/gwt/editor/client/AutoBean.java
rename to user/src/com/google/gwt/autobean/shared/AutoBean.java
index f90e621..025c341 100644
--- a/user/src/com/google/gwt/editor/client/AutoBean.java
+++ b/user/src/com/google/gwt/autobean/shared/AutoBean.java
@@ -13,7 +13,13 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.client;
+package com.google.gwt.autobean.shared;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
  * A controller for an implementation of a bean interface.
@@ -22,8 +28,22 @@
  */
 public interface AutoBean<T> {
   /**
+   * An annotation that allows inferred property names to be overridden.
+   * <p>
+   * This annotation is asymmetric, applying it to a getter will not affect the
+   * setter. The asymmetry allows existing users of an interface to read old
+   * {@link AutoBeanCodex} messages, but write new ones.
+   */
+  @Documented
+  @Retention(RetentionPolicy.RUNTIME)
+  @Target(ElementType.METHOD)
+  public @interface PropertyName {
+    String value();
+  }
+
+  /**
    * Accept an AutoBeanVisitor.
-   *
+   * 
    * @param visitor an {@link AutoBeanVisitor}
    */
   void accept(AutoBeanVisitor visitor);
@@ -31,7 +51,7 @@
   /**
    * Returns a proxy implementation of the <code>T</code> interface which will
    * delegate to the underlying wrapped object, if any.
-   *
+   * 
    * @return a proxy that delegates to the wrapped object
    */
   T as();
@@ -60,24 +80,28 @@
   <Q> Q getTag(String tagName);
 
   /**
-   * Returns the value most recently passed to {@link #setFrozen}, or {@code
-   * false} if it has never been called.
+   * Returns the wrapped interface type.
+   */
+  Class<T> getType();
+
+  /**
+   * Returns the value most recently passed to {@link #setFrozen}, or
+   * {@code false} if it has never been called.
    * 
    * @return {@code true} if this instance is frozen
    */
   boolean isFrozen();
 
   /**
-   * Returns {@code true} if the AutoBean was provided with an external
-   * object.
-   *
+   * Returns {@code true} if the AutoBean was provided with an external object.
+   * 
    * @return {@code true} if this instance is a wrapper
    */
   boolean isWrapper();
 
   /**
    * Disallows any method calls other than getters. All setter and call
-   * operations will throw an {@link UnsupportedOperationException}.
+   * operations will throw an {@link IllegalStateException}.
    * 
    * @param frozen if {@code true}, freeze this instance
    */
@@ -86,7 +110,7 @@
   /**
    * A tag is an arbitrary piece of external metadata to be associated with the
    * wrapped value.
-   *
+   * 
    * @param tagName the tag name
    * @param value the wrapped value
    * @see #getTag(String)
@@ -94,9 +118,9 @@
   void setTag(String tagName, Object value);
 
   /**
-   * If the AutoBean wraps an object, return the underlying object.
-   * The AutoBean will no longer function once unwrapped.
-   *
+   * If the AutoBean wraps an object, return the underlying object. The AutoBean
+   * will no longer function once unwrapped.
+   * 
    * @return the previously-wrapped object
    * @throws IllegalStateException if the AutoBean is not a wrapper
    */
diff --git a/user/src/com/google/gwt/autobean/shared/AutoBeanCodex.java b/user/src/com/google/gwt/autobean/shared/AutoBeanCodex.java
new file mode 100644
index 0000000..425271a
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/shared/AutoBeanCodex.java
@@ -0,0 +1,497 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.shared;
+
+import com.google.gwt.autobean.shared.impl.LazySplittable;
+import com.google.gwt.autobean.shared.impl.StringQuoter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+/**
+ * Utility methods for encoding an AutoBean graph into a JSON-compatible string.
+ * This codex intentionally does not preserve object identity, nor does it
+ * encode cycles, but it will detect them.
+ */
+public class AutoBeanCodex {
+  static class Decoder extends AutoBeanVisitor {
+    private final Stack<AutoBean<?>> beanStack = new Stack<AutoBean<?>>();
+    private final Stack<Splittable> dataStack = new Stack<Splittable>();
+    private AutoBean<?> bean;
+    private Splittable data;
+    private final AutoBeanFactory factory;
+
+    public Decoder(AutoBeanFactory factory) {
+      this.factory = factory;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> AutoBean<T> decode(Splittable data, Class<T> type) {
+      push(data, type);
+      bean.accept(this);
+      return (AutoBean<T>) pop();
+    }
+
+    @Override
+    public boolean visitCollectionProperty(String propertyName,
+        AutoBean<Collection<?>> value, CollectionPropertyContext ctx) {
+      if (data.isNull(propertyName)) {
+        return false;
+      }
+
+      Collection<Object> collection;
+      if (List.class.equals(ctx.getType())) {
+        collection = new ArrayList<Object>();
+      } else if (Set.class.equals(ctx.getType())) {
+        collection = new HashSet<Object>();
+      } else {
+        throw new UnsupportedOperationException("Only List and Set supported");
+      }
+
+      boolean isValue = ValueCodex.canDecode(ctx.getElementType());
+      boolean isEncoded = Splittable.class.equals(ctx.getElementType());
+      Splittable listData = data.get(propertyName);
+      for (int i = 0, j = listData.size(); i < j; i++) {
+        if (listData.isNull(i)) {
+          collection.add(null);
+        } else {
+          if (isValue) {
+            collection.add(ValueCodex.decode(ctx.getElementType(),
+                listData.get(i)));
+          } else if (isEncoded) {
+            collection.add(listData.get(i));
+          } else {
+            collection.add(decode(listData.get(i), ctx.getElementType()).as());
+          }
+        }
+      }
+      ctx.set(collection);
+      return false;
+    }
+
+    @Override
+    public boolean visitMapProperty(String propertyName,
+        AutoBean<Map<?, ?>> value, MapPropertyContext ctx) {
+      if (data.isNull(propertyName)) {
+        return false;
+      }
+
+      Map<?, ?> map;
+      if (ValueCodex.canDecode(ctx.getKeyType())) {
+        map = decodeValueKeyMap(data.get(propertyName), ctx.getKeyType(),
+            ctx.getValueType());
+      } else {
+        map = decodeObjectKeyMap(data.get(propertyName), ctx.getKeyType(),
+            ctx.getValueType());
+      }
+      ctx.set(map);
+      return false;
+    }
+
+    @Override
+    public boolean visitReferenceProperty(String propertyName,
+        AutoBean<?> value, PropertyContext ctx) {
+      if (data.isNull(propertyName)) {
+        return false;
+      }
+
+      if (Splittable.class.equals(ctx.getType())) {
+        ctx.set(data.get(propertyName));
+        return false;
+      }
+
+      push(data.get(propertyName), ctx.getType());
+      bean.accept(this);
+      ctx.set(pop().as());
+      return false;
+    }
+
+    @Override
+    public boolean visitValueProperty(String propertyName, Object value,
+        PropertyContext ctx) {
+      if (!data.isNull(propertyName)) {
+        Splittable propertyValue = data.get(propertyName);
+        ctx.set(ValueCodex.decode(ctx.getType(), propertyValue));
+      }
+      return false;
+    }
+
+    private Map<?, ?> decodeObjectKeyMap(Splittable map, Class<?> keyType,
+        Class<?> valueType) {
+      boolean isEncodedKey = Splittable.class.equals(keyType);
+      boolean isEncodedValue = Splittable.class.equals(valueType);
+      boolean isValueValue = Splittable.class.equals(valueType);
+
+      Splittable keyList = map.get(0);
+      Splittable valueList = map.get(1);
+      assert keyList.size() == valueList.size();
+
+      Map<Object, Object> toReturn = new HashMap<Object, Object>(keyList.size());
+      for (int i = 0, j = keyList.size(); i < j; i++) {
+        Object key;
+        if (isEncodedKey) {
+          key = keyList.get(i);
+        } else {
+          key = decode(keyList.get(i), keyType).as();
+        }
+
+        Object value;
+        if (valueList.isNull(i)) {
+          value = null;
+        } else if (isEncodedValue) {
+          value = keyList.get(i);
+        } else if (isValueValue) {
+          value = ValueCodex.decode(valueType, keyList.get(i));
+        } else {
+          value = decode(valueList.get(i), valueType).as();
+        }
+
+        toReturn.put(key, value);
+      }
+      return toReturn;
+    }
+
+    private Map<?, ?> decodeValueKeyMap(Splittable map, Class<?> keyType,
+        Class<?> valueType) {
+      Map<Object, Object> toReturn = new HashMap<Object, Object>();
+
+      boolean isEncodedValue = Splittable.class.equals(valueType);
+      boolean isValueValue = ValueCodex.canDecode(valueType);
+      for (String encodedKey : map.getPropertyKeys()) {
+        Object key = ValueCodex.decode(keyType, encodedKey);
+        Object value;
+        if (map.isNull(encodedKey)) {
+          value = null;
+        } else if (isEncodedValue) {
+          value = map.get(encodedKey);
+        } else if (isValueValue) {
+          value = ValueCodex.decode(valueType, map.get(encodedKey));
+        } else {
+          value = decode(map.get(encodedKey), valueType).as();
+        }
+        toReturn.put(key, value);
+      }
+
+      return toReturn;
+    }
+
+    private AutoBean<?> pop() {
+      dataStack.pop();
+      if (dataStack.isEmpty()) {
+        data = null;
+      } else {
+        data = dataStack.peek();
+      }
+      AutoBean<?> toReturn = beanStack.pop();
+      if (beanStack.isEmpty()) {
+        bean = null;
+      } else {
+        bean = beanStack.peek();
+      }
+      return toReturn;
+    }
+
+    private void push(Splittable data, Class<?> type) {
+      this.data = data;
+      bean = factory.create(type);
+      dataStack.push(data);
+      beanStack.push(bean);
+    }
+  }
+
+  static class Encoder extends AutoBeanVisitor {
+    private Set<AutoBean<?>> seen = new HashSet<AutoBean<?>>();
+    private Stack<StringBuilder> stack = new Stack<StringBuilder>();
+    private StringBuilder sb;
+
+    @Override
+    public void endVisit(AutoBean<?> bean, Context ctx) {
+      if (sb.length() == 0) {
+        // No properties
+        sb.append("{");
+      } else {
+        sb.setCharAt(0, '{');
+      }
+      sb.append("}");
+    }
+
+    @Override
+    public void endVisitReferenceProperty(String propertyName,
+        AutoBean<?> value, PropertyContext ctx) {
+      StringBuilder popped = pop();
+      if (popped.length() > 0) {
+        sb.append(",\"").append(propertyName).append("\":").append(
+            popped.toString());
+      }
+    }
+
+    @Override
+    public boolean visitCollectionProperty(String propertyName,
+        AutoBean<Collection<?>> value, CollectionPropertyContext ctx) {
+      push(new StringBuilder());
+
+      if (value == null) {
+        return false;
+      }
+
+      Collection<?> collection = value.as();
+      if (collection.isEmpty()) {
+        sb.append("[]");
+        return false;
+      }
+
+      if (ValueCodex.canDecode(ctx.getElementType())) {
+        for (Object element : collection) {
+          sb.append(",").append(ValueCodex.encode(element).getPayload());
+        }
+      } else {
+        boolean isEncoded = Splittable.class.equals(ctx.getElementType());
+        for (Object element : collection) {
+          sb.append(",");
+          if (element == null) {
+            sb.append("null");
+          } else if (isEncoded) {
+            sb.append(((Splittable) element).getPayload());
+          } else {
+            encodeToStringBuilder(sb, element);
+          }
+        }
+      }
+      sb.setCharAt(0, '[');
+      sb.append("]");
+      return false;
+    }
+
+    @Override
+    public boolean visitMapProperty(String propertyName,
+        AutoBean<Map<?, ?>> value, MapPropertyContext ctx) {
+      push(new StringBuilder());
+
+      if (value == null) {
+        return false;
+      }
+
+      Map<?, ?> map = value.as();
+      if (map.isEmpty()) {
+        sb.append("{}");
+        return false;
+      }
+
+      boolean isEncodedKey = Splittable.class.equals(ctx.getKeyType());
+      boolean isEncodedValue = Splittable.class.equals(ctx.getValueType());
+      boolean isValueKey = ValueCodex.canDecode(ctx.getKeyType());
+      boolean isValueValue = ValueCodex.canDecode(ctx.getValueType());
+
+      if (isValueKey) {
+        writeValueKeyMap(map, isEncodedValue, isValueValue);
+      } else {
+        writeObjectKeyMap(map, isEncodedKey, isEncodedValue, isValueValue);
+      }
+
+      return false;
+    }
+
+    @Override
+    public boolean visitReferenceProperty(String propertyName,
+        AutoBean<?> value, PropertyContext ctx) {
+      push(new StringBuilder());
+
+      if (value == null) {
+        return false;
+      }
+
+      if (Splittable.class.equals(ctx.getType())) {
+        sb.append(((Splittable) value.as()).getPayload());
+        return false;
+      }
+
+      if (seen.contains(value)) {
+        haltOnCycle();
+      }
+
+      return true;
+    }
+
+    @Override
+    public boolean visitValueProperty(String propertyName, Object value,
+        PropertyContext ctx) {
+      // Skip primitive types whose values are uninteresting.
+      if (value != null) {
+        if (value.equals(ValueCodex.getUninitializedFieldValue(ctx.getType()))) {
+          return false;
+        }
+      }
+      sb.append(",\"").append(propertyName).append("\":").append(
+          ValueCodex.encode(value).getPayload());
+      return false;
+    }
+
+    StringBuilder pop() {
+      StringBuilder toReturn = stack.pop();
+      sb = stack.peek();
+      return toReturn;
+    }
+
+    void push(StringBuilder sb) {
+      stack.push(sb);
+      this.sb = sb;
+    }
+
+    private void encodeToStringBuilder(StringBuilder accumulator, Object value) {
+      push(new StringBuilder());
+      AutoBean<?> bean = AutoBeanUtils.getAutoBean(value);
+      if (!seen.add(bean)) {
+        haltOnCycle();
+      }
+      bean.accept(this);
+      accumulator.append(pop().toString());
+      seen.remove(bean);
+    }
+
+    private void haltOnCycle() {
+      throw new HaltException(new UnsupportedOperationException(
+          "Cycle detected"));
+    }
+
+    /**
+     * Writes a map JSON literal where the keys are object types. This is
+     * encoded as a list of two lists, since it's possible that two distinct
+     * objects have the same encoded form.
+     */
+    private void writeObjectKeyMap(Map<?, ?> map, boolean isEncodedKey,
+        boolean isEncodedValue, boolean isValueValue) {
+      StringBuilder keys = new StringBuilder();
+      StringBuilder values = new StringBuilder();
+
+      for (Map.Entry<?, ?> entry : map.entrySet()) {
+        if (isEncodedKey) {
+          keys.append(",").append(((Splittable) entry.getKey()).getPayload());
+        } else {
+          encodeToStringBuilder(keys.append(","), entry.getKey());
+        }
+
+        if (isEncodedValue) {
+          values.append(",").append(
+              ((Splittable) entry.getValue()).getPayload());
+        } else if (isValueValue) {
+          values.append(",").append(
+              ValueCodex.encode(entry.getValue()).getPayload());
+        } else {
+          encodeToStringBuilder(values.append(","), entry.getValue());
+        }
+      }
+      keys.setCharAt(0, '[');
+      keys.append("]");
+      values.setCharAt(0, '[');
+      values.append("]");
+
+      sb.append("[").append(keys.toString()).append(",").append(
+          values.toString()).append("]");
+    }
+
+    /**
+     * Writes a map JSON literal where the keys are value types.
+     */
+    private void writeValueKeyMap(Map<?, ?> map, boolean isEncodedValue,
+        boolean isValueValue) {
+      for (Map.Entry<?, ?> entry : map.entrySet()) {
+        sb.append(",").append(ValueCodex.encode(entry.getKey()).getPayload()).append(
+            ":");
+        if (isEncodedValue) {
+          sb.append(((Splittable) entry.getValue()).getPayload());
+        } else if (isValueValue) {
+          sb.append(ValueCodex.encode(entry.getValue()).getPayload());
+        } else {
+          encodeToStringBuilder(sb, entry.getValue());
+        }
+      }
+      sb.setCharAt(0, '{');
+      sb.append("}");
+    }
+  }
+
+  /**
+   * Used to stop processing.
+   */
+  static class HaltException extends RuntimeException {
+    public HaltException(RuntimeException cause) {
+      super(cause);
+    }
+
+    @Override
+    public RuntimeException getCause() {
+      return (RuntimeException) super.getCause();
+    }
+  }
+
+  public static <T> AutoBean<T> decode(AutoBeanFactory factory, Class<T> clazz,
+      Splittable data) {
+    return new Decoder(factory).decode(data, clazz);
+  }
+
+  /**
+   * Decode an AutoBeanCodex payload.
+   * 
+   * @param <T> the expected return type
+   * @param factory an AutoBeanFactory capable of producing {@code AutoBean<T>}
+   * @param clazz the expected return type
+   * @param payload a payload string previously generated by
+   *          {@link #encode(AutoBean)}
+   * @return an AutoBean containing the payload contents
+   */
+  public static <T> AutoBean<T> decode(AutoBeanFactory factory, Class<T> clazz,
+      String payload) {
+    Splittable data = StringQuoter.split(payload);
+    return decode(factory, clazz, data);
+  }
+
+  /**
+   * Encodes an AutoBean. The actual payload contents can be retrieved through
+   * {@link Splittable#getPayload()}.
+   * 
+   * @param bean the bean to encode
+   * @return a Splittable that encodes the state of the AutoBean
+   */
+  public static Splittable encode(AutoBean<?> bean) {
+    if (bean == null) {
+      return LazySplittable.NULL;
+    }
+
+    StringBuilder sb = new StringBuilder();
+    encodeForJsoPayload(sb, bean);
+    return new LazySplittable(sb.toString());
+  }
+
+  // ["prop",value,"prop",value, ...]
+  private static void encodeForJsoPayload(StringBuilder sb, AutoBean<?> bean) {
+    Encoder e = new Encoder();
+    e.push(sb);
+    try {
+      bean.accept(e);
+    } catch (HaltException ex) {
+      throw ex.getCause();
+    }
+  }
+
+  private AutoBeanCodex() {
+  }
+}
diff --git a/user/src/com/google/gwt/editor/client/AutoBeanFactory.java b/user/src/com/google/gwt/autobean/shared/AutoBeanFactory.java
similarity index 98%
rename from user/src/com/google/gwt/editor/client/AutoBeanFactory.java
rename to user/src/com/google/gwt/autobean/shared/AutoBeanFactory.java
index 872e1b5..d5832e7 100644
--- a/user/src/com/google/gwt/editor/client/AutoBeanFactory.java
+++ b/user/src/com/google/gwt/autobean/shared/AutoBeanFactory.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.client;
+package com.google.gwt.autobean.shared;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
diff --git a/user/src/com/google/gwt/editor/client/AutoBeanUtils.java b/user/src/com/google/gwt/autobean/shared/AutoBeanUtils.java
similarity index 94%
rename from user/src/com/google/gwt/editor/client/AutoBeanUtils.java
rename to user/src/com/google/gwt/autobean/shared/AutoBeanUtils.java
index 2299b9f..129892d 100644
--- a/user/src/com/google/gwt/editor/client/AutoBeanUtils.java
+++ b/user/src/com/google/gwt/autobean/shared/AutoBeanUtils.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.client;
+package com.google.gwt.autobean.shared;
 
 import com.google.gwt.core.client.impl.WeakMapping;
 
@@ -35,7 +35,7 @@
    * although the diff produced is likely meaningless.
    * <p>
    * This will work for both simple and wrapper AutoBeans.
-   *
+   * 
    * @param a an {@link AutoBean}
    * @param b an {@link AutoBean}
    * @return a {@link Map} of differing properties
@@ -85,9 +85,9 @@
       }
 
       private boolean equal(String propertyName, Object previousValue) {
-        return previousValue == null && toReturn.get(propertyName) == null
-            || previousValue != null
-            && previousValue.equals(toReturn.get(propertyName));
+        Object currentValue = toReturn.get(propertyName);
+        return previousValue == null && currentValue == null
+            || previousValue != null && previousValue.equals(currentValue);
       }
     });
     return toReturn;
@@ -97,7 +97,7 @@
    * Returns a map that is a copy of the properties contained in an AutoBean.
    * The returned map is mutable, but editing it will not have any effect on the
    * bean that produced it.
-   *
+   * 
    * @param bean an {@link AutoBean}
    * @return a {@link Map} of the bean's properties
    */
@@ -125,8 +125,7 @@
 
   /**
    * Return the single AutoBean wrapper that is observing the delegate object or
-   * {@code null} if the parameter is {@code null}or not wrapped by
-   * an AutoBean.
+   * {@code null} if the parameter is {@code null}or not wrapped by an AutoBean.
    * 
    * @param delegate a delegate object, or {@code null}
    * @return the {@link AutoBean} wrapper for the delegate, or {@code null}
diff --git a/user/src/com/google/gwt/autobean/shared/AutoBeanVisitor.java b/user/src/com/google/gwt/autobean/shared/AutoBeanVisitor.java
new file mode 100644
index 0000000..49e81dc
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/shared/AutoBeanVisitor.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.shared;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Allows traversal of an AutoBean object graph.
+ */
+public class AutoBeanVisitor {
+  /**
+   * A PropertyContext that describes the parameterization of the Collection
+   * being visited.
+   */
+  public interface CollectionPropertyContext extends PropertyContext {
+    /**
+     * Returns the collection's element type.
+     * 
+     * @return a Class object representing the element type
+     */
+    Class<?> getElementType();
+  }
+
+  /**
+   * Reserved for future expansion to avoid API breaks.
+   */
+  public interface Context {
+  }
+
+  /**
+   * A PropertyContext that describes the parameterization of the Map being
+   * visited.
+   */
+  public interface MapPropertyContext extends PropertyContext {
+    /**
+     * Returns the map's key type.
+     * 
+     * @return a Class object representing the key type
+     */
+    Class<?> getKeyType();
+
+    /**
+     * Returns the map's value type.
+     * 
+     * @return a Class object representing the value type
+     */
+    Class<?> getValueType();
+  }
+
+  /**
+   * Allows properties to be reset.
+   */
+  public interface PropertyContext {
+    /**
+     * Indicates if the {@link #set} method will succeed.
+     * 
+     * @return {@code true} if the property can be set
+     */
+    boolean canSet();
+
+    /**
+     * Returns the expected type of the property.
+     * 
+     * @return a Class object representing the property type
+     */
+    Class<?> getType();
+
+    /**
+     * Sets a property value.
+     * 
+     * @param value the new value
+     */
+    void set(Object value);
+  }
+
+  /**
+   * Called after visiting an {@link AutoBean}.
+   * 
+   * @param bean an {@link AutoBean}
+   * @param ctx a Context
+   */
+  public void endVisit(AutoBean<?> bean, Context ctx) {
+  }
+
+  /**
+   * Called after visiting a reference property.
+   * 
+   * @param propertyName the property name, as a String
+   * @param value the property value
+   * @param ctx a PropertyContext
+   */
+  public void endVisitCollectionProperty(String propertyName,
+      AutoBean<Collection<?>> value, CollectionPropertyContext ctx) {
+    endVisitReferenceProperty(propertyName, value, ctx);
+  }
+
+  /**
+   * Called after visiting a reference property.
+   * 
+   * @param propertyName the property name, as a String
+   * @param value the property value
+   * @param ctx a PropertyContext
+   */
+  public void endVisitMapProperty(String propertyName,
+      AutoBean<Map<?, ?>> value, MapPropertyContext ctx) {
+    endVisitReferenceProperty(propertyName, value, ctx);
+  }
+
+  /**
+   * Called after visiting a reference property.
+   * 
+   * @param propertyName the property name, as a String
+   * @param value the property value
+   * @param ctx a PropertyContext
+   */
+  public void endVisitReferenceProperty(String propertyName, AutoBean<?> value,
+      PropertyContext ctx) {
+  }
+
+  /**
+   * Called after visiting a value property.
+   * 
+   * @param propertyName the property name, as a String
+   * @param value the property value
+   * @param ctx a PropertyContext
+   */
+  public void endVisitValueProperty(String propertyName, Object value,
+      PropertyContext ctx) {
+  }
+
+  /**
+   * Called when visiting an {@link AutoBean}.
+   * 
+   * @param bean an {@link AutoBean}
+   * @param ctx a Context
+   */
+  public boolean visit(AutoBean<?> bean, Context ctx) {
+    return true;
+  }
+
+  /**
+   * Called every time, but {@link #visit(AutoBean, Context)} will be called for
+   * the value only the first time it is encountered.
+   * 
+   * @param propertyName the property name, as a String
+   * @param value the property value
+   * @param ctx a PropertyContext
+   */
+  public boolean visitCollectionProperty(String propertyName,
+      AutoBean<Collection<?>> value, CollectionPropertyContext ctx) {
+    return visitReferenceProperty(propertyName, value, ctx);
+  }
+
+  /**
+   * Called every time, but {@link #visit(AutoBean, Context)} will be called for
+   * the value only the first time it is encountered.
+   * 
+   * @param propertyName the property name, as a String
+   * @param value the property value
+   * @param ctx a PropertyContext
+   */
+  public boolean visitMapProperty(String propertyName,
+      AutoBean<Map<?, ?>> value, MapPropertyContext ctx) {
+    return visitReferenceProperty(propertyName, value, ctx);
+  }
+
+  /**
+   * Called every time, but {@link #visit(AutoBean, Context)} will be called for
+   * the value only the first time it is encountered.
+   * 
+   * @param propertyName the property name, as a String
+   * @param value the property value
+   * @param ctx a PropertyContext
+   */
+  public boolean visitReferenceProperty(String propertyName, AutoBean<?> value,
+      PropertyContext ctx) {
+    return true;
+  }
+
+  /**
+   * TODO: document.
+   * 
+   * @param propertyName the property name, as a String
+   * @param value the property value
+   * @param ctx a PropertyContext
+   */
+  public boolean visitValueProperty(String propertyName, Object value,
+      PropertyContext ctx) {
+    return true;
+  }
+}
diff --git a/user/src/com/google/gwt/autobean/shared/Splittable.java b/user/src/com/google/gwt/autobean/shared/Splittable.java
new file mode 100644
index 0000000..0059d3c
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/shared/Splittable.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.shared;
+
+import java.util.List;
+
+/**
+ * This interface provides an abstraction around the underlying data model
+ * (JavaScriptObject, {@code org.json}, or XML) used to encode an AutoBeanCodex
+ * payload.
+ */
+public interface Splittable {
+  /**
+   * Returns a string representation of the data.
+   */
+  String asString();
+
+  /**
+   * Returns the nth element of a list.
+   */
+  Splittable get(int index);
+
+  /**
+   * Returns the named property.
+   */
+  Splittable get(String key);
+
+  /**
+   * Returns a wire-format representation of the data.
+   */
+  String getPayload();
+
+  /**
+   * Returns all keys available in the Splittable. This method may be expensive
+   * to compute.
+   */
+  List<String> getPropertyKeys();
+
+  /**
+   * Indicates if the nth element of a list is null.
+   */
+  boolean isNull(int index);
+
+  /**
+   * Indicates if the named property is null.
+   */
+  boolean isNull(String key);
+
+  /**
+   * Returns the size of the list.
+   */
+  int size();
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/requestfactory/shared/ValueCodex.java b/user/src/com/google/gwt/autobean/shared/ValueCodex.java
similarity index 60%
rename from user/src/com/google/gwt/requestfactory/shared/ValueCodex.java
rename to user/src/com/google/gwt/autobean/shared/ValueCodex.java
index 1763759..19ef456 100644
--- a/user/src/com/google/gwt/requestfactory/shared/ValueCodex.java
+++ b/user/src/com/google/gwt/autobean/shared/ValueCodex.java
@@ -13,9 +13,10 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.shared;
+package com.google.gwt.autobean.shared;
 
-import com.google.gwt.core.client.JsonUtils;
+import com.google.gwt.autobean.shared.impl.LazySplittable;
+import com.google.gwt.autobean.shared.impl.StringQuoter;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -33,26 +34,36 @@
       public BigDecimal decode(Class<?> clazz, String value) {
         return new BigDecimal(value);
       }
+
+      @Override
+      public String toJsonExpression(Object value) {
+        return StringQuoter.quote(((BigDecimal) value).toString());
+      }
     },
     BIG_INTEGER(BigInteger.class) {
       @Override
       public BigInteger decode(Class<?> clazz, String value) {
         return new BigInteger(value);
       }
+
+      @Override
+      public String toJsonExpression(Object value) {
+        return StringQuoter.quote(((BigInteger) value).toString());
+      }
     },
-    BOOLEAN(Boolean.class, boolean.class) {
+    BOOLEAN(Boolean.class, boolean.class, false) {
       @Override
       public Boolean decode(Class<?> clazz, String value) {
         return Boolean.valueOf(value);
       }
     },
-    BYTE(Byte.class, byte.class) {
+    BYTE(Byte.class, byte.class, (byte) 0) {
       @Override
       public Byte decode(Class<?> clazz, String value) {
         return Byte.valueOf(value);
       }
     },
-    CHARACTER(Character.class, char.class) {
+    CHARACTER(Character.class, char.class, (char) 0) {
       @Override
       public Character decode(Class<?> clazz, String value) {
         return value.charAt(0);
@@ -65,11 +76,11 @@
       }
 
       @Override
-      public String encode(Object value) {
+      public String toJsonExpression(Object value) {
         return String.valueOf(((Date) value).getTime());
       }
     },
-    DOUBLE(Double.class, double.class) {
+    DOUBLE(Double.class, double.class, 0d) {
       @Override
       public Double decode(Class<?> clazz, String value) {
         return Double.valueOf(value);
@@ -82,29 +93,35 @@
       }
 
       @Override
-      public String encode(Object value) {
+      public String toJsonExpression(Object value) {
         return String.valueOf(((Enum<?>) value).ordinal());
       }
     },
-    FLOAT(Float.class, float.class) {
+    FLOAT(Float.class, float.class, 0f) {
       @Override
       public Float decode(Class<?> clazz, String value) {
         return Float.valueOf(value);
       }
     },
-    INTEGER(Integer.class, int.class) {
+    INTEGER(Integer.class, int.class, 0) {
       @Override
       public Integer decode(Class<?> clazz, String value) {
         return Integer.valueOf(value);
       }
     },
-    LONG(Long.class, long.class) {
+    LONG(Long.class, long.class, 0L) {
       @Override
       public Long decode(Class<?> clazz, String value) {
         return Long.valueOf(value);
       }
+
+      @Override
+      public String toJsonExpression(Object value) {
+        // Longs cannot be expressed as a JS double
+        return StringQuoter.quote(String.valueOf((Long) value));
+      }
     },
-    SHORT(Short.class, short.class) {
+    SHORT(Short.class, short.class, (short) 0) {
       @Override
       public Short decode(Class<?> clazz, String value) {
         return Short.valueOf(value);
@@ -117,32 +134,34 @@
       }
 
       @Override
-      public String encode(Object value) {
-        return JsonUtils.escapeValue(String.valueOf(value));
+      public String toJsonExpression(Object value) {
+        return StringQuoter.quote((String) value);
       }
     },
-    VOID(Void.class, void.class) {
+    VOID(Void.class, void.class, null) {
       @Override
       public Void decode(Class<?> clazz, String value) {
         return null;
       }
     };
+    private final Object defaultValue;
     private final Class<?> type;
     private final Class<?> primitiveType;
 
     Type(Class<?> objectType) {
-      this(objectType, null);
+      this(objectType, null, null);
     }
 
-    Type(Class<?> objectType, Class<?> primitiveType) {
+    Type(Class<?> objectType, Class<?> primitiveType, Object defaultValue) {
       this.type = objectType;
       this.primitiveType = primitiveType;
+      this.defaultValue = defaultValue;
     }
 
     public abstract Object decode(Class<?> clazz, String value);
 
-    public String encode(Object value) {
-      return String.valueOf(value);
+    public Object getDefaultValue() {
+      return defaultValue;
     }
 
     public Class<?> getPrimitiveType() {
@@ -152,6 +171,10 @@
     public Class<?> getType() {
       return type;
     }
+
+    public String toJsonExpression(Object value) {
+      return String.valueOf(value);
+    }
   }
 
   private static Map<Class<?>, Type> typesByClass = new HashMap<Class<?>, Type>();
@@ -166,53 +189,67 @@
 
   /**
    * Returns true if ValueCodex can operate on values of the given type.
-   *
+   * 
    * @param clazz a Class object
    * @return {@code true} if the given object type can be decoded
    */
   public static boolean canDecode(Class<?> clazz) {
-    return typesByClass.containsKey(clazz);
+    return findType(clazz) != null;
   }
 
-  /**
-   * Convert an encoded representation of a value into a value.
-   * 
-   * @param <T> the type of value desired
-   * @param clazz the type of value desired
-   * @param encoded the encoded representation of the value
-   * @return the value
-   * @throws IllegalArgumentException if <code>clazz</code> is not a supported
-   *           value type
-   */
-  @SuppressWarnings("unchecked")
-  public static <T> T convertFromString(Class<T> clazz, String encoded) {
-    if (encoded == null) {
+  public static <T> T decode(Class<T> clazz, Splittable split) {
+    if (split == null || split == LazySplittable.NULL) {
       return null;
     }
-    return (T) getType(clazz).decode(clazz, encoded);
+    return decode(clazz, split.asString());
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T> T decode(Class<T> clazz, String string) {
+    if (string == null) {
+      return null;
+    }
+    return (T) getTypeOrDie(clazz).decode(clazz, string);
+  }
+
+  public static Splittable encode(Object obj) {
+    if (obj == null) {
+      return LazySplittable.NULL;
+    }
+    return new LazySplittable(
+        getTypeOrDie(obj.getClass()).toJsonExpression(obj));
   }
 
   /**
-   * Convert a value into an encoded string representation.
-   * 
-   * @param obj the value to encode
-   * @return an encoded representation of the object
-   * @throws IllegalArgumentException if <code>obj</code> is not of a supported
-   *           type
+   * Returns the uninitialized field value for the given primitive type.
    */
-  public static String encodeForJsonPayload(Object obj) {
-    return getType(obj.getClass()).encode(obj);
+  public static Object getUninitializedFieldValue(Class<?> clazz) {
+    Type type = getTypeOrDie(clazz);
+    if (clazz.equals(type.getPrimitiveType())) {
+      return type.getDefaultValue();
+    }
+    return null;
   }
 
-  private static <T> Type getType(Class<T> clazz) {
+  /**
+   * May return <code>null</code>.
+   */
+  private static <T> Type findType(Class<T> clazz) {
     Type type = typesByClass.get(clazz);
     if (type == null) {
       // Necessary due to lack of Class.isAssignable() in client-side
       if (clazz.getEnumConstants() != null) {
         return Type.ENUM;
       }
-      throw new IllegalArgumentException(clazz.getName());
     }
     return type;
   }
+
+  private static <T> Type getTypeOrDie(Class<T> clazz) {
+    Type toReturn = findType(clazz);
+    if (toReturn == null) {
+      throw new UnsupportedOperationException(clazz.getName());
+    }
+    return toReturn;
+  }
 }
diff --git a/user/src/com/google/gwt/editor/client/impl/AbstractAutoBean.java b/user/src/com/google/gwt/autobean/shared/impl/AbstractAutoBean.java
similarity index 89%
rename from user/src/com/google/gwt/editor/client/impl/AbstractAutoBean.java
rename to user/src/com/google/gwt/autobean/shared/impl/AbstractAutoBean.java
index a043a8c..95d1926 100644
--- a/user/src/com/google/gwt/editor/client/impl/AbstractAutoBean.java
+++ b/user/src/com/google/gwt/autobean/shared/impl/AbstractAutoBean.java
@@ -13,13 +13,13 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.client.impl;
+package com.google.gwt.autobean.shared.impl;
 
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanUtils;
+import com.google.gwt.autobean.shared.AutoBeanVisitor;
+import com.google.gwt.autobean.shared.AutoBeanVisitor.Context;
 import com.google.gwt.core.client.impl.WeakMapping;
-import com.google.gwt.editor.client.AutoBean;
-import com.google.gwt.editor.client.AutoBeanUtils;
-import com.google.gwt.editor.client.AutoBeanVisitor;
-import com.google.gwt.editor.client.AutoBeanVisitor.Context;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -37,6 +37,10 @@
    */
   public static class OneShotContext implements Context {
     private final Set<AbstractAutoBean<?>> seen = new HashSet<AbstractAutoBean<?>>();
+
+    public boolean hasSeen(AbstractAutoBean<?> bean) {
+      return !seen.add(bean);
+    }
   }
 
   protected static final Object[] EMPTY_OBJECT = new Object[0];
@@ -47,6 +51,7 @@
   protected final Map<String, Object> values;
 
   private boolean frozen;
+
   /**
    * Lazily initialized by {@link #setTag(String, Object)} because not all
    * instances will make use of tags.
@@ -61,10 +66,6 @@
   protected AbstractAutoBean() {
     usingSimplePeer = true;
     values = new HashMap<String, Object>();
-    wrapped = createSimplePeer();
-
-    // Used by AutoBeanUtils
-    WeakMapping.set(wrapped, AutoBean.class.getName(), this);
   }
 
   /**
@@ -79,7 +80,6 @@
     }
     usingSimplePeer = true;
     values = new HashMap<String, Object>(toClone.values);
-    wrapped = createSimplePeer();
 
     if (deep) {
       for (Map.Entry<String, Object> entry : values.entrySet()) {
@@ -89,9 +89,6 @@
         }
       }
     }
-
-    // Used by AutoBeanUtils
-    WeakMapping.set(wrapped, AutoBean.class.getName(), this);
   }
 
   /**
@@ -140,7 +137,7 @@
 
   public void traverse(AutoBeanVisitor visitor, OneShotContext ctx) {
     // Avoid cycles
-    if (!ctx.seen.add(this)) {
+    if (ctx.hasSeen(this)) {
       return;
     }
     if (visitor.visit(this, ctx)) {
@@ -178,7 +175,7 @@
   }
 
   protected void checkWrapped() {
-    if (wrapped == null) {
+    if (wrapped == null && !usingSimplePeer) {
       throw new IllegalStateException("The AutoBean has been unwrapped");
     }
   }
@@ -203,9 +200,17 @@
   }
 
   protected T getWrapped() {
+    if (wrapped == null) {
+      assert usingSimplePeer : "checkWrapped should have failed";
+      wrapped = createSimplePeer();
+    }
     return wrapped;
   }
 
+  protected boolean isUsingSimplePeer() {
+    return usingSimplePeer;
+  }
+
   protected boolean isWrapped(Object obj) {
     return AutoBeanUtils.getAutoBean(obj) != null;
   }
diff --git a/user/src/com/google/gwt/autobean/shared/impl/LazySplittable.java b/user/src/com/google/gwt/autobean/shared/impl/LazySplittable.java
new file mode 100644
index 0000000..3e804d1
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/shared/impl/LazySplittable.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.shared.impl;
+
+import com.google.gwt.autobean.shared.Splittable;
+
+import java.util.List;
+
+/**
+ * Holds a string payload with the expectation that the object will be used only
+ * for creating a larger payload.
+ */
+public class LazySplittable implements Splittable {
+  public static final Splittable NULL = new LazySplittable("null");
+
+  private final String payload;
+  private Splittable split;
+
+  public LazySplittable(String payload) {
+    this.payload = payload;
+  }
+
+  public String asString() {
+    maybeSplit();
+    return split.asString();
+  }
+
+  public Splittable get(int index) {
+    maybeSplit();
+    return split.get(index);
+  }
+
+  public Splittable get(String key) {
+    maybeSplit();
+    return split.get(key);
+  }
+
+  public String getPayload() {
+    return payload;
+  }
+
+  public List<String> getPropertyKeys() {
+    maybeSplit();
+    return split.getPropertyKeys();
+  }
+
+  public boolean isNull(int index) {
+    maybeSplit();
+    return split.isNull(index);
+  }
+
+  public boolean isNull(String key) {
+    maybeSplit();
+    return split.isNull(key);
+  }
+
+  public int size() {
+    maybeSplit();
+    return split.size();
+  }
+
+  private void maybeSplit() {
+    if (split == null) {
+      split = StringQuoter.split(payload);
+    }
+  }
+}
diff --git a/user/src/com/google/gwt/autobean/shared/impl/StringQuoter.java b/user/src/com/google/gwt/autobean/shared/impl/StringQuoter.java
new file mode 100644
index 0000000..9f65e5e
--- /dev/null
+++ b/user/src/com/google/gwt/autobean/shared/impl/StringQuoter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.shared.impl;
+
+import com.google.gwt.autobean.server.impl.JsonSplittable;
+import com.google.gwt.autobean.shared.Splittable;
+import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter;
+
+/**
+ * This class has a super-source version with a client-only implementation.
+ */
+public class StringQuoter {
+  /**
+   * Create a quoted JSON string.
+   */
+  public static String quote(String raw) {
+    return ServerSerializationStreamWriter.escapeString(raw);
+  }
+
+  public static Splittable split(String payload) {
+    return JsonSplittable.create(payload);
+  }
+}
diff --git a/user/src/com/google/gwt/core/client/impl/WeakMapping.java b/user/src/com/google/gwt/core/client/impl/WeakMapping.java
index 6afb310..4906f96 100644
--- a/user/src/com/google/gwt/core/client/impl/WeakMapping.java
+++ b/user/src/com/google/gwt/core/client/impl/WeakMapping.java
@@ -46,7 +46,7 @@
     /**
      * The identity hash code of the referent, cached during construction.
      */
-    private int hashCode;
+    private final int hashCode;
 
     public IdentityWeakReference(Object referent, ReferenceQueue<Object> queue) {
       super(referent, queue);
@@ -93,7 +93,7 @@
    * identity. Weak references are used to allow otherwise unreferenced Objects
    * to be garbage collected.
    */
-  private static Map<IdentityWeakReference, HashMap<String, Object>> map = new HashMap<IdentityWeakReference, HashMap<String, Object>>();
+  private static Map<IdentityWeakReference, Map<String, Object>> map = new HashMap<IdentityWeakReference, Map<String, Object>>();
 
   /**
    * A ReferenceQueue used to clean up the map as its keys are
@@ -109,11 +109,11 @@
    * @param key a String key.
    * @return an Object associated with that key on the given instance, or null.
    */
-  public static Object get(Object instance, String key) {
+  public static synchronized Object get(Object instance, String key) {
     cleanup();
 
     Object ref = new IdentityWeakReference(instance, queue);
-    HashMap<String, Object> m = map.get(ref);
+    Map<String, Object> m = map.get(ref);
     if (m == null) {
       return null;
     }
@@ -135,7 +135,7 @@
    *          Object.
    * @throws IllegalArgumentException if instance is a String.
    */
-  public static void set(Object instance, String key, Object value) {
+  public static synchronized void set(Object instance, String key, Object value) {
     cleanup();
 
     if (instance instanceof String) {
@@ -143,7 +143,7 @@
     }
 
     IdentityWeakReference ref = new IdentityWeakReference(instance, queue);
-    HashMap<String, Object> m = map.get(ref);
+    Map<String, Object> m = map.get(ref);
     if (m == null) {
       m = new HashMap<String, Object>();
       map.put(ref, m);
diff --git a/user/src/com/google/gwt/editor/Editor.gwt.xml b/user/src/com/google/gwt/editor/Editor.gwt.xml
index adda3ed..1fd667d 100644
--- a/user/src/com/google/gwt/editor/Editor.gwt.xml
+++ b/user/src/com/google/gwt/editor/Editor.gwt.xml
@@ -14,13 +14,11 @@
 <!-- Editor framework support -->
 <module>
   <inherits name="com.google.gwt.core.Core" />
-  
+
   <source path="client"/>
+  <source path="shared"/>
   <source path="ui/client"/>
-  
-  <generate-with class="com.google.gwt.editor.rebind.AutoBeanFactoryGenerator">
-    <when-type-assignable class="com.google.gwt.editor.client.AutoBeanFactory" />
-  </generate-with>
+
   <generate-with class="com.google.gwt.editor.rebind.SimpleBeanEditorDriverGenerator">
     <when-type-assignable class="com.google.gwt.editor.client.SimpleBeanEditorDriver" />
   </generate-with>
diff --git a/user/src/com/google/gwt/editor/client/AutoBeanVisitor.java b/user/src/com/google/gwt/editor/client/AutoBeanVisitor.java
deleted file mode 100644
index 40c14d1..0000000
--- a/user/src/com/google/gwt/editor/client/AutoBeanVisitor.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.editor.client;
-
-/**
- * Allows traversal of an AutoBean object graph.
- */
-public class AutoBeanVisitor {
-  /**
-   * Reserved for future expansion to avoid API breaks.
-   */
-  public interface Context {
-  }
-
-  /**
-   * Allows properties to be reset.
-   */
-  public interface PropertyContext {
-    /**
-     * Indicates if the {@link #set} method will succeed.
-     *
-     * @return {@code true} if the property can be set
-     */
-    boolean canSet();
-
-    /**
-     * If the reference property is a collection, returns the collection's
-     * element type.
-     * 
-     * @return a Class object representing the element type or {@code null} if
-     *         the property is not a collection type
-     */
-    Class<?> getElementType();
-
-    /**
-     * Returns the expected type of the property.
-     *
-     * @return a Class object representing the property type
-     */
-    Class<?> getType();
-
-    /**
-     * Sets a property value.
-     *
-     * @param value the new value
-     */
-    void set(Object value);
-  }
-
-  /**
-   * Called after visiting an {@link AutoBean}.
-   * 
-   * @param bean an {@link AutoBean}
-   * @param ctx a Context
-   */
-  public void endVisit(AutoBean<?> bean, Context ctx) {
-  }
-
-  /**
-   * Called after visiting a reference property.
-   * 
-   * @param propertyName the property name, as a String
-   * @param value the property value
-   * @param ctx a PropertyContext
-   */
-  public void endVisitReferenceProperty(String propertyName, AutoBean<?> value,
-      PropertyContext ctx) {
-  }
-
-  /**
-   * Called after visiting a value property.
-   * 
-   * @param propertyName the property name, as a String
-   * @param value the property value
-   * @param ctx a PropertyContext
-   */
-  public void endVisitValueProperty(String propertyName, Object value,
-      PropertyContext ctx) {
-  }
-
-  /**
-   * Called when visiting an {@link AutoBean}.
-   * 
-   * @param bean an {@link AutoBean}
-   * @param ctx a Context
-   */
-  public boolean visit(AutoBean<?> bean, Context ctx) {
-    return true;
-  }
-
-  /**
-   * Called every time, but {@link #visit(AutoBean, Context)} will be called for
-   * the value only the first time it is encountered.
-   * 
-   * @param propertyName the property name, as a String
-   * @param value the property value
-   * @param ctx a PropertyContext
-   */
-  public boolean visitReferenceProperty(String propertyName, AutoBean<?> value,
-      PropertyContext ctx) {
-    return true;
-  }
-
-  /**
-   * TODO: document.
-   * 
-   * @param propertyName the property name, as a String
-   * @param value the property value
-   * @param ctx a PropertyContext
-   */
-  public boolean visitValueProperty(String propertyName, Object value,
-      PropertyContext ctx) {
-    return true;
-  }
-}
diff --git a/user/src/com/google/gwt/editor/rebind/model/ModelUtils.java b/user/src/com/google/gwt/editor/rebind/model/ModelUtils.java
index 1a2c815..5545cd1 100644
--- a/user/src/com/google/gwt/editor/rebind/model/ModelUtils.java
+++ b/user/src/com/google/gwt/editor/rebind/model/ModelUtils.java
@@ -20,13 +20,11 @@
 import com.google.gwt.core.ext.typeinfo.JParameterizedType;
 import com.google.gwt.core.ext.typeinfo.JType;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.dev.util.collect.HashMap;
 
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -34,24 +32,19 @@
  */
 public class ModelUtils {
 
-  static final Map<Class<?>, Class<?>> AUTOBOX_MAP;
+  @SuppressWarnings("unchecked")
+  static final Set<Class<?>> VALUE_TYPES = Collections.unmodifiableSet(new HashSet<Class<?>>(
+      Arrays.asList(Boolean.class, Character.class, Class.class, Date.class,
+          Enum.class, Number.class, String.class, Void.class)));
 
-  static final Set<String> VALUE_TYPES = Collections.unmodifiableSet(new HashSet<String>(
-      Arrays.asList(Boolean.class.getName(), Character.class.getName(),
-          Class.class.getName(), Date.class.getName(), Enum.class.getName(),
-          Number.class.getName(), String.class.getName(), Void.class.getName())));
+  static final Set<String> VALUE_TYPE_NAMES;
 
   static {
-    Map<Class<?>, Class<?>> autoBoxMap = new HashMap<Class<?>, Class<?>>();
-    autoBoxMap.put(byte.class, Byte.class);
-    autoBoxMap.put(char.class, Character.class);
-    autoBoxMap.put(double.class, Double.class);
-    autoBoxMap.put(float.class, Float.class);
-    autoBoxMap.put(int.class, Integer.class);
-    autoBoxMap.put(long.class, Long.class);
-    autoBoxMap.put(short.class, Short.class);
-    autoBoxMap.put(void.class, Void.class);
-    AUTOBOX_MAP = Collections.unmodifiableMap(autoBoxMap);
+    Set<String> names = new HashSet<String>(VALUE_TYPES.size());
+    for (Class<?> clazz : VALUE_TYPES) {
+      names.add(clazz.getName());
+    }
+    VALUE_TYPE_NAMES = Collections.unmodifiableSet(names);
   }
 
   @SuppressWarnings("unchecked")
@@ -109,7 +102,7 @@
       return true;
     }
 
-    for (String valueType : VALUE_TYPES) {
+    for (String valueType : VALUE_TYPE_NAMES) {
       JClassType found = oracle.findType(valueType);
       // null check to accommodate limited mock CompilationStates
       if (found != null && found.isAssignableFrom(classType)) {
@@ -119,11 +112,6 @@
     return false;
   }
 
-  public static Class<?> maybeAutobox(Class<?> domainType) {
-    Class<?> autoBoxType = AUTOBOX_MAP.get(domainType);
-    return autoBoxType == null ? domainType : autoBoxType;
-  }
-
   private ModelUtils() {
   }
 }
diff --git a/user/src/com/google/gwt/requestfactory/RequestFactory.gwt.xml b/user/src/com/google/gwt/requestfactory/RequestFactory.gwt.xml
index 9ff3aba..c942293 100644
--- a/user/src/com/google/gwt/requestfactory/RequestFactory.gwt.xml
+++ b/user/src/com/google/gwt/requestfactory/RequestFactory.gwt.xml
@@ -17,6 +17,7 @@
 -->
 <module>
   <inherits name='com.google.gwt.core.Core'/>
+  <inherits name='com.google.gwt.autobean.AutoBean'/>
   <inherits name='com.google.gwt.editor.Editor'/>
   <inherits name='com.google.gwt.http.HTTP'/>
   <inherits name='com.google.gwt.logging.LoggingDisabled'/>
@@ -24,6 +25,7 @@
   <source path="client"/>
   <source path="shared"/>
   <source path="ui/client"/>
+  <super-source path="super" />
   <generate-with
     class="com.google.gwt.requestfactory.rebind.RequestFactoryEditorDriverGenerator">
     <when-type-assignable
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractClientRequestFactory.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractClientRequestFactory.java
new file mode 100644
index 0000000..2e6a312
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractClientRequestFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.client.impl;
+
+import com.google.gwt.event.shared.EventBus;
+import com.google.gwt.requestfactory.client.DefaultRequestTransport;
+import com.google.gwt.requestfactory.shared.impl.AbstractRequestFactory;
+
+/**
+ * A RequestFactory that uses a {@link DefaultRequestTransport} by default.
+ */
+public abstract class AbstractClientRequestFactory extends
+    AbstractRequestFactory {
+  @Override
+  public void initialize(EventBus eventBus) {
+    initialize(eventBus, new DefaultRequestTransport(eventBus));
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
deleted file mode 100644
index 66ec958..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl;
-
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.requestfactory.client.impl.messages.JsonResults;
-import com.google.gwt.requestfactory.client.impl.messages.JsonServerException;
-import com.google.gwt.requestfactory.client.impl.messages.RelatedObjects;
-import com.google.gwt.requestfactory.client.impl.messages.RequestData;
-import com.google.gwt.requestfactory.client.impl.messages.ReturnRecord;
-import com.google.gwt.requestfactory.shared.EntityProxy;
-import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.InstanceRequest;
-import com.google.gwt.requestfactory.shared.Receiver;
-import com.google.gwt.requestfactory.shared.Request;
-import com.google.gwt.requestfactory.shared.RequestContext;
-import com.google.gwt.requestfactory.shared.ServerFailure;
-import com.google.gwt.requestfactory.shared.Violation;
-import com.google.gwt.requestfactory.shared.WriteOperation;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * <p>
- * <span style="color:red">Experimental API: This class is still under rapid
- * development, and is very likely to be deleted. Use it at your own risk.
- * </span>
- * </p>
- * Abstract implementation of {@link Request}. Each request stores a
- * {@link DeltaValueStoreJsonImpl}.
- *
- * @param <T> return type
- */
-public abstract class AbstractRequest<T> implements Request<T>,
-    InstanceRequest<EntityProxy, T> {
-
-  /**
-   * Used by generated subtypes.
-   */
-  protected final Set<String> propertyRefs = new HashSet<String>();
-  protected final AbstractRequestContext requestContext;
-  private Receiver<? super T> receiver;
-  private RequestData requestData;
-
-  protected AbstractRequest(AbstractRequestContext requestContext) {
-    this.requestContext = requestContext;
-  }
-
-  public void fire() {
-    requestContext.fire();
-  }
-
-  public void fire(Receiver<? super T> receiver) {
-    to(receiver);
-    fire();
-  }
-
-  /**
-   * Returns the properties.
-   */
-  public Set<String> getPropertyRefs() {
-    return Collections.unmodifiableSet(propertyRefs);
-  }
-
-  public RequestData getRequestData() {
-    if (requestData == null) {
-      requestData = makeRequestData();
-    }
-    return requestData;
-  }
-
-  public void handleResponseText(String responseText) {
-    JsonResults results = JsonResults.fromResults(responseText);
-    JsonServerException cause = results.getException();
-    if (cause != null) {
-      fail(new ServerFailure(cause.getMessage(), cause.getType(),
-          cause.getTrace()));
-      return;
-    }
-    // handle violations
-    JsArray<ReturnRecord> violationsArray = results.getViolations();
-    if (violationsArray != null) {
-      processViolations(violationsArray);
-    } else {
-      requestContext.processSideEffects(results.getSideEffects());
-      processRelated(results.getRelated());
-      if (results.isNullResult()) {
-        // Indicates the server explicitly meant to send a null value
-        succeed(null);
-      } else {
-        handleResult(results.getResult());
-      }
-    }
-  }
-
-  public RequestContext to(Receiver<? super T> receiver) {
-    this.receiver = receiver;
-    return requestContext;
-  }
-
-  /**
-   * This method comes from the {@link InstanceRequest} interface. Instance
-   * methods place the instance in the first parameter slot.
-   */
-  public Request<T> using(EntityProxy instanceObject) {
-    getRequestData().getParameters()[0] = instanceObject;
-    /*
-     * Instance methods enqueue themselves when their using() method is called.
-     * This ensures that the instance parameter will have been set when
-     * AbstractRequestContext.retainArg() is called.
-     */
-    requestContext.addInvocation(this);
-    return this;
-  }
-
-  public Request<T> with(String... propertyRefs) {
-    this.propertyRefs.addAll(Arrays.asList(propertyRefs));
-    return this;
-  }
-
-  /**
-   * This method is called by generated subclasses to process the main return
-   * property of the JSON payload. The return record isn't just a reference to a
-   * persist or update side-effect, so it has to be processed separately.
-   */
-  protected <Q extends EntityProxy> Q decodeReturnObject(Class<Q> clazz,
-      Object obj) {
-    ReturnRecord jso = (ReturnRecord) obj;
-    SimpleEntityProxyId<Q> id = requestContext.getRequestFactory().getId(clazz,
-        jso.getSimpleId());
-    Q proxy = requestContext.processReturnRecord(id, (ReturnRecord) obj,
-        WriteOperation.UPDATE);
-    return proxy;
-  }
-
-  protected <Q extends EntityProxy> void decodeReturnObjectList(
-      Class<Q> elementType, Object obj, Collection<Q> accumulator) {
-    @SuppressWarnings("unchecked")
-    JsArray<ReturnRecord> array = (JsArray<ReturnRecord>) obj;
-    for (int i = 0, j = array.length(); i < j; i++) {
-      ReturnRecord record = array.get(i);
-      if (record == null) {
-        accumulator.add(null);
-        continue;
-      }
-
-      // Decode the individual object
-      Q decoded = decodeReturnObject(elementType, record);
-
-      // Really want Class.isInstance()
-      assert elementType.equals(decoded.stableId().getProxyClass());
-      accumulator.add(decoded);
-    }
-  }
-
-  protected <Q> void decodeReturnValueList(Class<Q> elementType, Object obj,
-      Collection<Q> accumulator) {
-    @SuppressWarnings("unchecked")
-    List<Q> temp = (List<Q>) EntityCodex.decode(List.class, elementType,
-        requestContext, obj);
-    accumulator.addAll(temp);
-  }
-
-  protected void fail(ServerFailure failure) {
-    requestContext.reuse();
-    if (receiver != null) {
-      receiver.onFailure(failure);
-    }
-  }
-
-  /**
-   * Process the response and call {@link #succeed(Object) or
-   * #fail(com.google.gwt.requestfactory.shared.ServerFailure).
-   */
-  protected abstract void handleResult(Object result);
-
-  protected boolean hasReceiver() {
-    return receiver != null;
-  }
-
-  protected abstract RequestData makeRequestData();
-
-  protected void processRelated(RelatedObjects related) {
-    for (String token : related.getHistoryTokens()) {
-      SimpleEntityProxyId<EntityProxy> id = requestContext.getRequestFactory().getProxyId(
-          token);
-      requestContext.processReturnRecord(id, related.getReturnRecord(token));
-    }
-  }
-
-  protected void succeed(T t) {
-    // The user may not have called to()
-    if (receiver != null) {
-      receiver.onSuccess(t);
-    }
-  }
-
-  private void processViolations(JsArray<ReturnRecord> violationsArray) {
-    int length = violationsArray.length();
-    Set<Violation> errors = new HashSet<Violation>(length);
-
-    for (int i = 0; i < length; i++) {
-      ReturnRecord violationRecord = violationsArray.get(i);
-      final EntityProxyId<?> key = requestContext.getRequestFactory().getId(
-          violationRecord.getSchema(), violationRecord.getEncodedId(),
-          violationRecord.getFutureId());
-
-      HashMap<String, String> violations = new HashMap<String, String>();
-      assert violationRecord.hasViolations();
-      violationRecord.fillViolations(violations);
-
-      for (Map.Entry<String, String> entry : violations.entrySet()) {
-        final String path = entry.getKey();
-        final String message = entry.getValue();
-        errors.add(new Violation() {
-          public String getMessage() {
-            return message;
-          }
-
-          public String getPath() {
-            return path;
-          }
-
-          public EntityProxyId<?> getProxyId() {
-            return key;
-          }
-        });
-      }
-    }
-
-    requestContext.reuse();
-    requestContext.addErrors(errors);
-    if (receiver != null) {
-      receiver.onViolation(errors);
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequestContext.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequestContext.java
deleted file mode 100644
index 2dbfd976..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequestContext.java
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl;
-
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.editor.client.AutoBean;
-import com.google.gwt.editor.client.AutoBeanUtils;
-import com.google.gwt.editor.client.AutoBeanVisitor;
-import com.google.gwt.requestfactory.client.impl.messages.RequestContentData;
-import com.google.gwt.requestfactory.client.impl.messages.ReturnRecord;
-import com.google.gwt.requestfactory.client.impl.messages.SideEffects;
-import com.google.gwt.requestfactory.shared.EntityProxy;
-import com.google.gwt.requestfactory.shared.EntityProxyChange;
-import com.google.gwt.requestfactory.shared.Receiver;
-import com.google.gwt.requestfactory.shared.RequestContext;
-import com.google.gwt.requestfactory.shared.RequestTransport.TransportReceiver;
-import com.google.gwt.requestfactory.shared.ServerFailure;
-import com.google.gwt.requestfactory.shared.ValueCodex;
-import com.google.gwt.requestfactory.shared.Violation;
-import com.google.gwt.requestfactory.shared.WriteOperation;
-import com.google.gwt.requestfactory.shared.impl.Constants;
-
-import java.util.ArrayList;
-import java.util.Collection;
-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;
-
-/**
- * Base implementations for RequestContext services.
- */
-public class AbstractRequestContext implements RequestContext {
-  private static final String PARENT_OBJECT = "parentObject";
-
-  private List<AbstractRequest<?>> invocations = new ArrayList<AbstractRequest<?>>();
-  private boolean locked;
-  private final AbstractRequestFactory requestFactory;
-  /**
-   * A map of all EntityProxies that the RequestContext has interacted with.
-   * Objects are placed into this map by being passed into {@link #edit} or as
-   * an invocation argument.
-   */
-  private final Map<SimpleEntityProxyId<?>, AutoBean<?>> editedProxies = new LinkedHashMap<SimpleEntityProxyId<?>, AutoBean<?>>();
-  private Set<Violation> errors = new LinkedHashSet<Violation>();
-  /**
-   * A map that contains the canonical instance of an entity to return in the
-   * return graph, since this is built from scratch.
-   */
-  private final Map<SimpleEntityProxyId<?>, AutoBean<?>> returnedProxies = new HashMap<SimpleEntityProxyId<?>, AutoBean<?>>();
-
-  protected AbstractRequestContext(AbstractRequestFactory factory) {
-    this.requestFactory = factory;
-  }
-
-  /**
-   * Create a new object, with an ephemeral id.
-   */
-  public <T extends EntityProxy> T create(Class<T> clazz) {
-    checkLocked();
-
-    AutoBean<T> created = requestFactory.createEntityProxy(clazz,
-        requestFactory.allocateId(clazz));
-    return takeOwnership(created);
-  }
-
-  public <T extends EntityProxy> T edit(T object) {
-    AutoBean<T> bean = checkStreamsNotCrossed(object);
-
-    checkLocked();
-
-    @SuppressWarnings("unchecked")
-    AutoBean<T> previouslySeen = (AutoBean<T>) editedProxies.get(object.stableId());
-    if (previouslySeen != null && !previouslySeen.isFrozen()) {
-      /*
-       * If we've seen the object before, it might be because it was passed in
-       * as a method argument. This does not guarantee its mutability, so check
-       * that here before returning the cached object.
-       */
-      return previouslySeen.as();
-    }
-
-    // Create editable copies
-    AutoBean<T> parent = bean;
-    bean = cloneBeanAndCollections(bean);
-    bean.setTag(PARENT_OBJECT, parent);
-    return takeOwnership(bean);
-  }
-
-  /**
-   * Make sure there's a default receiver so errors don't get dropped. This
-   * behavior should be revisited when chaining is supported, depending on
-   * whether or not chained invocations can fail independently.
-   */
-  public void fire() {
-    boolean needsReceiver = true;
-    for (AbstractRequest<?> request : invocations) {
-      if (request.hasReceiver()) {
-        needsReceiver = false;
-        break;
-      }
-    }
-
-    if (needsReceiver) {
-      doFire(new Receiver<Void>() {
-        @Override
-        public void onSuccess(Void response) {
-          // Don't care
-        }
-      });
-    } else {
-      doFire(null);
-    }
-  }
-
-  public void fire(final Receiver<Void> receiver) {
-    if (receiver == null) {
-      throw new IllegalArgumentException();
-    }
-    doFire(receiver);
-  }
-
-  public AbstractRequestFactory getRequestFactory() {
-    return requestFactory;
-  }
-
-  public boolean isChanged() {
-    /*
-     * NB: Don't use the presence of ephemeral objects for this test.
-     * 
-     * Diff the objects until one is found to be different. It's not just a
-     * simple flag-check because of the possibility of "unmaking" a change, per
-     * the JavaDoc.
-     */
-    for (AutoBean<?> bean : editedProxies.values()) {
-      AutoBean<?> previous = bean.getTag(PARENT_OBJECT);
-      if (previous == null) {
-        // Compare to empty object
-        Class<?> proxyClass = ((EntityProxy) bean.as()).stableId().getProxyClass();
-        previous = getRequestFactory().getAutoBeanFactory().create(proxyClass);
-      }
-      if (!AutoBeanUtils.diff(previous, bean).isEmpty()) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  public boolean isLocked() {
-    return locked;
-  }
-
-  public void reuse() {
-    freezeEntities(false);
-    locked = false;
-  }
-
-  /**
-   * Called by individual invocations to aggregate all errors.
-   */
-  protected void addErrors(Collection<Violation> errors) {
-    this.errors.addAll(errors);
-  }
-
-  /**
-   * Called by generated subclasses to enqueue a method invocation.
-   */
-  protected void addInvocation(AbstractRequest<?> request) {
-    if (invocations.size() > 0) {
-      // TODO(bobv): Upgrade wire protocol and server to handle chains
-      throw new IllegalStateException("Method chaining not implemented");
-    }
-    invocations.add(request);
-    for (Object arg : request.getRequestData().getParameters()) {
-      retainArg(arg);
-    }
-  }
-
-  /**
-   * Creates or retrieves a new canonical AutoBean to represent the given id in
-   * the returned payload.
-   */
-  <Q extends EntityProxy> AutoBean<Q> getProxyForReturnPayloadGraph(
-      SimpleEntityProxyId<Q> id) {
-    assert !id.isEphemeral();
-
-    @SuppressWarnings("unchecked")
-    AutoBean<Q> bean = (AutoBean<Q>) returnedProxies.get(id);
-    if (bean == null) {
-      Class<Q> proxyClass = id.getProxyClass();
-      bean = requestFactory.createEntityProxy(proxyClass, id);
-      returnedProxies.put(id, bean);
-    }
-
-    return bean;
-  }
-
-  /**
-   * Create a new EntityProxy from a snapshot in the return payload.
-   * 
-   * @param id the EntityProxyId of the object
-   * @param returnRecord the JSON map containing property/value pairs
-   * @param operations the WriteOperation eventns to broadcast over the EventBus
-   */
-  <Q extends EntityProxy> Q processReturnRecord(SimpleEntityProxyId<Q> id,
-      final ReturnRecord returnRecord, WriteOperation... operations) {
-
-    AutoBean<Q> toMutate = getProxyForReturnPayloadGraph(id);
-
-    // Apply updates
-    toMutate.accept(new AutoBeanVisitor() {
-      @Override
-      public boolean visitReferenceProperty(String propertyName,
-          AutoBean<?> value, PropertyContext ctx) {
-        if (ctx.canSet()) {
-          if (returnRecord.hasProperty(propertyName)) {
-            Object raw = returnRecord.get(propertyName);
-            if (returnRecord.isNull(propertyName)) {
-              ctx.set(null);
-            } else {
-              Object decoded = EntityCodex.decode(ctx.getType(),
-                  ctx.getElementType(), AbstractRequestContext.this, raw);
-              ctx.set(decoded);
-            }
-          }
-        }
-        return false;
-      }
-
-      @Override
-      public boolean visitValueProperty(String propertyName, Object value,
-          PropertyContext ctx) {
-        if (ctx.canSet()) {
-          if (returnRecord.hasProperty(propertyName)) {
-            Object raw = returnRecord.get(propertyName);
-            if (returnRecord.isNull(propertyName)) {
-              ctx.set(null);
-            } else {
-              Object decoded = ValueCodex.convertFromString(ctx.getType(),
-                  String.valueOf(raw));
-              ctx.set(decoded);
-            }
-          }
-        }
-        return false;
-      }
-    });
-
-    // Finished applying updates, freeze the bean
-    makeImmutable(toMutate);
-    Q proxy = toMutate.as();
-
-    /*
-     * Notify subscribers if the object differs from when it first came into the
-     * RequestContext.
-     */
-    if (operations != null) {
-      for (WriteOperation op : operations) {
-        if (op.equals(WriteOperation.UPDATE)
-            && !requestFactory.hasVersionChanged(id, returnRecord.getVersion())) {
-          // No updates if the server reports no change
-          continue;
-        }
-        requestFactory.getEventBus().fireEventFromSource(
-            new EntityProxyChange<EntityProxy>(proxy, op), id.getProxyClass());
-      }
-    }
-    return proxy;
-  }
-
-  /**
-   * Process a SideEffects message.
-   */
-  void processSideEffects(SideEffects sideEffects) {
-    JsArray<ReturnRecord> persisted = sideEffects.getPersist();
-    if (persisted != null) {
-      processReturnRecords(persisted, WriteOperation.PERSIST);
-    }
-    JsArray<ReturnRecord> updated = sideEffects.getUpdate();
-    if (updated != null) {
-      processReturnRecords(updated, WriteOperation.UPDATE);
-    }
-    JsArray<ReturnRecord> deleted = sideEffects.getDelete();
-    if (deleted != null) {
-      processReturnRecords(deleted, WriteOperation.DELETE);
-    }
-  }
-
-  private void checkLocked() {
-    if (locked) {
-      throw new IllegalStateException("A request is already in progress");
-    }
-  }
-
-  /**
-   * This method checks that a proxy object is either immutable, or already
-   * edited by this context.
-   */
-  private <T> AutoBean<T> checkStreamsNotCrossed(T object) {
-    AutoBean<T> bean = AutoBeanUtils.getAutoBean(object);
-    if (bean == null) {
-      // Unexpected; some kind of foreign implementation?
-      throw new IllegalArgumentException(object.getClass().getName());
-    }
-
-    RequestContext context = bean.getTag(EntityProxyCategory.REQUEST_CONTEXT);
-    if (!bean.isFrozen() && context != this) {
-      /*
-       * This means something is way off in the weeds. If a bean is editable,
-       * it's supposed to be associated with a RequestContext.
-       */
-      assert context != null : "Unfrozen bean with null RequestContext";
-
-      /*
-       * Already editing the object in another context or it would have been in
-       * the editing map.
-       */
-      throw new IllegalArgumentException("Attempting to edit an EntityProxy"
-          + " previously edited by another RequestContext");
-    }
-    return bean;
-  }
-
-  /**
-   * Shallow-clones an autobean and makes duplicates of the collection types. A
-   * regular {@link AutoBean#clone} won't duplicate reference properties.
-   */
-  private <T> AutoBean<T> cloneBeanAndCollections(AutoBean<T> toClone) {
-    AutoBean<T> clone = toClone.clone(false);
-    clone.accept(new AutoBeanVisitor() {
-      @Override
-      public boolean visitReferenceProperty(String propertyName,
-          AutoBean<?> value, PropertyContext ctx) {
-        if (value != null) {
-          if (List.class == ctx.getType()) {
-            ctx.set(new ArrayList<Object>((List<?>) value.as()));
-          } else if (Set.class == ctx.getType()) {
-            ctx.set(new HashSet<Object>((Set<?>) value.as()));
-          }
-        }
-        return false;
-      }
-    });
-    return clone;
-  }
-
-  private void doFire(final Receiver<Void> receiver) {
-    checkLocked();
-    locked = true;
-
-    freezeEntities(true);
-
-    String payload = makePayload();
-
-    requestFactory.getRequestTransport().send(payload, new TransportReceiver() {
-      public void onTransportFailure(String message) {
-        ServerFailure failure = new ServerFailure(message, null, null);
-        try {
-          // TODO: chained methods
-          assert invocations.size() == 1;
-          invocations.get(0).fail(failure);
-          if (receiver != null) {
-            receiver.onFailure(failure);
-          }
-        } finally {
-          postRequestCleanup();
-        }
-      }
-
-      public void onTransportSuccess(String payload) {
-        try {
-          // TODO: chained methods
-          assert invocations.size() == 1;
-          invocations.get(0).handleResponseText(payload);
-
-          if (receiver != null) {
-            if (errors.isEmpty()) {
-              receiver.onSuccess(null);
-              // After success, shut down the context
-              editedProxies.clear();
-              invocations.clear();
-              returnedProxies.clear();
-            } else {
-              receiver.onViolation(errors);
-            }
-          }
-        } finally {
-          postRequestCleanup();
-        }
-      }
-    });
-  }
-
-  /**
-   * Set the frozen status of all EntityProxies owned by this context.
-   */
-  private void freezeEntities(boolean frozen) {
-    for (AutoBean<?> bean : editedProxies.values()) {
-      bean.setFrozen(frozen);
-    }
-  }
-
-  /**
-   * Make an EntityProxy immutable.
-   */
-  private void makeImmutable(final AutoBean<? extends EntityProxy> toMutate) {
-    // Always diff'ed against itself, producing a no-op
-    toMutate.setTag(PARENT_OBJECT, toMutate);
-    // Act with entity-identity semantics
-    toMutate.setTag(EntityProxyCategory.REQUEST_CONTEXT, null);
-    toMutate.setFrozen(true);
-  }
-
-  /**
-   * Assemble all of the state that has been accumulated in this context. This
-   * includes:
-   * <ul>
-   * <li>Diffs accumulated on objects passed to {@link #edit}.
-   * <li>Invocations accumulated as Request subtypes passed to
-   * {@link #addInvocation}.
-   * </ul>
-   */
-  private String makePayload() {
-    // TODO: Chained invocations
-    assert invocations.size() == 1 : "addInvocation() should have failed";
-
-    // Produces the contentData payload fragment
-    RequestContentData data = new RequestContentData();
-
-    // Compute deltas for each entity seen by the context
-    for (AutoBean<?> currentView : editedProxies.values()) {
-      boolean isPersist = false;
-      @SuppressWarnings("unchecked")
-      SimpleEntityProxyId<EntityProxy> stableId = EntityProxyCategory.stableId((AutoBean<EntityProxy>) currentView);
-
-      // Encoded string representations of the properties
-      Map<String, String> encoded = new LinkedHashMap<String, String>();
-
-      {
-        // Find the object to compare against
-        AutoBean<?> parent = currentView.getTag(PARENT_OBJECT);
-        if (parent == null) {
-          // Newly-created object, use a blank object to compare against
-          parent = requestFactory.createEntityProxy(stableId.getProxyClass(),
-              stableId);
-
-          // Newly-created objects go into the persist operation bucket
-          isPersist = true;
-          // The ephemeral id is passed to the server
-          String clientId = String.valueOf(stableId.getClientId());
-          encoded.put(Constants.ENCODED_ID_PROPERTY,
-              ValueCodex.encodeForJsonPayload(clientId));
-        } else {
-          // Requests involving existing objects use the persisted id
-          encoded.put(Constants.ENCODED_ID_PROPERTY,
-              ValueCodex.encodeForJsonPayload(stableId.getServerId()));
-        }
-
-        // Compute the diff
-        Map<String, Object> diff = AutoBeanUtils.diff(parent, currentView);
-        for (Map.Entry<String, Object> entry : diff.entrySet()) {
-          // Make JSON representations of the new values
-          encoded.put(entry.getKey(),
-              EntityCodex.encodeForJsonPayload(entry.getValue()));
-        }
-      }
-
-      // Append the payload fragment to the correct bucket
-      String typeToken = requestFactory.getTypeToken(stableId.getProxyClass());
-      if (isPersist) {
-        data.addPersist(typeToken, encoded);
-      } else {
-        data.addUpdate(typeToken, encoded);
-      }
-    }
-
-    AbstractRequest<?> request = invocations.get(0);
-    // Known issue that the data is double-quoted
-    Map<String, String> requestMap = request.getRequestData().getRequestMap(
-        data.toJson());
-    String string = RequestContentData.flattenKeysToExpressions(requestMap);
-    return string;
-  }
-
-  /**
-   * Delete state that's no longer required.
-   */
-  private void postRequestCleanup() {
-    errors.clear();
-  }
-
-  /**
-   * Process an array of ReturnRecords, delegating to
-   * {@link #processReturnRecord}.
-   */
-  private void processReturnRecords(JsArray<ReturnRecord> records,
-      WriteOperation operations) {
-    for (int i = 0, j = records.length(); i < j; i++) {
-      ReturnRecord record = records.get(i);
-      SimpleEntityProxyId<EntityProxy> id = requestFactory.getId(
-          record.getSchema(), record.getEncodedId(), record.getFutureId());
-      processReturnRecord(id, record, operations);
-    }
-  }
-
-  /**
-   * Ensures that any method arguments are retained in the context's sphere of
-   * influence.
-   */
-  private void retainArg(Object arg) {
-    if (arg instanceof Iterable<?>) {
-      for (Object o : (Iterable<?>) arg) {
-        retainArg(o);
-      }
-    } else if (arg instanceof EntityProxy) {
-      // Calling edit will validate and set up the tracking we need
-      edit((EntityProxy) arg);
-    }
-  }
-
-  /**
-   * Make the EnityProxy bean edited and owned by this RequestContext.
-   */
-  private <T extends EntityProxy> T takeOwnership(AutoBean<T> bean) {
-    editedProxies.put(EntityProxyCategory.stableId(bean), bean);
-    bean.setTag(EntityProxyCategory.REQUEST_CONTEXT,
-        AbstractRequestContext.this);
-    return bean.as();
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequestFactory.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequestFactory.java
deleted file mode 100644
index bcd026c..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequestFactory.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl;
-
-import com.google.gwt.editor.client.AutoBean;
-import com.google.gwt.editor.client.AutoBeanFactory;
-import com.google.gwt.editor.client.AutoBeanUtils;
-import com.google.gwt.event.shared.EventBus;
-import com.google.gwt.requestfactory.client.DefaultRequestTransport;
-import com.google.gwt.requestfactory.client.impl.messages.RequestData;
-import com.google.gwt.requestfactory.shared.EntityProxy;
-import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.Request;
-import com.google.gwt.requestfactory.shared.RequestFactory;
-import com.google.gwt.requestfactory.shared.RequestTransport;
-
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * 
- */
-public abstract class AbstractRequestFactory implements RequestFactory {
-  protected static final String EPHEMERAL_SEPARATOR = "@IS@";
-  protected static final String TOKEN_SEPARATOR = "@NO@";
-  protected static final int ID_TOKEN_INDEX = 0;
-  protected static final int TYPE_TOKEN_INDEX = 1;
-  private static final int MAX_VERSION_ENTRIES = 10000;
-
-  public static String getHistoryToken(EntityProxy proxy) {
-    AutoBean<EntityProxy> bean = AutoBeanUtils.getAutoBean(proxy);
-    String historyToken = EntityProxyCategory.requestFactory(bean).getHistoryToken(
-        proxy.stableId());
-    return historyToken;
-  }
-
-  private EventBus eventBus;
-
-  /**
-   * Maps ephemeral history tokens to an id object. This canonicalizing mapping
-   * resolves the problem of EntityProxyIds hashcodes changing after persist.
-   * Only ids that are created in the RequestFactory are stored here.
-   */
-  /*
-   * All of the ephemeral id-tracking could be moved into RequestContext if we
-   * allowed ephemeral history tokens only to be used with the RequestConext
-   * where the create method was called.
-   */
-  private final Map<String, SimpleEntityProxyId<?>> ephemeralIds = new HashMap<String, SimpleEntityProxyId<?>>();
-  private final Map<String, Integer> version = new LinkedHashMap<String, Integer>(
-      16, 0.75f, true) {
-    @Override
-    protected boolean removeEldestEntry(Entry<String, Integer> eldest) {
-      return size() > MAX_VERSION_ENTRIES;
-    }
-  };
-  private RequestTransport transport;
-
-  /**
-   * Allocates an ephemeral proxy id. This object is only valid for the lifetime
-   * of the RequestFactory.
-   */
-  public <P extends EntityProxy> SimpleEntityProxyId<P> allocateId(
-      Class<P> clazz) {
-    SimpleEntityProxyId<P> toReturn = new SimpleEntityProxyId<P>(clazz,
-        ephemeralIds.size() + 1);
-    ephemeralIds.put(getHistoryToken(toReturn), toReturn);
-    return toReturn;
-  }
-
-  /**
-   * Creates a new EntityProxy with an assigned ID.
-   */
-  public <T extends EntityProxy> AutoBean<T> createEntityProxy(Class<T> clazz,
-      SimpleEntityProxyId<T> id) {
-    AutoBean<T> created = getAutoBeanFactory().create(clazz);
-    if (created == null) {
-      throw new IllegalArgumentException("Unknown EntityProxy type "
-          + clazz.getName());
-    }
-    created.setTag(EntityProxyCategory.REQUEST_FACTORY, this);
-    created.setTag(EntityProxyCategory.STABLE_ID, id);
-    return created;
-  }
-
-  public <P extends EntityProxy> Request<P> find(final EntityProxyId<P> proxyId) {
-    if (((SimpleEntityProxyId<P>) proxyId).isEphemeral()) {
-      throw new IllegalArgumentException("Cannot fetch unpersisted entity");
-    }
-
-    AbstractRequestContext context = new AbstractRequestContext(
-        AbstractRequestFactory.this);
-    return new AbstractRequest<P>(context) {
-      {
-        requestContext.addInvocation(this);
-      }
-
-      @Override
-      protected void handleResult(Object result) {
-        succeed(decodeReturnObject(proxyId.getProxyClass(), result));
-      }
-
-      @Override
-      protected RequestData makeRequestData() {
-        return new RequestData(
-            "com.google.gwt.requestfactory.client.impl.FindRequest::find",
-            new Object[] {getHistoryToken(proxyId)}, propertyRefs);
-      }
-    };
-  }
-
-  public EventBus getEventBus() {
-    return eventBus;
-  }
-
-  public String getHistoryToken(Class<? extends EntityProxy> clazz) {
-    return getTypeToken(clazz);
-  }
-
-  public String getHistoryToken(EntityProxyId<?> proxy) {
-    SimpleEntityProxyId<?> id = (SimpleEntityProxyId<?>) proxy;
-    if (id.isEphemeral()) {
-      return id.getClientId() + EPHEMERAL_SEPARATOR
-          + getHistoryToken(proxy.getProxyClass());
-    } else {
-      return id.getServerId() + TOKEN_SEPARATOR
-          + getHistoryToken(proxy.getProxyClass());
-    }
-  }
-
-  public Class<? extends EntityProxy> getProxyClass(String historyToken) {
-    String[] parts = historyToken.split(TOKEN_SEPARATOR);
-    if (parts.length == 2) {
-      return getTypeFromToken(parts[TYPE_TOKEN_INDEX]);
-    }
-    parts = historyToken.split(EPHEMERAL_SEPARATOR);
-    if (parts.length == 2) {
-      return getTypeFromToken(parts[TYPE_TOKEN_INDEX]);
-    }
-    return getTypeFromToken(historyToken);
-  }
-
-  public <P extends EntityProxy> SimpleEntityProxyId<P> getProxyId(
-      String historyToken) {
-    String[] parts = historyToken.split(TOKEN_SEPARATOR);
-    if (parts.length == 2) {
-      return getId(parts[TYPE_TOKEN_INDEX], parts[ID_TOKEN_INDEX]);
-    }
-    parts = historyToken.split(EPHEMERAL_SEPARATOR);
-    if (parts.length == 2) {
-      @SuppressWarnings("unchecked")
-      SimpleEntityProxyId<P> toReturn = (SimpleEntityProxyId<P>) ephemeralIds.get(historyToken);
-
-      /*
-       * This is tested in FindServiceTest.testFetchUnpersistedFutureId. In
-       * order to get here, the user would have to get an unpersisted history
-       * token and attempt to use it with a different RequestFactory instance.
-       * This could occur if an ephemeral token was bookmarked. In this case,
-       * we'll create a token, however it will never match anything.
-       */
-      if (toReturn == null) {
-        Class<P> clazz = checkTypeToken(parts[TYPE_TOKEN_INDEX]);
-        toReturn = new SimpleEntityProxyId<P>(clazz, -1 * ephemeralIds.size());
-        ephemeralIds.put(historyToken, toReturn);
-      }
-
-      return toReturn;
-    }
-    throw new IllegalArgumentException(historyToken);
-  }
-
-  public RequestTransport getRequestTransport() {
-    return transport;
-  }
-
-  public void initialize(EventBus eventBus) {
-    initialize(eventBus, new DefaultRequestTransport(eventBus));
-  }
-
-  public void initialize(EventBus eventBus, RequestTransport transport) {
-    this.eventBus = eventBus;
-    this.transport = transport;
-  }
-
-  /**
-   * Implementations of EntityProxies are provided by an AutoBeanFactory, which
-   * is itself a generated type.
-   */
-  protected abstract AutoBeanFactory getAutoBeanFactory();
-
-  /**
-   * Create or retrieve a SimpleEntityProxyId.
-   */
-  protected <P extends EntityProxy> SimpleEntityProxyId<P> getId(
-      Class<P> clazz, String serverId) {
-    return getId(getTypeToken(clazz), serverId);
-  }
-
-  /**
-   * Create or retrieve a SimpleEntityProxyId.
-   */
-  protected <P extends EntityProxy> SimpleEntityProxyId<P> getId(
-      String typeToken, String serverId) {
-    return getId(typeToken, serverId, null);
-  }
-
-  /**
-   * Create or retrieve a SimpleEntityProxyId. If both the serverId and clientId
-   * are specified and the id is ephemeral, it will be updated with the server
-   * id.
-   */
-  protected <P extends EntityProxy> SimpleEntityProxyId<P> getId(
-      String typeToken, String serverId, String clientId) {
-    /*
-     * If there's a clientId, that probably means we've just created a brand-new
-     * EntityProxy or have just persisted something on the server.
-     */
-    if (clientId != null) {
-      // Try a cache lookup for the ephemeral key
-      String ephemeralKey = clientId + EPHEMERAL_SEPARATOR + typeToken;
-      @SuppressWarnings("unchecked")
-      SimpleEntityProxyId<P> toReturn = (SimpleEntityProxyId<P>) ephemeralIds.get(ephemeralKey);
-      // Cache hit based on client id
-      if (toReturn != null) {
-        // If it's ephemeral, see if we have a serverId and save it
-        if (toReturn.isEphemeral()) {
-          // Sanity check
-          assert toReturn.getProxyClass().equals(getTypeFromToken(typeToken));
-
-          // TODO: This happens when objects fail to validate on create
-          if (!"null".equals(serverId)) {
-            /*
-             * Record the server id so a later "find" operation will have an
-             * equal stableId.
-             */
-            toReturn.setServerId(serverId);
-            String serverKey = serverId + TOKEN_SEPARATOR + typeToken;
-            ephemeralIds.put(serverKey, toReturn);
-          }
-        }
-        return toReturn;
-      }
-    }
-
-    // Should never get this far without a server id
-    assert serverId != null : "serverId";
-
-    String serverKey = serverId + TOKEN_SEPARATOR + typeToken;
-    @SuppressWarnings("unchecked")
-    SimpleEntityProxyId<P> toReturn = (SimpleEntityProxyId<P>) ephemeralIds.get(serverKey);
-    if (toReturn != null) {
-      // A cache hit for a locally-created object that has been persisted
-      return toReturn;
-    }
-
-    /*
-     * No existing id, so it was never an ephemeral id created by this
-     * RequestFactory, so we don't need to record it. This should be the normal
-     * case for read-dominated applications.
-     */
-    Class<P> clazz = getTypeFromToken(typeToken);
-    return new SimpleEntityProxyId<P>(clazz, serverId);
-  }
-
-  protected abstract <P extends EntityProxy> Class<P> getTypeFromToken(
-      String typeToken);
-
-  protected abstract String getTypeToken(Class<?> clazz);
-
-  /**
-   * Used by {@link AbstractRequestContext} to quiesce update events for objects
-   * that haven't truly changed.
-   */
-  protected boolean hasVersionChanged(SimpleEntityProxyId<?> id,
-      int observedVersion) {
-    Integer existingVersion = version.get(id.getServerId());
-    // Return true if we haven't seen this before or the versions differ
-    boolean toReturn = existingVersion == null
-        || !existingVersion.equals(observedVersion);
-    if (toReturn) {
-      version.put(id.getServerId(), observedVersion);
-    }
-    return toReturn;
-  }
-
-  private <P> Class<P> checkTypeToken(String token) {
-    @SuppressWarnings("unchecked")
-    Class<P> clazz = (Class<P>) getTypeFromToken(token);
-    if (clazz == null) {
-      throw new IllegalArgumentException("Unknnown type");
-    }
-    return clazz;
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/EntityCodex.java b/user/src/com/google/gwt/requestfactory/client/impl/EntityCodex.java
deleted file mode 100644
index 64e0a1f..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/EntityCodex.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.core.client.JsArrayString;
-import com.google.gwt.requestfactory.shared.EntityProxy;
-import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.ValueCodex;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Analogous to {@link ValueCodex}, but for object types.
- */
-public class EntityCodex {
-  /**
-   * Collection support is limited to value types and resolving ids.
-   */
-  public static Object decode(Class<?> type, Class<?> elementType,
-      final AbstractRequestContext requestContext, Object jso) {
-    if (jso == null) {
-      return null;
-    }
-
-    // Collection support
-    if (elementType != null) {
-      Collection<Object> collection = null;
-      if (List.class == type) {
-        collection = new ArrayList<Object>();
-      } else if (Set.class == type) {
-        collection = new HashSet<Object>();
-      }
-
-      // OK, here's a Java typesystem wart, we need an JsAny type
-      if (ValueCodex.canDecode(elementType)) {
-        @SuppressWarnings("unchecked")
-        JsArray<JavaScriptObject> array = (JsArray<JavaScriptObject>) jso;
-        for (int i = 0, j = array.length(); i < j; i++) {
-          if (isNull(array, i)) {
-            collection.add(null);
-          } else {
-            // Use getString() to make DevMode not complain about primitives
-            Object element = ValueCodex.convertFromString(elementType,
-                getString(array, i));
-            collection.add(element);
-          }
-        }
-      } else {
-        JsArrayString array = (JsArrayString) jso;
-        for (int i = 0, j = array.length(); i < j; i++) {
-          Object element = decode(elementType, null, requestContext,
-              array.get(i));
-          collection.add(element);
-        }
-      }
-      return collection;
-    }
-
-    // Really want EntityProxy.isAssignableFrom(type)
-    if (requestContext.getRequestFactory().getTypeToken(type) != null) {
-      EntityProxyId<?> id = requestContext.getRequestFactory().getProxyId(
-          (String) jso);
-      return requestContext.getProxyForReturnPayloadGraph(
-          (SimpleEntityProxyId<?>) id).as();
-    }
-
-    // Fall back to values
-    return ValueCodex.convertFromString(type, String.valueOf(jso));
-  }
-
-  /**
-   * Create a wire-format representation of an object.
-   */
-  public static String encodeForJsonPayload(Object value) {
-    if (value == null) {
-      return "null";
-    }
-
-    if (value instanceof Iterable<?>) {
-      StringBuffer toReturn = new StringBuffer();
-      toReturn.append('[');
-      boolean first = true;
-      for (Object val : ((Iterable<?>) value)) {
-        if (!first) {
-          toReturn.append(',');
-        } else {
-          first = false;
-        }
-        toReturn.append(encodeForJsonPayload(val));
-      }
-      toReturn.append(']');
-      return toReturn.toString();
-    }
-
-    if (value instanceof EntityProxy) {
-      String historyToken = AbstractRequestFactory.getHistoryToken((EntityProxy) value);
-      return "\"" + historyToken + "\"";
-    }
-
-    return ValueCodex.encodeForJsonPayload(value);
-  }
-
-  private static native String getString(JavaScriptObject array, int index) /*-{
-    return String(array[index]);
-  }-*/;
-
-  /**
-   * Looks for an explicit null value.
-   */
-  private static native boolean isNull(JavaScriptObject array, int index) /*-{
-    return array[index] === null;
-  }-*/;
-}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/messages/JsonResults.java b/user/src/com/google/gwt/requestfactory/client/impl/messages/JsonResults.java
deleted file mode 100644
index 9129d39..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/messages/JsonResults.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl.messages;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.core.client.JsonUtils;
-
-/**
- * JSO to hold result and related objects.
- */
-public class JsonResults extends JavaScriptObject {
-
-  public static JsonResults fromResults(String json) {
-    // Avoid a compiler bug that occurs when this is all on one line.
-    // Bug found in Mac OS X 10.5.8 using javac 1.5.0_24.
-    JavaScriptObject results = JsonUtils.safeEval(json);
-    return results.cast();
-  }
-
-  protected JsonResults() {
-  }
-
-  public final native JsonServerException getException() /*-{
-    return this.exception || null;
-  }-*/;
-
-  public final native RelatedObjects getRelated() /*-{
-    return this.related;
-  }-*/;
-
-  public final native Object getResult() /*-{
-    return Object(this.result);
-  }-*/;
-
-  public final native SideEffects getSideEffects() /*-{
-    return this.sideEffects;
-  }-*/;
-
-  public final native JsArray<ReturnRecord> getViolations()/*-{
-    return this.violations || null;
-  }-*/;
-
-  /**
-   * Looks for an explicit <code>{result: null}</code> in the payload.
-   */
-  public final native boolean isNullResult() /*-{
-    return this.result === null;
-  }-*/;
-}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/messages/JsonServerException.java b/user/src/com/google/gwt/requestfactory/client/impl/messages/JsonServerException.java
deleted file mode 100644
index 1e508f2..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/messages/JsonServerException.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl.messages;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-/**
- * Contains details of a server error.
- */
- public final class JsonServerException extends JavaScriptObject {
-
-  protected JsonServerException() {
-  }
-
-  public native String getMessage() /*-{
-    return this.message || "";
-  }-*/;
-
-  public native String getTrace() /*-{
-    return this.trace || "";
-  }-*/;
-
-  public native String getType() /*-{
-    return this.type || "";
-  }-*/;
-}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/messages/RelatedObjects.java b/user/src/com/google/gwt/requestfactory/client/impl/messages/RelatedObjects.java
deleted file mode 100644
index de1bb19..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/messages/RelatedObjects.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl.messages;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Provides access to the related field in the main payload.
- */
-public final class RelatedObjects extends JavaScriptObject {
-
-  protected RelatedObjects() {
-  }
-
-  public Set<String> getHistoryTokens() {
-    HashSet<String> toReturn = new HashSet<String>();
-    ReturnRecord.fillKeys(this, toReturn);
-    return toReturn;
-  }
-
-  public native ReturnRecord getReturnRecord(String key) /*-{
-    return this[key];
-  }-*/;
-}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/messages/RequestContentData.java b/user/src/com/google/gwt/requestfactory/client/impl/messages/RequestContentData.java
deleted file mode 100644
index f955bf0..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/messages/RequestContentData.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl.messages;
-
-import com.google.gwt.core.client.JsonUtils;
-import com.google.gwt.requestfactory.shared.WriteOperation;
-
-import java.util.EnumMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * Accumulates data to place in the contentData section of a client request.
- */
-public class RequestContentData {
-  /**
-   * Create a JSON map ouf of keys and JSON expressions. The keys are quoted,
-   * however, the expressions are not.
-   */
-  public static String flattenKeysToExpressions(
-      Map<String, String> keysToExpressions) {
-    if (keysToExpressions.isEmpty()) {
-      return "{}";
-    }
-
-    StringBuilder flattenedProperties = new StringBuilder();
-    for (Map.Entry<String, String> entry : keysToExpressions.entrySet()) {
-      flattenedProperties.append(",").append(
-          JsonUtils.escapeValue(entry.getKey())).append(":").append(
-          entry.getValue());
-    }
-    capMap(flattenedProperties);
-    return flattenedProperties.toString();
-  }
-
-  /**
-   * Appends a flattened map object to a larger map of keys to lists.
-   */
-  private static void addToMap(Map<WriteOperation, StringBuilder> map,
-      WriteOperation op, String typeToken, Map<String, String> toFlatten) {
-    // { "id": 1, "foo": "bar", "baz": [1,2,3] }
-    String flattenedProperties = flattenKeysToExpressions(toFlatten);
-
-    StringBuilder sb = map.get(op);
-    if (sb == null) {
-      sb = new StringBuilder();
-      map.put(op, sb);
-    }
-
-    // {"com.google.Foo" : { id:1, foo:"bar"}}
-    sb.append(",").append("{\"").append(typeToken).append("\":").append(
-        flattenedProperties.toString()).append("}");
-  }
-
-  /**
-   * For simplicity, most lists are generated with a leading comma. This method
-   * makes the StringBuilder a properly terminated.
-   */
-  private static void capList(StringBuilder properties) {
-    properties.deleteCharAt(0).insert(0, "[").append("]");
-  }
-
-  private static void capMap(StringBuilder sb) {
-    sb.deleteCharAt(0).insert(0, "{").append("}");
-  }
-
-  private final Map<WriteOperation, StringBuilder> payloads = new EnumMap<WriteOperation, StringBuilder>(
-      WriteOperation.class);
-
-  public void addPersist(String typeToken, Map<String, String> encoded) {
-    addToMap(payloads, WriteOperation.PERSIST, typeToken, encoded);
-  }
-
-  public void addUpdate(String typeToken, Map<String, String> encoded) {
-    addToMap(payloads, WriteOperation.UPDATE, typeToken, encoded);
-  }
-
-  public String toJson() {
-    Map<String, String> toReturn = new LinkedHashMap<String, String>();
-    addToReturn(toReturn, WriteOperation.PERSIST);
-    addToReturn(toReturn, WriteOperation.UPDATE);
-    return flattenKeysToExpressions(toReturn);
-  }
-
-  /**
-   * For debugging use only.
-   */
-  @Override
-  public String toString() {
-    return toJson();
-  }
-
-  private void addToReturn(Map<String, String> toReturn, WriteOperation op) {
-    StringBuilder sb = payloads.get(op);
-    if (sb != null) {
-      capList(sb);
-      toReturn.put(op.getUnObfuscatedEnumName(), sb.toString());
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/messages/RequestData.java b/user/src/com/google/gwt/requestfactory/client/impl/messages/RequestData.java
deleted file mode 100644
index 487717d..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/messages/RequestData.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl.messages;
-
-import com.google.gwt.requestfactory.client.impl.EntityCodex;
-import com.google.gwt.requestfactory.shared.ValueCodex;
-import com.google.gwt.requestfactory.shared.impl.Constants;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * <p>
- * <span style="color:red">Experimental API: This class is still under rapid
- * development, and is very likely to be deleted. Use it at your own risk.
- * </span>
- * </p>
- * A class that encapsulates the parameters and method name to be invoked on the
- * server.
- */
-public class RequestData {
-  private final String operation;
-  private final Object[] parameters;
-  private final Set<String> propertyRefs;
-
-  public RequestData(String operation, Object[] parameters,
-      Set<String> propertyRefs) {
-    this.operation = operation;
-    this.parameters = parameters;
-    this.propertyRefs = propertyRefs;
-  }
-
-  /**
-   * Used by InstanceRequest subtypes to reset the instance object in the
-   * <code>using</code> method.
-   */
-  public Object[] getParameters() {
-    return parameters;
-  }
-
-  /**
-   * Returns the string that encodes the request data.
-   * 
-   */
-  public Map<String, String> getRequestMap(String contentData) {
-    Map<String, String> requestMap = new HashMap<String, String>();
-    requestMap.put(Constants.OPERATION_TOKEN,
-        ValueCodex.encodeForJsonPayload(operation));
-    if (parameters != null) {
-      for (int i = 0; i < parameters.length; i++) {
-        Object value = parameters[i];
-        requestMap.put(Constants.PARAM_TOKEN + i,
-            EntityCodex.encodeForJsonPayload(value));
-      }
-    }
-    if (contentData != null) {
-      // Yes, double-encoding
-      requestMap.put(Constants.CONTENT_TOKEN,
-          ValueCodex.encodeForJsonPayload(contentData));
-    }
-
-    if (propertyRefs != null && !propertyRefs.isEmpty()) {
-      StringBuffer props = new StringBuffer();
-      Iterator<String> propIt = propertyRefs.iterator();
-      while (propIt.hasNext()) {
-        props.append(propIt.next());
-        if (propIt.hasNext()) {
-          props.append(",");
-        }
-      }
-      requestMap.put(Constants.PROPERTY_REF_TOKEN,
-          ValueCodex.encodeForJsonPayload(props.toString()));
-    }
-    return requestMap;
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/messages/ReturnRecord.java b/user/src/com/google/gwt/requestfactory/client/impl/messages/ReturnRecord.java
deleted file mode 100644
index 17446cf..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/messages/ReturnRecord.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl.messages;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-import java.util.HashMap;
-import java.util.HashSet;
-
-/**
- * JSO that holds an entity reference being returned from the server.
- */
-public class ReturnRecord extends JavaScriptObject {
-
-  static native void fillKeys(JavaScriptObject jso, HashSet<String> s) /*-{
-    for (key in jso) {
-      if (jso.hasOwnProperty(key)) {
-        s.@java.util.HashSet::add(Ljava/lang/Object;)(key);
-      }
-    }
-  }-*/;
-
-  protected ReturnRecord() {
-  }
-
-  public final native void fillViolations(HashMap<String, String> s) /*-{
-    for (key in this.violations) {
-      if (this.violations.hasOwnProperty(key)) {
-        s.@java.util.HashMap::put(Ljava/lang/Object;Ljava/lang/Object;)(key, this.violations[key]);
-      }
-    }
-  }-*/;
-
-  public final native Object get(String propertyName) /*-{
-    return Object(this[propertyName]);
-  }-*/;
-
-  public final String getEncodedId() {
-    String parts[] = getSchemaAndId().split("@");
-    return parts[1];
-  }
-
-  public final native String getFutureId()/*-{
-    return this[@com.google.gwt.requestfactory.shared.impl.Constants::ENCODED_FUTUREID_PROPERTY];
-  }-*/;
-
-  public final String getSchema() {
-    String parts[] = getSchemaAndId().split("@");
-    return parts[0];
-  }
-
-  public final native String getSchemaAndId() /*-{
-    return this[@com.google.gwt.requestfactory.shared.impl.Constants::ENCODED_ID_PROPERTY];
-  }-*/;
-
-  public final native String getSimpleId()/*-{
-    return this[@com.google.gwt.requestfactory.shared.impl.Constants::ENCODED_ID_PROPERTY];
-  }-*/;
-
-  public final native int getVersion()/*-{
-    return this[@com.google.gwt.requestfactory.shared.impl.Constants::ENCODED_VERSION_PROPERTY] || 0;
-  }-*/;
-
-  public final native boolean hasFutureId()/*-{
-    return @com.google.gwt.requestfactory.shared.impl.Constants::ENCODED_FUTUREID_PROPERTY in this;
-  }-*/;
-
-  public final native boolean hasId()/*-{
-    return @com.google.gwt.requestfactory.shared.impl.Constants::ENCODED_ID_PROPERTY in this;
-  }-*/;
-
-  public final native boolean hasProperty(String property) /*-{
-    return this.hasOwnProperty(property);
-  }-*/;
-
-  public final native boolean hasViolations()/*-{
-    return @com.google.gwt.requestfactory.shared.impl.Constants::VIOLATIONS_TOKEN in this;
-  }-*/;
-
-  /**
-   * Returns <code>true</code> if the property explicitly set to null.
-   */
-  public final native boolean isNull(String property) /*-{
-    return this[property] === null;
-  }-*/;
-
-}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/messages/SideEffects.java b/user/src/com/google/gwt/requestfactory/client/impl/messages/SideEffects.java
deleted file mode 100644
index 1fa1f36..0000000
--- a/user/src/com/google/gwt/requestfactory/client/impl/messages/SideEffects.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client.impl.messages;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-
-/**
- * Provides access to the changes that occurred on the server.
- */
-public final class SideEffects extends JavaScriptObject {
-  protected SideEffects() {
-  }
-
-  public native JsArray<ReturnRecord> getDelete() /*-{
-    return this['DELETE'];
-  }-*/;
-
-  public native JsArray<ReturnRecord> getPersist() /*-{
-    return this['PERSIST'];
-  }-*/;
-
-  public native JsArray<ReturnRecord> getUpdate() /*-{
-    return this['UPDATE'];
-  }-*/;
-}
diff --git a/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java b/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
index 53aaeed..b7eb331 100644
--- a/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
+++ b/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
@@ -15,6 +15,10 @@
  */
 package com.google.gwt.requestfactory.rebind;
 
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanFactory;
+import com.google.gwt.autobean.shared.AutoBeanFactory.Category;
+import com.google.gwt.autobean.shared.AutoBeanFactory.NoWrap;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.ext.Generator;
 import com.google.gwt.core.ext.GeneratorContext;
@@ -25,37 +29,25 @@
 import com.google.gwt.core.ext.typeinfo.JParameter;
 import com.google.gwt.core.ext.typeinfo.JTypeParameter;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.editor.client.AutoBean;
-import com.google.gwt.editor.client.AutoBeanFactory;
-import com.google.gwt.editor.client.AutoBeanFactory.Category;
-import com.google.gwt.editor.client.AutoBeanFactory.NoWrap;
 import com.google.gwt.editor.rebind.model.ModelUtils;
-import com.google.gwt.requestfactory.client.impl.AbstractRequest;
-import com.google.gwt.requestfactory.client.impl.AbstractRequestContext;
-import com.google.gwt.requestfactory.client.impl.AbstractRequestFactory;
-import com.google.gwt.requestfactory.client.impl.EntityProxyCategory;
-import com.google.gwt.requestfactory.client.impl.messages.RequestData;
+import com.google.gwt.requestfactory.client.impl.AbstractClientRequestFactory;
 import com.google.gwt.requestfactory.rebind.model.ContextMethod;
 import com.google.gwt.requestfactory.rebind.model.EntityProxyModel;
 import com.google.gwt.requestfactory.rebind.model.RequestFactoryModel;
 import com.google.gwt.requestfactory.rebind.model.RequestMethod;
-import com.google.gwt.requestfactory.rebind.model.RequestMethod.CollectionType;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.ValueCodex;
+import com.google.gwt.requestfactory.shared.impl.AbstractRequest;
+import com.google.gwt.requestfactory.shared.impl.AbstractRequestContext;
+import com.google.gwt.requestfactory.shared.impl.AbstractRequestFactory;
+import com.google.gwt.requestfactory.shared.impl.EntityProxyCategory;
+import com.google.gwt.requestfactory.shared.impl.RequestData;
 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 
 /**
- * <p>
- * <span style="color:red">Experimental API: This class is still under rapid
- * development, and is very likely to be deleted. Use it at your own risk.
- * </span>
- * </p>
  * Generates implementations of
  * {@link com.google.gwt.requestfactory.shared.RequestFactory RequestFactory}
  * and its nested interfaces.
@@ -90,7 +82,7 @@
 
     ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(
         packageName, simpleSourceName);
-    factory.setSuperclass(AbstractRequestFactory.class.getCanonicalName());
+    factory.setSuperclass(AbstractClientRequestFactory.class.getCanonicalName());
     factory.addImplementedInterface(typeName);
     SourceWriter sw = factory.createSourceWriter(context, pw);
     writeAutoBeanFactory(sw);
@@ -211,50 +203,20 @@
         // makeRequestData()
         sw.println("@Override protected %s makeRequestData() {",
             RequestData.class.getCanonicalName());
-        // return new RequestData("Foo::bar", new Object
-        sw.indentln("return new %s(\"%s\", new Object[] {%s}, propertyRefs);",
-            RequestData.class.getCanonicalName(), operation, parameterArray);
+        // return new RequestData("Foo::bar", {parameters}, propertyRefs,
+        // List.class, FooProxy.class);
+        String elementType = request.isCollectionType()
+            ? request.getCollectionElementType().getQualifiedSourceName()
+                + ".class" : "null";
+        String returnTypeBaseQualifiedName = ModelUtils.ensureBaseType(
+            request.getDataType()).getQualifiedSourceName();
+        sw.indentln(
+            "return new %s(\"%s\", new Object[] {%s}, propertyRefs, %s.class, %s);",
+            RequestData.class.getCanonicalName(), operation, parameterArray,
+            returnTypeBaseQualifiedName, elementType);
         sw.println("}");
 
-        // handleResponse(Object obj)
-        sw.println("@Override protected void handleResult(Object obj) {");
-        sw.indent();
-        sw.println("Object decoded;");
-        if (request.isCollectionType()) {
-          // Lists are ArrayLists, Sets are HashSets
-          Class<?> collectionType = request.getCollectionType().equals(
-              CollectionType.LIST) ? ArrayList.class : HashSet.class;
-
-          // decoded = new ArrayList<Foo>();
-          sw.println("decoded = new %s();", collectionType.getCanonicalName());
-
-          // decodeReturnObjectList(FooEntityProxy.class,obj, (List)decoded);
-          String decodeMethod = request.isValueType() ? "decodeReturnValueList"
-              : "decodeReturnObjectList";
-          sw.println(
-              "%s(%s.class, obj, (%s)decoded);",
-              decodeMethod,
-              ModelUtils.getQualifiedBaseName(request.getCollectionElementType()),
-              collectionType.getCanonicalName());
-        } else if (request.isValueType()) {
-          // decoded = ValueCodex.cFString(Integer.class, String.valueOf(obj));
-          sw.println(
-              "decoded = %s.convertFromString(%s.class, String.valueOf(obj));",
-              ValueCodex.class.getCanonicalName(),
-              ModelUtils.getQualifiedBaseName(request.getDataType()));
-        } else if (request.isEntityType()) {
-          // Implicitly erased
-          sw.println("decoded = decodeReturnObject(%s.class, obj);",
-              request.getEntityType().getQualifiedSourceName());
-        } else {
-          sw.println("throw new UnsupportedOperationException()");
-        }
-        // succeed((Integer) decoded);
-        sw.println("succeed((%s) decoded);",
-            request.getDataType().getParameterizedQualifiedSourceName());
-        sw.outdent();
-        sw.println("}");
-
+        // end class X{}
         sw.outdent();
         sw.println("}");
 
diff --git a/user/src/com/google/gwt/requestfactory/server/DeadEntityException.java b/user/src/com/google/gwt/requestfactory/server/DeadEntityException.java
index 84df340..535239e 100644
--- a/user/src/com/google/gwt/requestfactory/server/DeadEntityException.java
+++ b/user/src/com/google/gwt/requestfactory/server/DeadEntityException.java
@@ -19,17 +19,10 @@
  * Indicates the user attempted to perform an operation on an irretrievable
  * entity.
  */
-public class DeadEntityException extends RuntimeException {
-  
-  /**
-   * Contructs a new {@link DeadEntityException}.
-   */
-  public DeadEntityException() {
-  }
-
+class DeadEntityException extends RuntimeException {
   /**
    * Contructs a new {@link DeadEntityException} with a given message.
-   *
+   * 
    * @param message a message String
    */
   public DeadEntityException(String message) {
diff --git a/user/src/com/google/gwt/requestfactory/server/DefaultExceptionHandler.java b/user/src/com/google/gwt/requestfactory/server/DefaultExceptionHandler.java
index 344b622..924b70e 100644
--- a/user/src/com/google/gwt/requestfactory/server/DefaultExceptionHandler.java
+++ b/user/src/com/google/gwt/requestfactory/server/DefaultExceptionHandler.java
@@ -1,12 +1,12 @@
 /*
  * 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
@@ -18,9 +18,8 @@
 import com.google.gwt.requestfactory.shared.ServerFailure;
 
 /**
- * Default implementation for handling exceptions thrown while
- * processing a request. Suppresses stack traces and the exception
- * class name.
+ * Default implementation for handling exceptions thrown while processing a
+ * request. Suppresses stack traces and the exception class name.
  */
 public class DefaultExceptionHandler implements ExceptionHandler {
   public ServerFailure createServerFailure(Throwable throwable) {
diff --git a/user/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java b/user/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java
deleted file mode 100644
index cdcb90f..0000000
--- a/user/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-import com.google.gwt.requestfactory.shared.Service;
-import com.google.gwt.requestfactory.shared.ServiceName;
-
-/**
- * A security provider that enforces
- * {@link com.google.gwt.requestfactory.shared.Service} annotations.
- */
-class DefaultSecurityProvider implements RequestSecurityProvider {
-
-  public void checkClass(Class<?> clazz) throws SecurityException {
-    Service service = clazz.getAnnotation(Service.class);
-    ServiceName serviceName = clazz.getAnnotation(ServiceName.class);
-    String className;
-    if (service != null) {
-      className = service.value().getName();
-    } else if (serviceName != null) {
-      className = serviceName.value();
-    } else {
-      throw new SecurityException("Class " + clazz.getName()
-          + " does not have a @Service annotation.");
-    }
-    try {
-      Class.forName(className);
-    } catch (ClassNotFoundException e) {
-      throw new SecurityException("Class " + className
-          + " from @Service annotation on " + clazz + " cannot be loaded.");
-    }
-  }
-
-  public String encodeClassType(Class<?> type) {
-    return type.getName();
-  }
-
-  public String mapOperation(String operationName) throws SecurityException {
-    return operationName;
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/server/ExceptionHandler.java b/user/src/com/google/gwt/requestfactory/server/ExceptionHandler.java
index 4faff11..8735633 100644
--- a/user/src/com/google/gwt/requestfactory/server/ExceptionHandler.java
+++ b/user/src/com/google/gwt/requestfactory/server/ExceptionHandler.java
@@ -19,11 +19,13 @@
 
 /**
  * Handles an exception produced while processing a request.
+ * 
+ * @see DefaultExceptionHandler
  */
 public interface ExceptionHandler {
   /**
-   * Generates a {@link ServerFailure} based on the information
-   * contained in the received {@code exception}.
+   * Generates a {@link ServerFailure} based on the information contained in the
+   * received {@code exception}.
    * 
    * @param throwable a Throwable instance
    * @return a {@link ServerFailure} instance
diff --git a/user/src/com/google/gwt/requestfactory/server/FindService.java b/user/src/com/google/gwt/requestfactory/server/FindService.java
index 06aefd8..d5b5353 100644
--- a/user/src/com/google/gwt/requestfactory/server/FindService.java
+++ b/user/src/com/google/gwt/requestfactory/server/FindService.java
@@ -22,7 +22,7 @@
 
   /**
    * For now, a simple implementation of find will work.
-   *
+   * 
    * @param entityInstance an entity instance
    * @return the passed-in entity instance
    */
diff --git a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
deleted file mode 100644
index ea7fb51..0000000
--- a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
+++ /dev/null
@@ -1,1644 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-import com.google.gwt.requestfactory.shared.EntityProxy;
-import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.ProxyFor;
-import com.google.gwt.requestfactory.shared.ProxyForName;
-import com.google.gwt.requestfactory.shared.ServerFailure;
-import com.google.gwt.requestfactory.shared.WriteOperation;
-import com.google.gwt.requestfactory.shared.impl.CollectionProperty;
-import com.google.gwt.requestfactory.shared.impl.Constants;
-import com.google.gwt.requestfactory.shared.impl.Property;
-import com.google.gwt.user.server.Base64Utils;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.beans.Introspector;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Logger;
-
-import javax.validation.ConstraintViolation;
-import javax.validation.Validation;
-import javax.validation.Validator;
-import javax.validation.ValidatorFactory;
-
-/**
- * An implementation of RequestProcessor for JSON encoded payloads.
- */
-class JsonRequestProcessor implements RequestProcessor<String> {
-
-  // TODO should we consume String, InputStream, or JSONObject?
-  private class DvsData {
-    private final JSONObject jsonObject;
-    private final WriteOperation writeOperation;
-    // save version because it is deleted later.
-    private final Integer version;
-
-    DvsData(JSONObject jsonObject, WriteOperation writeOperation)
-        throws JSONException, SecurityException, IllegalAccessException,
-        InvocationTargetException, NoSuchMethodException,
-        InstantiationException {
-      this.jsonObject = jsonObject;
-      this.writeOperation = writeOperation;
-      this.version = (Integer) (jsonObject.has(Constants.ENCODED_VERSION_PROPERTY)
-          ? decodeParameterValue(Constants.ENTITY_VERSION_PROPERTY.getType(),
-              jsonObject.get(Constants.ENCODED_VERSION_PROPERTY).toString())
-          : null);
-    }
-  }
-
-  private static class EntityData {
-    private final Object entityInstance;
-    // TODO: violations should have more structure than JSONObject
-    private final JSONObject violations;
-
-    EntityData(Object entityInstance, JSONObject violations) {
-      this.entityInstance = entityInstance;
-      this.violations = violations;
-    }
-  }
-
-  private class EntityKey {
-    final boolean isFuture;
-    final String encodedId;
-    final Class<? extends EntityProxy> proxyType;
-
-    EntityKey(String id, boolean isFuture,
-        Class<? extends EntityProxy> proxyType) {
-      this.encodedId = id;
-      this.isFuture = isFuture;
-      assert proxyType != null;
-      this.proxyType = proxyType;
-    }
-
-    public Object decodedId(Class<?> entityIdType) throws SecurityException,
-        JSONException, IllegalAccessException, InvocationTargetException,
-        NoSuchMethodException, InstantiationException {
-      if (isFuture) {
-        return encodedId;
-      }
-
-      if (String.class.isAssignableFrom(entityIdType)) {
-        return base64Decode(encodedId);
-      }
-
-      return decodeParameterValue(entityIdType, encodedId);
-    }
-
-    @Override
-    public boolean equals(Object ob) {
-      if (!(ob instanceof EntityKey)) {
-        return false;
-      }
-      EntityKey other = (EntityKey) ob;
-      return (encodedId.equals(other.encodedId))
-          && (isFuture == other.isFuture)
-          && (proxyType.equals(other.proxyType));
-    }
-
-    @Override
-    public int hashCode() {
-      return 31 * this.proxyType.hashCode()
-          + (31 * this.encodedId.hashCode() + (isFuture ? 1 : 0));
-    }
-
-    @Override
-    public String toString() {
-      return encodedId + "@" + (isFuture ? "IS" : "NO") + "@"
-          + proxyType.getName();
-    }
-  }
-
-  private static class SerializedEntity {
-    // the field value of the entityInstance might change from under us.
-    private final Object entityInstance;
-
-    private final JSONObject serializedEntity;
-
-    SerializedEntity(Object entityInstance, JSONObject serializedEntity) {
-      this.entityInstance = entityInstance;
-      this.serializedEntity = serializedEntity;
-    }
-  }
-
-  public static final String RELATED = "related";
-
-  private static final Logger log = Logger.getLogger(JsonRequestProcessor.class.getName());
-
-  /**
-   * Decodes a String encoded as web-safe base64.
-   * 
-   * @param encoded the encoded String
-   * @return a decoded String
-   */
-  public static String base64Decode(String encoded) {
-    byte[] decodedBytes;
-    try {
-      decodedBytes = Base64Utils.fromBase64(encoded);
-    } catch (Exception e) {
-      throw new IllegalArgumentException("EntityKeyId was not Base64 encoded: "
-          + encoded);
-    }
-    try {
-      return new String(decodedBytes, "UTF-8");
-    } catch (UnsupportedEncodingException e) {
-      // This can't happen
-      throw new IllegalStateException(e);
-    }
-  }
-
-  /**
-   * Encodes a String as web-safe base64.
-   * 
-   * @param decoded the decoded String
-   * @return an encoded String
-   */
-  public static String base64Encode(String decoded) {
-    try {
-      byte[] decodedBytes = decoded.getBytes("UTF-8");
-      return Base64Utils.toBase64(decodedBytes);
-    } catch (UnsupportedEncodingException e) {
-      // This can't happen
-      throw new IllegalStateException(e);
-    }
-  }
-
-  // TODO - document
-  @SuppressWarnings("unchecked")
-  public static Class<EntityProxy> getRecordFromClassToken(String recordToken) {
-    try {
-      // TODO(rjrjr) Should be getting class loader from servlet environment?
-      Class<?> clazz = Class.forName(recordToken, false,
-          JsonRequestProcessor.class.getClassLoader());
-      if (EntityProxy.class.isAssignableFrom(clazz)) {
-        return (Class<EntityProxy>) clazz;
-      }
-      throw new SecurityException("Attempt to access non-record class "
-          + recordToken);
-    } catch (ClassNotFoundException e) {
-      throw new IllegalArgumentException("Non-existent record class "
-          + recordToken);
-    }
-  }
-
-  private RequestProperty propertyRefs;
-
-  private final Map<String, JSONObject> relatedObjects = new HashMap<String, JSONObject>();
-
-  private OperationRegistry operationRegistry;
-
-  private ExceptionHandler exceptionHandler;
-
-  /*
-   * <li>Request comes in. Construct the involvedKeys, dvsDataMap and
-   * beforeDataMap, using DVS and parameters.
-   * 
-   * <li>Apply the DVS and construct the afterDvsDataMqp.
-   * 
-   * <li>Invoke the method noted in the operation.
-   * 
-   * <li>Find the changes that need to be sent back.
-   */
-  private final Map<EntityKey, Object> cachedEntityLookup = new HashMap<EntityKey, Object>();
-  private final Set<EntityKey> involvedKeys = new HashSet<EntityKey>();
-  private final Map<EntityKey, DvsData> dvsDataMap = new HashMap<EntityKey, DvsData>();
-  private final Map<EntityKey, SerializedEntity> beforeDataMap = new HashMap<EntityKey, SerializedEntity>();
-
-  private Map<EntityKey, EntityData> afterDvsDataMap = new HashMap<EntityKey, EntityData>();
-
-  // TODO - document
-  public Collection<Property<?>> allProperties(
-      Class<? extends EntityProxy> clazz) throws IllegalArgumentException {
-    return getPropertiesFromRecordProxyType(clazz).values();
-  }
-
-  // TODO - document
-  public String decodeAndInvokeRequest(String encodedRequest)
-      throws RequestProcessingException {
-    try {
-      Logger.getLogger(this.getClass().getName()).finest(
-          "Incoming request " + encodedRequest);
-      String response = processJsonRequest(encodedRequest).toString();
-      Logger.getLogger(this.getClass().getName()).finest(
-          "Outgoing response " + response);
-      return response;
-    } catch (InvocationTargetException e) {
-      JSONObject exceptionResponse = buildExceptionResponse(e.getCause());
-      throw new RequestProcessingException("Unexpected exception", e,
-          exceptionResponse.toString());
-    } catch (DeadEntityException e) {
-      // This is a normal, if exceptional, condition
-      return buildExceptionResponse(e).toString();
-    } catch (Exception e) {
-      JSONObject exceptionResponse = buildExceptionResponse(e);
-      throw new RequestProcessingException("Unexpected exception", e,
-          exceptionResponse.toString());
-    }
-  }
-
-  /**
-   * Decodes parameter value.
-   */
-  // TODO - document parameters and return value
-  public Object decodeParameterValue(Type genericParameterType,
-      String parameterValue) throws SecurityException, JSONException,
-      IllegalAccessException, InvocationTargetException, NoSuchMethodException,
-      InstantiationException {
-    if (parameterValue == null) {
-      return null;
-    }
-    Class<?> parameterType = null;
-    if (genericParameterType instanceof Class<?>) {
-      parameterType = (Class<?>) genericParameterType;
-    }
-    if (genericParameterType instanceof ParameterizedType) {
-      ParameterizedType pType = (ParameterizedType) genericParameterType;
-      if (pType.getRawType() instanceof Class<?>) {
-        Class<?> rType = (Class<?>) pType.getRawType();
-        // Ensure parameterType is initialized
-        parameterType = rType;
-        if (Collection.class.isAssignableFrom(rType)) {
-          Collection<Object> collection = createCollection(rType);
-          if (collection != null) {
-            JSONArray array = new JSONArray(parameterValue);
-            for (int i = 0; i < array.length(); i++) {
-              String value = array.isNull(i) ? null : array.getString(i);
-              collection.add(decodeParameterValue(
-                  pType.getActualTypeArguments()[0], value));
-            }
-            return collection;
-          }
-        }
-      }
-    }
-    if (String.class == parameterType) {
-      return parameterValue;
-    }
-    if (Boolean.class == parameterType || boolean.class == parameterType) {
-      return Boolean.valueOf(parameterValue);
-    }
-    if (Integer.class == parameterType || int.class == parameterType) {
-      return new Integer(parameterValue);
-    }
-    if (Byte.class == parameterType || byte.class == parameterType) {
-      return new Byte(parameterValue);
-    }
-    if (Short.class == parameterType || short.class == parameterType) {
-      return new Short(parameterValue);
-    }
-    if (Float.class == parameterType || float.class == parameterType) {
-      return new Float(parameterValue);
-    }
-    if (Double.class == parameterType || double.class == parameterType) {
-      return new Double(parameterValue);
-    }
-    if (Long.class == parameterType || long.class == parameterType) {
-      return new Long(parameterValue);
-    }
-    if (Character.class == parameterType || char.class == parameterType) {
-      return parameterValue.charAt(0);
-    }
-    if (BigInteger.class == parameterType) {
-      return new BigInteger(parameterValue);
-    }
-    if (BigDecimal.class == parameterType) {
-      return new BigDecimal(parameterValue);
-    }
-    if (parameterType.isEnum()) {
-      int ordinal = Integer.parseInt(parameterValue);
-      Method valuesMethod = parameterType.getDeclaredMethod("values",
-          new Class[0]);
-
-      if (valuesMethod != null) {
-        valuesMethod.setAccessible(true);
-        Enum<?>[] values = (Enum<?>[]) valuesMethod.invoke(null);
-        // we use ordinal serialization instead of name since future compiler
-        // opts may remove names
-        for (Enum<?> e : values) {
-          if (ordinal == e.ordinal()) {
-            return e;
-          }
-        }
-      }
-      throw new IllegalArgumentException("Can't decode enum " + parameterType
-          + " no matching ordinal " + ordinal);
-    }
-    if (Date.class == parameterType) {
-      return new Date(Long.parseLong(parameterValue));
-    }
-    if (EntityProxy.class.isAssignableFrom(parameterType)) {
-      /*
-       * TODO: 1. Don't resolve in this step, just get EntityKey. May need to
-       * use DVS.
-       * 
-       * 2. Merge the following and the object resolution code in getEntityKey.
-       * 3. Update the involvedKeys set.
-       */
-      ProxyFor proxyFor = parameterType.getAnnotation(ProxyFor.class);
-      ProxyForName proxyForName = parameterType.getAnnotation(ProxyForName.class);
-      if (proxyFor != null || proxyForName != null) {
-        EntityKey entityKey = getEntityKey(parameterValue.toString());
-
-        DvsData dvsData = dvsDataMap.get(entityKey);
-        if (dvsData != null) {
-          EntityData entityData = getEntityDataForRecordWithSettersApplied(
-              entityKey, dvsData.jsonObject, dvsData.writeOperation);
-          return entityData.entityInstance;
-        } else {
-          involvedKeys.add(entityKey);
-          return getEntityInstance(entityKey);
-        }
-      }
-    }
-    if (EntityProxyId.class.isAssignableFrom(parameterType)) {
-      EntityKey entityKey = getEntityKey(parameterValue.toString());
-      ProxyFor proxyFor = entityKey.proxyType.getAnnotation(ProxyFor.class);
-      ProxyForName proxyForName = entityKey.proxyType.getAnnotation(ProxyForName.class);
-      if (proxyFor == null && proxyForName == null) {
-        throw new IllegalArgumentException("Unknown service, unable to decode "
-            + parameterValue);
-      }
-      involvedKeys.add(entityKey);
-      return getEntityInstance(entityKey);
-    }
-    throw new IllegalArgumentException("Unknown parameter type: "
-        + parameterType);
-  }
-
-  /**
-   * Encode a property value to be sent across the wire.
-   * 
-   * @param value a value Object
-   * @return an encoded value Object
-   */
-  public Object encodePropertyValue(Object value) {
-    if (value == null) {
-      return JSONObject.NULL;
-    }
-    Class<?> type = value.getClass();
-    if (Boolean.class == type) {
-      return value;
-    }
-    if (Date.class.isAssignableFrom(type)) {
-      return String.valueOf(((Date) value).getTime());
-    }
-    if (Enum.class.isAssignableFrom(type)) {
-      return Double.valueOf(((Enum<?>) value).ordinal());
-    }
-    if (BigDecimal.class == type || BigInteger.class == type
-        || Long.class == type) {
-      return String.valueOf(value);
-    }
-    if (Number.class.isAssignableFrom(type)) {
-      return ((Number) value).doubleValue();
-    }
-    return String.valueOf(value);
-  }
-
-  /**
-   * Returns the propertyValue in the right type, from the DataStore. The value
-   * is sent into the response.
-   */
-  // TODO - document parameters and return value
-  public Object encodePropertyValueFromDataStore(Object entityElement,
-      Property<?> property, String propertyName, RequestProperty propertyContext)
-      throws SecurityException, NoSuchMethodException, IllegalAccessException,
-      InvocationTargetException, JSONException {
-
-    Object returnValue = getRawPropertyValueFromDatastore(entityElement,
-        propertyName);
-    Class<?> proxyPropertyType = property.getType();
-    Class<?> elementType = property instanceof CollectionProperty<?, ?>
-        ? ((CollectionProperty<?, ?>) property).getLeafType()
-        : proxyPropertyType;
-    String encodedEntityId = isEntityReference(returnValue, proxyPropertyType);
-
-    if (returnValue == null) {
-      return JSONObject.NULL;
-    } else if (encodedEntityId != null) {
-      String keyRef = encodeRelated(proxyPropertyType, propertyName,
-          propertyContext, returnValue);
-      return keyRef;
-    } else if (property instanceof CollectionProperty<?, ?>) {
-      Class<?> colType = ((CollectionProperty<?, ?>) property).getType();
-      Collection<Object> col = createCollection(colType);
-      if (col != null) {
-        for (Object o : ((Collection<?>) returnValue)) {
-          String encodedValId = isEntityReference(o,
-              ((CollectionProperty<?, ?>) property).getLeafType());
-          if (encodedValId != null) {
-            col.add(encodeRelated(elementType, propertyName, propertyContext, o));
-          } else {
-            col.add(encodePropertyValue(o));
-          }
-        }
-        return col;
-      }
-      return null;
-    } else {
-      return encodePropertyValue(returnValue);
-    }
-  }
-
-  /**
-   * Find the entity in the server data store, apply its setters, capture any
-   * violations, and return a
-   * {@link com.google.gwt.requestfactory.server.JsonRequestProcessor.EntityData
-   * EntityData} encapsulating the results.
-   * <p>
-   * If a <i>set</i> method has side-effects, we will not notice.
-   */
-  // TODO - document parameters and return value
-  public EntityData getEntityDataForRecordWithSettersApplied(
-      EntityKey entityKey, JSONObject recordObject,
-      WriteOperation writeOperation) throws JSONException, SecurityException,
-      IllegalAccessException, InvocationTargetException, NoSuchMethodException,
-      InstantiationException {
-
-    Class<?> entityType = getEntityTypeForProxyType(entityKey.proxyType);
-
-    Map<String, Property<?>> propertiesInProxy = getPropertiesFromRecordProxyType(entityKey.proxyType);
-    Map<String, Class<?>> propertiesInDomain = updatePropertyTypes(
-        propertiesInProxy, entityType);
-    validateKeys(recordObject, propertiesInDomain.keySet());
-
-    // get entityInstance
-    Class<?> idType = getIdMethodForEntity(entityType).getReturnType();
-    Object entityInstance = getEntityInstance(writeOperation, entityType,
-        entityKey.decodedId(idType), idType);
-    if (entityInstance == null) {
-      throw new DeadEntityException(
-          "The requested entity is not available on the server");
-    }
-    cachedEntityLookup.put(entityKey, entityInstance);
-
-    Iterator<?> keys = recordObject.keys();
-    while (keys.hasNext()) {
-      String key = (String) keys.next();
-      Property<?> dtoProperty = propertiesInProxy.get(key);
-      if (writeOperation == WriteOperation.PERSIST
-          && (Constants.ENTITY_ID_PROPERTY.equals(key))) {
-        // Don't allow the client to attempt to set the id
-        continue;
-      } else {
-        Object propertyValue = null;
-        if (recordObject.isNull(key)) {
-          // null
-        } else if (dtoProperty instanceof CollectionProperty<?, ?>) {
-          Class<?> cType = dtoProperty.getType();
-          Class<?> leafType = ((CollectionProperty<?, ?>) dtoProperty).getLeafType();
-          Collection<Object> col = createCollection(cType);
-          if (col != null) {
-            JSONArray array = recordObject.getJSONArray(key);
-            for (int i = 0; i < array.length(); i++) {
-              if (EntityProxy.class.isAssignableFrom(leafType)) {
-                propertyValue = getPropertyValueFromRequestCached(array, i,
-                    dtoProperty);
-              } else {
-                propertyValue = decodeParameterValue(leafType,
-                    array.getString(i));
-              }
-              col.add(propertyValue);
-            }
-            propertyValue = col;
-          }
-        } else {
-          propertyValue = getPropertyValueFromRequestCached(recordObject,
-              propertiesInProxy, key, dtoProperty);
-        }
-        entityType.getMethod(getMethodNameFromPropertyName(key, "set"),
-            propertiesInDomain.get(key)).invoke(entityInstance, propertyValue);
-      }
-    }
-
-    Set<ConstraintViolation<Object>> violations = Collections.emptySet();
-    // validations check..
-    Validator validator = null;
-    try {
-      ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
-      validator = validatorFactory.getValidator();
-    } catch (Exception e) {
-      /*
-       * This is JBoss's clumsy way of telling us that the system has not been
-       * configured.
-       */
-      log.info(String.format(
-          "Ignoring exception caught initializing bean validation framework. "
-              + "It is probably unconfigured or misconfigured. [%s] %s ",
-          e.getClass().getName(), e.getLocalizedMessage()));
-    }
-
-    if (validator != null) {
-      violations = validator.validate(entityInstance);
-    }
-    return new EntityData(entityInstance, (violations.isEmpty() ? null
-        : getViolationsAsJson(violations)));
-  }
-
-  // TODO - document
-  public Object getEntityInstance(EntityKey entityKey)
-      throws NoSuchMethodException, IllegalAccessException,
-      InvocationTargetException, JSONException, InstantiationException {
-    Class<?> entityClass = getEntityTypeForProxyType(entityKey.proxyType);
-    Class<?> idType = getIdMethodForEntity(entityClass).getReturnType();
-    Object entityInstance = entityClass.getMethod(
-        "find" + entityClass.getSimpleName(), idType).invoke(null,
-        entityKey.decodedId(idType));
-    return entityInstance;
-  }
-
-  // TODO - document
-  public Object getEntityInstance(WriteOperation writeOperation,
-      Class<?> entityType, Object idValue, Class<?> idType)
-      throws SecurityException, InstantiationException, IllegalAccessException,
-      InvocationTargetException, NoSuchMethodException,
-      IllegalArgumentException, JSONException {
-
-    if (writeOperation == WriteOperation.PERSIST) {
-      return entityType.getConstructor().newInstance();
-    }
-    // TODO: check "version" validity.
-    return entityType.getMethod("find" + entityType.getSimpleName(), idType).invoke(
-        null, decodeParameterValue(idType, idValue.toString()));
-  }
-
-  // TODO - document
-  @SuppressWarnings("unchecked")
-  public Class<Object> getEntityTypeForProxyType(
-      Class<? extends EntityProxy> record) {
-    ProxyFor dtoAnn = record.getAnnotation(ProxyFor.class);
-    if (dtoAnn != null) {
-      return (Class<Object>) dtoAnn.value();
-    }
-    ProxyForName name = record.getAnnotation(ProxyForName.class);
-    if (name != null) {
-      try {
-        return (Class<Object>) Class.forName(name.value(), false,
-            Thread.currentThread().getContextClassLoader());
-      } catch (ClassNotFoundException e) {
-        throw new IllegalArgumentException("Could not find ProxyForName class",
-            e);
-      }
-    }
-    throw new IllegalArgumentException("Proxy class " + record.getName()
-        + " missing ProxyFor annotation");
-  }
-
-  /**
-   * Converts the returnValue of a 'get' method to a JSONArray.
-   * 
-   * @param resultList object returned by a 'get' method, must be of type
-   *          List<?>
-   * @param entityKeyClass the class type of the contained value
-   * @return the JSONArray
-   */
-  public JSONArray getJsonArray(Collection<?> resultList,
-      Class<? extends EntityProxy> entityKeyClass)
-      throws IllegalArgumentException, SecurityException,
-      IllegalAccessException, JSONException, NoSuchMethodException,
-      InvocationTargetException {
-    JSONArray jsonArray = new JSONArray();
-    if (resultList.size() == 0) {
-      return jsonArray;
-    }
-
-    for (Object entityElement : resultList) {
-      if (entityElement instanceof Number || entityElement instanceof String
-          || entityElement instanceof Character
-          || entityElement instanceof Date || entityElement instanceof Boolean
-          || entityElement instanceof Enum<?>) {
-        jsonArray.put(encodePropertyValue(entityElement));
-      } else if (entityElement instanceof List<?>
-          || entityElement instanceof Set<?>) {
-        // TODO: unwrap nested type params?
-        jsonArray.put(getJsonArray((Collection<?>) entityElement,
-            entityKeyClass));
-      } else {
-        jsonArray.put(getJsonObject(entityElement, entityKeyClass, propertyRefs));
-      }
-    }
-    return jsonArray;
-  }
-
-  public Object getJsonObject(Object entityElement,
-      Class<? extends EntityProxy> entityKeyClass,
-      RequestProperty propertyContext) throws JSONException,
-      NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-    if (entityElement == null
-        || !EntityProxy.class.isAssignableFrom(entityKeyClass)) {
-      // JSONObject.NULL isn't a JSONObject
-      return JSONObject.NULL;
-    }
-    JSONObject jsonObject = getJsonObjectWithIdAndVersion(
-        isEntityReference(entityElement, entityKeyClass), entityElement,
-        propertyContext);
-
-    for (Property<?> p : allProperties(entityKeyClass)) {
-      if (requestedProperty(p, propertyContext)) {
-        String propertyName = p.getName();
-        jsonObject.put(
-            propertyName,
-            encodePropertyValueFromDataStore(entityElement, p, propertyName,
-                propertyContext));
-      }
-    }
-    return jsonObject;
-  }
-
-  /**
-   * Returns methodName corresponding to the propertyName that can be invoked on
-   * an entity.
-   * 
-   * Example: "userName" returns prefix + "UserName". "version" returns prefix +
-   * "Version"
-   */
-  public String getMethodNameFromPropertyName(String propertyName, String prefix) {
-    if (propertyName == null) {
-      throw new NullPointerException("propertyName must not be null");
-    }
-
-    StringBuffer methodName = new StringBuffer(prefix);
-    methodName.append(propertyName.substring(0, 1).toUpperCase());
-    methodName.append(propertyName.substring(1));
-    return methodName.toString();
-  }
-
-  /**
-   * Returns Object[0][0] as the entityKey corresponding to the object instance
-   * or null if it is a static method. Returns Object[1] as the params array.
-   */
-  public Object[][] getObjectsFromParameterMap(boolean isInstanceMethod,
-      Map<String, String> parameterMap, Type parameterClasses[])
-      throws SecurityException, JSONException, IllegalAccessException,
-      InvocationTargetException, NoSuchMethodException, InstantiationException {
-    // TODO: create an EntityMethodCall (instance, args) instead.
-    assert parameterClasses != null;
-    Object args[][] = new Object[2][];
-    args[0] = new Object[1];
-    if (isInstanceMethod) {
-      EntityKey entityKey = getEntityKey(parameterMap.get(Constants.PARAM_TOKEN
-          + "0"));
-      involvedKeys.add(entityKey);
-      args[0][0] = entityKey;
-    } else {
-      args[0][0] = null;
-    }
-
-    // TODO: update the involvedKeys for other params
-    int offset = (isInstanceMethod ? 1 : 0);
-    args[1] = new Object[parameterClasses.length - offset];
-    for (int i = 0; i < parameterClasses.length - offset; i++) {
-      args[1][i] = decodeParameterValue(parameterClasses[i + offset],
-          parameterMap.get(Constants.PARAM_TOKEN + (i + offset)));
-    }
-    return args;
-  }
-
-  public RequestDefinition getOperation(String operationName) {
-    RequestDefinition operation;
-    operation = operationRegistry.getOperation(operationName);
-    if (null == operation) {
-      throw new IllegalArgumentException("Unknown operation " + operationName);
-    }
-    return operation;
-  }
-
-  public Map<String, String> getParameterMap(JSONObject jsonObject)
-      throws JSONException {
-    Map<String, String> parameterMap = new HashMap<String, String>();
-    Iterator<?> keys = jsonObject.keys();
-    while (keys.hasNext()) {
-      String key = keys.next().toString();
-      if (key.startsWith(Constants.PARAM_TOKEN)) {
-        parameterMap.put(key, jsonObject.getString(key));
-        String value = jsonObject.isNull(key) ? null
-            : jsonObject.getString(key);
-        parameterMap.put(key, value);
-      }
-    }
-    return parameterMap;
-  }
-
-  /**
-   * Returns the property fields (name => type) for a record.
-   */
-  public Map<String, Property<?>> getPropertiesFromRecordProxyType(
-      Class<? extends EntityProxy> record) throws SecurityException {
-    if (!EntityProxy.class.isAssignableFrom(record)) {
-      return Collections.emptyMap();
-    }
-
-    Map<String, Property<?>> properties = new LinkedHashMap<String, Property<?>>();
-    Method[] methods = record.getMethods();
-    for (Method method : methods) {
-      String methodName = method.getName();
-      String propertyName = null;
-      Property<?> newProperty = null;
-      if (methodName.startsWith("get")) {
-        propertyName = Introspector.decapitalize(methodName.substring(3));
-        if (propertyName.length() == 0) {
-          continue;
-        }
-        newProperty = getPropertyFromGenericType(propertyName,
-            method.getGenericReturnType());
-      } else if (methodName.startsWith("set")) {
-        propertyName = Introspector.decapitalize(methodName.substring(3));
-        if (propertyName.length() > 0) {
-          Type[] parameterTypes = method.getGenericParameterTypes();
-          if (parameterTypes.length > 0) {
-            newProperty = getPropertyFromGenericType(propertyName,
-                parameterTypes[parameterTypes.length - 1]);
-          }
-        }
-      }
-      if (newProperty == null) {
-        continue;
-      }
-      Property<?> existing = properties.put(propertyName, newProperty);
-      if (existing != null && !existing.equals(newProperty)) {
-        throw new IllegalStateException(String.format(
-            "In %s, mismatched getter and setter types for property %s, "
-                + "found %s and %s", record.getName(), propertyName,
-            existing.getName(), newProperty.getName()));
-      }
-    }
-    return properties;
-  }
-
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  public Property<?> getPropertyFromGenericType(String propertyName, Type type) {
-    if (type instanceof ParameterizedType) {
-      ParameterizedType pType = (ParameterizedType) type;
-      Class<?> rawType = (Class<Object>) pType.getRawType();
-      Type[] typeArgs = pType.getActualTypeArguments();
-      if (Collection.class.isAssignableFrom(rawType)) {
-        if (typeArgs.length == 1) {
-          Type leafType = typeArgs[0];
-          if (leafType instanceof Class) {
-            return new CollectionProperty(propertyName, rawType,
-                (Class<?>) leafType);
-          }
-        }
-      }
-    } else {
-      return new Property<Object>(propertyName, (Class<Object>) type);
-    }
-    return null;
-  }
-
-  /**
-   * Returns the property value, in the specified type, from the request object.
-   * The value is put in the DataStore.
-   * 
-   * @throws InstantiationException
-   * @throws NoSuchMethodException
-   * @throws InvocationTargetException
-   * @throws IllegalAccessException
-   * @throws SecurityException
-   */
-  public Object getPropertyValueFromRequest(JSONArray recordArray, int index,
-      Class<?> propertyType) throws JSONException, SecurityException,
-      IllegalAccessException, InvocationTargetException, NoSuchMethodException,
-      InstantiationException {
-    return decodeParameterValue(propertyType, recordArray.get(index).toString());
-  }
-
-  public Object getPropertyValueFromRequest(JSONObject recordObject,
-      String key, Class<?> propertyType) throws JSONException,
-      SecurityException, IllegalAccessException, InvocationTargetException,
-      NoSuchMethodException, InstantiationException {
-    return decodeParameterValue(propertyType, recordObject.isNull(key) ? null
-        : recordObject.get(key).toString());
-  }
-
-  public JSONObject getViolationsAsJson(
-      Set<ConstraintViolation<Object>> violations) throws JSONException {
-    JSONObject violationsAsJson = new JSONObject();
-    for (ConstraintViolation<Object> violation : violations) {
-      violationsAsJson.put(violation.getPropertyPath().toString(),
-          violation.getMessage());
-    }
-    return violationsAsJson;
-  }
-
-  public Object invokeDomainMethod(Object domainObject, Method domainMethod,
-      Object args[]) throws IllegalAccessException, InvocationTargetException {
-    return domainMethod.invoke(domainObject, args);
-  }
-
-  @SuppressWarnings("unchecked")
-  public JSONObject processJsonRequest(String jsonRequestString)
-      throws JSONException, NoSuchMethodException, IllegalAccessException,
-      InvocationTargetException, ClassNotFoundException, SecurityException,
-      InstantiationException {
-    RequestDefinition operation;
-    JSONObject topLevelJsonObject = new JSONObject(jsonRequestString);
-
-    String operationName = topLevelJsonObject.getString(Constants.OPERATION_TOKEN);
-    String propertyRefsString = topLevelJsonObject.has(Constants.PROPERTY_REF_TOKEN)
-        ? topLevelJsonObject.getString(Constants.PROPERTY_REF_TOKEN) : "";
-    propertyRefs = RequestProperty.parse(propertyRefsString);
-
-    operation = getOperation(operationName);
-    Class<?> domainClass = Class.forName(operation.getDomainClassName());
-
-    /*
-     * The use of JRP's classloader mirrors the use of Class.forName elsewhere.
-     * It's wrong, but it's consistently wrong.
-     */
-    RequestFactoryInterfaceValidator validator = new RequestFactoryInterfaceValidator(
-        log, new RequestFactoryInterfaceValidator.ClassLoaderLoader(
-            JsonRequestProcessor.class.getClassLoader()));
-    validator.validateRequestContext(operationName.substring(0,
-        operationName.indexOf("::")));
-    if (validator.isPoisoned()) {
-      log.severe("Unable to validate RequestContext");
-      throw new RuntimeException();
-    }
-
-    Method domainMethod = domainClass.getMethod(
-        operation.getDomainMethod().getName(), operation.getParameterTypes());
-    if (Modifier.isStatic(domainMethod.getModifiers()) == operation.isInstance()) {
-      throw new IllegalArgumentException("the " + domainMethod.getName()
-          + " should " + (operation.isInstance() ? "not " : "") + "be static");
-    }
-
-    if (topLevelJsonObject.has(Constants.CONTENT_TOKEN)) {
-      // updates involvedKeys and dvsDataMap.
-      decodeDVS(topLevelJsonObject.getString(Constants.CONTENT_TOKEN));
-    }
-    // get the domain object (for instance methods) and args.
-    Object args[][] = getObjectsFromParameterMap(operation.isInstance(),
-        getParameterMap(topLevelJsonObject),
-        operation.getRequestParameterTypes());
-    // Construct beforeDataMap
-    constructBeforeDataMap();
-    // Construct afterDvsDataMap.
-    constructAfterDvsDataMapAfterCallingSetters();
-
-    // violations are the only sideEffects at this point.
-    JSONArray violationsAsJson = getViolations();
-    if (violationsAsJson.length() > 0) {
-      JSONObject envelop = new JSONObject();
-      envelop.put(Constants.VIOLATIONS_TOKEN, violationsAsJson);
-      return envelop;
-    }
-
-    // resolve parameters that are so far just EntityKeys.
-    // TODO: resolve parameters other than the domainInstance
-    EntityKey domainEntityKey = null;
-    if (args[0][0] != null) {
-      // Instance method, replace the key with the actual receiver
-      domainEntityKey = (EntityKey) args[0][0];
-      EntityData domainEntityData = afterDvsDataMap.get(domainEntityKey);
-      if (domainEntityData != null) {
-        args[0][0] = domainEntityData.entityInstance;
-        assert args[0][0] != null;
-      }
-    }
-    Object result = invokeDomainMethod(args[0][0], domainMethod, args[1]);
-
-    JSONObject sideEffects = getSideEffects();
-
-    if (result != null
-        && (result instanceof List<?>) != List.class.isAssignableFrom(operation.getDomainMethod().getReturnType())) {
-      throw new IllegalArgumentException(String.format(
-          "Type mismatch, expected %s%s, but %s returns %s",
-          List.class.isAssignableFrom(operation.getReturnType()) ? "list of "
-              : "", operation.getReturnType(), domainMethod,
-          domainMethod.getReturnType()));
-    }
-
-    JSONObject envelop = new JSONObject();
-    if (result instanceof List<?> || result instanceof Set<?>) {
-      envelop.put(Constants.RESULT_TOKEN, toJsonArray(operation, result));
-    } else if (result instanceof Number || result instanceof Enum<?>
-        || result instanceof String || result instanceof Date
-        || result instanceof Character || result instanceof Boolean) {
-      envelop.put(Constants.RESULT_TOKEN, encodePropertyValue(result));
-    } else {
-      Class<? extends EntityProxy> returnType = null;
-      if (operation.getDomainClassName().equals(FindService.class.getName())) {
-        // HACK.
-        if (involvedKeys.size() == 1) {
-          returnType = involvedKeys.iterator().next().proxyType;
-        } else {
-          System.out.println("null find");
-        }
-      } else {
-        returnType = (Class<? extends EntityProxy>) operation.getReturnType();
-      }
-      Object jsonObject = getJsonObject(result, returnType, propertyRefs);
-      envelop.put(Constants.RESULT_TOKEN, jsonObject);
-    }
-    envelop.put(Constants.SIDE_EFFECTS_TOKEN, sideEffects);
-    envelop.put(Constants.RELATED_TOKEN, encodeRelatedObjectsToJson());
-    return envelop;
-  }
-
-  public void setExceptionHandler(ExceptionHandler exceptionHandler) {
-    this.exceptionHandler = exceptionHandler;
-  }
-
-  public void setOperationRegistry(OperationRegistry operationRegistry) {
-    this.operationRegistry = operationRegistry;
-  }
-
-  public void validateKeys(JSONObject recordObject,
-      Set<String> declaredProperties) {
-    /*
-     * We don't need it by the time we're here (it's in the EntityKey), and it
-     * gums up the works.
-     */
-    recordObject.remove(Constants.ENCODED_ID_PROPERTY);
-    recordObject.remove(Constants.ENCODED_VERSION_PROPERTY);
-
-    Iterator<?> keys = recordObject.keys();
-    while (keys.hasNext()) {
-      String key = (String) keys.next();
-      if (!declaredProperties.contains(key)) {
-        throw new IllegalArgumentException("key " + key
-            + " is not permitted to be set");
-      }
-    }
-  }
-
-  /**
-   * Returns true iff the after and before JSONArray are different.
-   */
-  boolean hasChanged(JSONArray beforeArray, JSONArray afterArray)
-      throws JSONException {
-    if (beforeArray.length() != afterArray.length()) {
-      return true;
-    } else {
-      for (int i = 0; i < beforeArray.length(); i++) {
-        Object bVal = beforeArray.get(i);
-        Object aVal = afterArray.get(i);
-        if (aVal != null && bVal != null) {
-          if (aVal == bVal || aVal.equals(bVal)) {
-            continue;
-          }
-          if (aVal.getClass() != bVal.getClass()) {
-            return true;
-          }
-          if (aVal instanceof JSONObject) {
-            if (hasChanged((JSONObject) bVal, (JSONObject) aVal)) {
-              return true;
-            }
-          }
-          if (aVal instanceof JSONArray) {
-            if (hasChanged((JSONArray) bVal, (JSONArray) aVal)) {
-              return true;
-            }
-          }
-        }
-        if (aVal != bVal) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Returns true iff the after and before JSONObjects are different.
-   */
-  boolean hasChanged(JSONObject before, JSONObject after) throws JSONException {
-    if (before == null) {
-      return after != null;
-    }
-    // before != null
-    if (after == null) {
-      return true;
-    }
-    // before != null && after != null
-    Iterator<?> keyIterator = before.keys();
-    while (keyIterator.hasNext()) {
-      String key = keyIterator.next().toString();
-      Object beforeValue = before.isNull(key) ? null : before.get(key);
-      Object afterValue = after.isNull(key) ? null : after.get(key);
-      if (beforeValue == null) {
-        if (afterValue == null) {
-          continue;
-        }
-        return true;
-      }
-      if (afterValue == null) {
-        return true;
-      }
-      // equals method on JSONArray doesn't consider contents
-      if (!beforeValue.equals(afterValue)) {
-        if (beforeValue instanceof JSONArray && afterValue instanceof JSONArray) {
-          JSONArray beforeArray = (JSONArray) beforeValue;
-          JSONArray afterArray = (JSONArray) afterValue;
-          if (hasChanged(beforeArray, afterArray)) {
-            return true;
-          }
-        } else {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  private void addRelatedObject(String keyRef, Object returnValue,
-      Class<? extends EntityProxy> propertyType, RequestProperty propertyContext)
-      throws JSONException, IllegalAccessException, NoSuchMethodException,
-      InvocationTargetException {
-    if (!relatedObjects.containsKey(keyRef)) {
-      // put temporary value to prevent infinite recursion
-      relatedObjects.put(keyRef, null);
-      Object jsonObject = getJsonObject(returnValue, propertyType,
-          propertyContext);
-      if (jsonObject != JSONObject.NULL) {
-        // put real value
-        relatedObjects.put(keyRef, (JSONObject) jsonObject);
-      }
-    }
-  }
-
-  private JSONObject buildExceptionResponse(Throwable throwable) {
-    JSONObject exceptionResponse = new JSONObject();
-    ServerFailure failure = exceptionHandler.createServerFailure(throwable);
-    try {
-      JSONObject exceptionMessage = new JSONObject();
-
-      String message = failure.getMessage();
-      String exceptionType = failure.getExceptionType();
-      String stackTraceString = failure.getStackTraceString();
-
-      if (message != null && message.length() != 0) {
-        exceptionMessage.put("message", message);
-      }
-      if (exceptionType != null && exceptionType.length() != 0) {
-        exceptionMessage.put("type", exceptionType);
-      }
-      if (stackTraceString != null && stackTraceString.length() != 0) {
-        exceptionMessage.put("trace", stackTraceString);
-      }
-      exceptionResponse.put("exception", exceptionMessage);
-    } catch (JSONException jsonException) {
-      throw new IllegalStateException(jsonException);
-    }
-    return exceptionResponse;
-  }
-
-  @SuppressWarnings("unchecked")
-  private Class<? extends EntityProxy> castToRecordClass(Class<?> propertyType) {
-    return (Class<? extends EntityProxy>) propertyType;
-  }
-
-  private void constructAfterDvsDataMapAfterCallingSetters()
-      throws SecurityException, JSONException, IllegalAccessException,
-      InvocationTargetException, NoSuchMethodException, InstantiationException {
-    /*
-     * EntityKeys can be added to involvedKeys if a setter sets an EntityType
-     * that was null before calling the setter, so we need to loop in a way that
-     * will protected against ConcurrentModificationExceptions.
-     */
-    afterDvsDataMap = new HashMap<EntityKey, EntityData>();
-    Set<EntityKey> done = new HashSet<EntityKey>();
-    Set<EntityKey> queue = new HashSet<EntityKey>(involvedKeys);
-    while (!queue.isEmpty()) {
-      for (EntityKey entityKey : queue) {
-        // use the beforeDataMap and dvsDataMap
-        DvsData dvsData = dvsDataMap.get(entityKey);
-        if (dvsData != null) {
-          EntityData entityData = getEntityDataForRecordWithSettersApplied(
-              entityKey, dvsData.jsonObject, dvsData.writeOperation);
-          if (entityKey.isFuture) {
-            // TODO: assert that the id is null for entityData.entityInstance
-          }
-          afterDvsDataMap.put(entityKey, entityData);
-        } else if (entityKey.isFuture) {
-          // The client-side DVS failed to include a CREATE operation.
-          throw new RuntimeException("Future object with no dvsData");
-        } else {
-          /*
-           * Involved, but not in the deltaValueStore -- param ref to an
-           * unedited, existing object.
-           */
-          SerializedEntity serializedEntity = beforeDataMap.get(entityKey);
-          Object entityInstance = (serializedEntity == null)
-              ? getEntityInstance(entityKey) : serializedEntity.entityInstance;
-          if (entityInstance != null) {
-            afterDvsDataMap.put(entityKey, new EntityData(entityInstance, null));
-          }
-        }
-      }
-
-      // Reset the queue.
-      done.addAll(queue);
-      queue.addAll(involvedKeys);
-      queue.removeAll(done);
-    }
-  }
-
-  /**
-   * Constructs the beforeDataMap.
-   * 
-   * <p>
-   * Algorithm: go through the involvedKeys, and find the entityData
-   * corresponding to each.
-   */
-  private void constructBeforeDataMap() throws IllegalArgumentException,
-      SecurityException, IllegalAccessException, InvocationTargetException,
-      NoSuchMethodException, JSONException, InstantiationException {
-    for (EntityKey entityKey : involvedKeys) {
-      if (entityKey.isFuture) {
-        // the "before" is empty.
-        continue;
-      }
-      beforeDataMap.put(entityKey, getSerializedEntity(entityKey));
-    }
-  }
-
-  private Collection<Object> createCollection(Class<?> colType) {
-    return colType == List.class ? new ArrayList<Object>()
-        : colType == Set.class ? new HashSet<Object>() : null;
-  }
-
-  /**
-   * Decode deltaValueStore to populate involvedKeys and dvsDataMap.
-   */
-  private void decodeDVS(String content) throws SecurityException,
-      JSONException, IllegalAccessException, InvocationTargetException,
-      NoSuchMethodException, InstantiationException {
-    JSONObject jsonObject = new JSONObject(content);
-    for (WriteOperation writeOperation : WriteOperation.values()) {
-      if (!jsonObject.has(writeOperation.name())) {
-        continue;
-      }
-      JSONArray reportArray = new JSONArray(
-          jsonObject.getString(writeOperation.name()));
-      int length = reportArray.length();
-      if (length == 0) {
-        throw new IllegalArgumentException("No json array for "
-            + writeOperation.name() + " should have been sent");
-      }
-      for (int i = 0; i < length; i++) {
-        JSONObject recordWithSchema = reportArray.getJSONObject(i);
-        Iterator<?> iterator = recordWithSchema.keys();
-        String recordToken = (String) iterator.next();
-        if (iterator.hasNext()) {
-          throw new IllegalArgumentException(
-              "There cannot be more than one record token");
-        }
-        JSONObject recordObject = recordWithSchema.getJSONObject(recordToken);
-        Class<? extends EntityProxy> record = getRecordFromClassToken(recordToken);
-        EntityKey entityKey = new EntityKey(
-            recordObject.getString(Constants.ENCODED_ID_PROPERTY),
-            (writeOperation == WriteOperation.PERSIST), record);
-        involvedKeys.add(entityKey);
-        dvsDataMap.put(entityKey, new DvsData(recordObject, writeOperation));
-      }
-    }
-  }
-
-  private String encodeId(Object id) {
-    if (id instanceof String) {
-      return base64Encode((String) id);
-    }
-    return encodePropertyValue(id).toString();
-  }
-
-  @SuppressWarnings("unchecked")
-  private String encodeRelated(Class<?> propertyType, String propertyName,
-      RequestProperty propertyContext, Object returnValue)
-      throws NoSuchMethodException, IllegalAccessException,
-      InvocationTargetException, JSONException {
-    String encodedId = isEntityReference(returnValue, propertyType);
-
-    String keyRef = new EntityKey(encodedId, false,
-        (Class<? extends EntityProxy>) propertyType).toString();
-
-    addRelatedObject(keyRef, returnValue, castToRecordClass(propertyType),
-        propertyContext.getProperty(propertyName));
-    return keyRef;
-  }
-
-  private JSONObject encodeRelatedObjectsToJson() throws JSONException {
-    JSONObject array = new JSONObject();
-    for (Map.Entry<String, JSONObject> entry : relatedObjects.entrySet()) {
-      array.put(entry.getKey(), entry.getValue());
-    }
-    return array;
-  }
-
-  private JSONObject getCreateReturnRecord(EntityKey originalEntityKey,
-      EntityData entityData) throws SecurityException, JSONException,
-      IllegalAccessException, InvocationTargetException, NoSuchMethodException {
-    // id/futureId, the identifying field is sent back from the incoming record.
-    assert originalEntityKey.isFuture;
-    Object entityInstance = entityData.entityInstance;
-    assert entityInstance != null;
-    Object newId = getRawPropertyValueFromDatastore(entityInstance,
-        Constants.ENTITY_ID_PROPERTY);
-    if (newId == null) {
-      // no changeRecord for this CREATE.
-      return null; 
-    }
-
-    newId = encodeId(newId);
-    JSONObject returnObject = getJsonObjectWithIdAndVersion(
-        getSchemaAndId(originalEntityKey.proxyType, newId), entityInstance,
-        propertyRefs);
-    // violations have already been taken care of.
-    returnObject.put(Constants.ENCODED_FUTUREID_PROPERTY,
-        originalEntityKey.encodedId + "");
-    return returnObject;
-  }
-
-  /**
-   * Given param0, return the EntityKey. String is of the form
-   * "239@NO@com....EmployeeRecord" or "239@IS@com...EmployeeRecord".
-   */
-  private EntityKey getEntityKey(String string) {
-    String parts[] = string.split("@");
-    assert parts.length == 3;
-
-    String encodedId = parts[0];
-    return new EntityKey(encodedId, "IS".equals(parts[1]),
-        getRecordFromClassToken(parts[2]));
-  }
-
-  private Method getIdMethodForEntity(Class<?> entityType)
-      throws NoSuchMethodException {
-    Method idMethod = entityType.getMethod(getMethodNameFromPropertyName(
-        Constants.ENTITY_ID_PROPERTY, "get"));
-    return idMethod;
-  }
-
-  private JSONObject getJsonObjectWithIdAndVersion(String encodedId,
-      Object entityElement, RequestProperty propertyContext)
-      throws JSONException, SecurityException, NoSuchMethodException,
-      IllegalAccessException, InvocationTargetException {
-    JSONObject jsonObject = new JSONObject();
-    jsonObject.put(Constants.ENCODED_ID_PROPERTY, encodedId);
-    jsonObject.put(
-        Constants.ENCODED_VERSION_PROPERTY,
-        encodePropertyValueFromDataStore(entityElement,
-            Constants.ENTITY_VERSION_PROPERTY,
-            Constants.ENTITY_VERSION_PROPERTY.getName(), propertyContext));
-    return jsonObject;
-  }
-
-  private Object getPropertyValueFromRequestCached(JSONArray recordArray,
-      int index, Property<?> dtoProperty) throws JSONException,
-      IllegalAccessException, InvocationTargetException, NoSuchMethodException,
-      InstantiationException {
-    Object propertyValue;
-    Class<?> leafType = dtoProperty instanceof CollectionProperty<?, ?>
-        ? ((CollectionProperty<?, ?>) dtoProperty).getLeafType()
-        : dtoProperty.getType();
-
-    // if the property type is a Proxy, we expect an encoded Key string
-    if (EntityProxy.class.isAssignableFrom(leafType)) {
-      // check to see if we've already decoded this object from JSON
-      EntityKey propKey = getEntityKey(recordArray.getString(index));
-      // containsKey is used here because an entity lookup can return null
-      Object cacheValue = cachedEntityLookup.get(propKey);
-      if (cachedEntityLookup.containsKey(propKey)) {
-        propertyValue = cacheValue;
-      } else {
-        propertyValue = getPropertyValueFromRequest(recordArray, index,
-            leafType);
-      }
-    } else {
-      propertyValue = getPropertyValueFromRequest(recordArray, index, leafType);
-    }
-    return propertyValue;
-  }
-
-  private Object getPropertyValueFromRequestCached(JSONObject recordObject,
-      Map<String, Property<?>> propertiesInProxy, String key,
-      Property<?> dtoProperty) throws JSONException, IllegalAccessException,
-      InvocationTargetException, NoSuchMethodException, InstantiationException {
-    Object propertyValue;
-    if (!recordObject.isNull(key)
-        && EntityProxy.class.isAssignableFrom(dtoProperty.getType())) {
-      // if the property type is a Proxy, we expect an encoded Key string
-      EntityKey propKey = getEntityKey(recordObject.getString(key));
-      // check to see if we've already decoded this object from JSON
-      Object cacheValue = cachedEntityLookup.get(propKey);
-      // containsKey is used here because an entity lookup can return null
-      if (cachedEntityLookup.containsKey(propKey)) {
-        propertyValue = cacheValue;
-      } else {
-        propertyValue = getPropertyValueFromRequest(recordObject, key,
-            propertiesInProxy.get(key).getType());
-      }
-    } else {
-      propertyValue = getPropertyValueFromRequest(recordObject, key,
-          propertiesInProxy.get(key).getType());
-    }
-    return propertyValue;
-  }
-
-  private Object getRawPropertyValueFromDatastore(Object entityElement,
-      String propertyName) throws SecurityException, NoSuchMethodException,
-      IllegalAccessException, InvocationTargetException {
-    String methodName = getMethodNameFromPropertyName(propertyName, "get");
-    Method method = entityElement.getClass().getMethod(methodName);
-    return method.invoke(entityElement);
-  }
-
-  private String getSchemaAndId(Class<? extends EntityProxy> proxyType,
-      Object newId) {
-    return proxyType.getName() + "@" + newId;
-  }
-
-  private SerializedEntity getSerializedEntity(EntityKey entityKey)
-      throws IllegalArgumentException, SecurityException,
-      IllegalAccessException, InvocationTargetException, NoSuchMethodException,
-      JSONException, InstantiationException {
-
-    Object entityInstance = getEntityInstance(entityKey);
-    JSONObject serializedEntity = serializeEntity(entityInstance, entityKey);
-    return new SerializedEntity(entityInstance, serializedEntity);
-  }
-
-  /**
-   * Returns a JSONObject with at most three keys: CREATE, UPDATE, DELETE. Each
-   * value is a JSONArray of JSONObjects.
-   */
-  private JSONObject getSideEffects() throws SecurityException, JSONException,
-      IllegalAccessException, InvocationTargetException, NoSuchMethodException,
-      IllegalArgumentException, InstantiationException {
-    JSONObject sideEffects = new JSONObject();
-    JSONArray createArray = new JSONArray();
-    JSONArray deleteArray = new JSONArray();
-    JSONArray updateArray = new JSONArray();
-    for (EntityKey entityKey : involvedKeys) {
-      EntityData entityData = afterDvsDataMap.get(entityKey);
-      if (entityData == null) {
-        continue;
-      }
-      // handle CREATE
-      if (entityKey.isFuture) {
-        JSONObject createRecord = getCreateReturnRecord(entityKey, entityData);
-        if (createRecord != null) {
-          createArray.put(createRecord);
-        }
-        continue;
-      }
-      // handle DELETE
-      Object entityInstanceAfterOperation = getEntityInstance(entityKey);
-      if (null == entityInstanceAfterOperation) {
-        JSONObject deleteRecord = new JSONObject();
-        deleteRecord.put(Constants.ENCODED_ID_PROPERTY,
-            getSchemaAndId(entityKey.proxyType, entityKey.encodedId));
-        deleteArray.put(deleteRecord);
-        continue;
-      }
-      /*
-       * Send an UPDATE if the client is at a version different than that of the
-       * server or if the server version has changed after invoking the domain
-       * method.
-       */
-      boolean clientNeedsUpdating = false;
-      DvsData dvsData = dvsDataMap.get(entityKey);
-      if (dvsData != null && dvsData.version != null) {
-        Integer serverVersion = (Integer) getRawPropertyValueFromDatastore(
-            entityInstanceAfterOperation,
-            Constants.ENTITY_VERSION_PROPERTY.getName());
-        if (!dvsData.version.equals(serverVersion)) {
-          clientNeedsUpdating = true;
-        }
-      }
-      if (clientNeedsUpdating
-          || hasServerVersionChanged(entityKey, entityInstanceAfterOperation)) {
-        updateArray.put(getJsonObjectWithIdAndVersion(
-            getSchemaAndId(entityKey.proxyType, entityKey.encodedId),
-            entityInstanceAfterOperation, propertyRefs));
-      }
-    }
-    if (createArray.length() > 0) {
-      sideEffects.put(WriteOperation.PERSIST.name(), createArray);
-    }
-    if (deleteArray.length() > 0) {
-      sideEffects.put(WriteOperation.DELETE.name(), deleteArray);
-    }
-    if (updateArray.length() > 0) {
-      sideEffects.put(WriteOperation.UPDATE.name(), updateArray);
-    }
-    return sideEffects;
-  }
-
-  private JSONArray getViolations() throws JSONException {
-    JSONArray violations = new JSONArray();
-    for (EntityKey entityKey : involvedKeys) {
-      EntityData entityData = afterDvsDataMap.get(entityKey);
-      if (entityData == null || entityData.violations == null
-          || entityData.violations.length() == 0) {
-        continue;
-      }
-      DvsData dvsData = dvsDataMap.get(entityKey);
-      if (dvsData != null) {
-        JSONObject returnObject = new JSONObject();
-        returnObject.put(Constants.VIOLATIONS_TOKEN, entityData.violations);
-        if (entityKey.isFuture) {
-          returnObject.put(Constants.ENCODED_FUTUREID_PROPERTY,
-              entityKey.encodedId);
-          returnObject.put(Constants.ENCODED_ID_PROPERTY,
-              getSchemaAndId(entityKey.proxyType, null));
-        } else {
-          returnObject.put(Constants.ENCODED_ID_PROPERTY,
-              getSchemaAndId(entityKey.proxyType, entityKey.encodedId));
-        }
-        violations.put(returnObject);
-      }
-    }
-    return violations;
-  }
-
-  private boolean hasServerVersionChanged(EntityKey entityKey,
-      Object entityInstanceAfterOperation) throws IllegalArgumentException,
-      SecurityException, IllegalAccessException, InvocationTargetException,
-      NoSuchMethodException, JSONException {
-    SerializedEntity beforeEntity = beforeDataMap.get(entityKey);
-    if (beforeEntity != null
-        && hasChanged(beforeEntity.serializedEntity,
-            serializeEntity(entityInstanceAfterOperation, entityKey))) {
-      return true;
-    }
-    return false;
-  }
-
-  private String isEntityReference(Object entity, Class<?> proxyPropertyType)
-      throws SecurityException, NoSuchMethodException,
-      IllegalArgumentException, IllegalAccessException,
-      InvocationTargetException {
-    if (entity != null && EntityProxy.class.isAssignableFrom(proxyPropertyType)) {
-      Method idMethod = getIdMethodForEntity(entity.getClass());
-      return encodeId(idMethod.invoke(entity));
-    }
-    return null;
-  }
-
-  /**
-   * returns true if the property has been requested. TODO: use the properties
-   * that should be coming with the request.
-   * 
-   * @param p the field of entity ref
-   * @param propertyContext the root of the current dotted property reference
-   * @return has the property value been requested
-   */
-  private boolean requestedProperty(Property<?> p,
-      RequestProperty propertyContext) {
-    if (propertyContext == null) {
-      return false;
-    }
-    Class<?> leafType = p.getType();
-    if (p instanceof CollectionProperty<?, ?>) {
-      leafType = ((CollectionProperty<?, ?>) p).getLeafType();
-    }
-    if (EntityProxy.class.isAssignableFrom(leafType)) {
-      return propertyContext.hasProperty(p.getName());
-    }
-
-    return true;
-  }
-
-  /**
-   * Return the client-visible properties of an entityInstance as a JSONObject.
-   * <p>
-   * TODO: clean up the copy-paste from getJSONObject.
-   */
-  private JSONObject serializeEntity(Object entityInstance, EntityKey entityKey)
-      throws SecurityException, NoSuchMethodException,
-      IllegalArgumentException, IllegalAccessException,
-      InvocationTargetException, JSONException {
-    if (entityInstance == null) {
-      return null;
-    }
-    JSONObject jsonObject = new JSONObject();
-    jsonObject.put(Constants.ENCODED_ID_PROPERTY, entityKey.encodedId);
-    for (Property<?> p : allProperties(entityKey.proxyType)) {
-      String propertyName = p.getName();
-      String methodName = getMethodNameFromPropertyName(propertyName, "get");
-      Method method = entityInstance.getClass().getMethod(methodName);
-      Object returnValue = method.invoke(entityInstance);
-
-      Object propertyValue;
-      String encodedEntityId = isEntityReference(returnValue, p.getType());
-      if (returnValue == null) {
-        propertyValue = JSONObject.NULL;
-      } else if (encodedEntityId != null) {
-        propertyValue = encodedEntityId
-            + "@NO@"
-            + operationRegistry.getSecurityProvider().encodeClassType(
-                p.getType());
-      } else if (p instanceof CollectionProperty<?, ?>) {
-        JSONArray array = new JSONArray();
-        for (Object val : ((Collection<?>) returnValue)) {
-          String encodedIdVal = isEntityReference(val, p.getType());
-          if (encodedIdVal != null) {
-            propertyValue = encodedIdVal
-                + "@NO@"
-                + operationRegistry.getSecurityProvider().encodeClassType(
-                    p.getType());
-          } else {
-            propertyValue = encodePropertyValue(val);
-          }
-          array.put(propertyValue);
-        }
-        propertyValue = array;
-      } else {
-        propertyValue = encodePropertyValue(returnValue);
-      }
-      jsonObject.put(propertyName, propertyValue);
-    }
-    return jsonObject;
-  }
-
-  @SuppressWarnings("unchecked")
-  private Object toJsonArray(RequestDefinition operation, Object result)
-      throws IllegalAccessException, JSONException, NoSuchMethodException,
-      InvocationTargetException {
-    JSONArray jsonArray = getJsonArray((Collection<?>) result,
-        (Class<? extends EntityProxy>) operation.getReturnType());
-    return jsonArray;
-  }
-
-  /**
-   * Update propertiesInRecord based on the types of entity type.
-   */
-  private Map<String, Class<?>> updatePropertyTypes(
-      Map<String, Property<?>> propertiesInProxy, Class<?> entity) {
-    Map<String, Class<?>> toReturn = new HashMap<String, Class<?>>();
-
-    /*
-     * TODO: this logic fails if the field and getter/setter methods are
-     * differently named.
-     */
-    for (Field field : entity.getDeclaredFields()) {
-      Property<?> property = propertiesInProxy.get(field.getName());
-      if (property == null) {
-        continue;
-      }
-      Class<?> fieldType = property.getType();
-      if (property instanceof CollectionProperty<?, ?>) {
-        toReturn.put(field.getName(), fieldType);
-      } else if (fieldType != null) {
-        if (EntityProxy.class.isAssignableFrom(fieldType)) {
-          ProxyFor pFor = fieldType.getAnnotation(ProxyFor.class);
-          if (pFor != null) {
-            fieldType = pFor.value();
-          }
-          ProxyForName pFN = fieldType.getAnnotation(ProxyForName.class);
-          if (pFN != null) {
-            try {
-              fieldType = Class.forName(pFN.value(), false,
-                  Thread.currentThread().getContextClassLoader());
-            } catch (ClassNotFoundException ignored) {
-            }
-          }
-          // TODO: remove override declared method return type with field type
-          if (!fieldType.equals(field.getType())) {
-            fieldType = field.getType();
-          }
-        }
-        toReturn.put(field.getName(), fieldType);
-      }
-    }
-    return toReturn;
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/server/Logging.java b/user/src/com/google/gwt/requestfactory/server/Logging.java
index 4bbef25..4c9e04e 100644
--- a/user/src/com/google/gwt/requestfactory/server/Logging.java
+++ b/user/src/com/google/gwt/requestfactory/server/Logging.java
@@ -27,30 +27,29 @@
  */
 public class Logging {
 
-  private static StackTraceDeobfuscator deobfuscator =
-    new StackTraceDeobfuscator("");
+  private static StackTraceDeobfuscator deobfuscator = new StackTraceDeobfuscator(
+      "");
 
   /**
    * Logs a message.
-   *
+   * 
    * @param logRecordJson a log record in JSON format.
    * @throws RemoteLoggingException if logging fails
    */
-  public static void logMessage(String logRecordJson) throws
-  RemoteLoggingException {
+  public static void logMessage(String logRecordJson)
+      throws RemoteLoggingException {
     // if the header does not exist, we pass null, which is handled gracefully
     // by the deobfuscation code.
-    String strongName =
-      RequestFactoryServlet.getThreadLocalRequest().getHeader(
-          RpcRequestBuilder.STRONG_NAME_HEADER);
-    RemoteLoggingServiceUtil.logOnServer(logRecordJson,
-        strongName, deobfuscator, null);
+    String strongName = RequestFactoryServlet.getThreadLocalRequest().getHeader(
+        RpcRequestBuilder.STRONG_NAME_HEADER);
+    RemoteLoggingServiceUtil.logOnServer(logRecordJson, strongName,
+        deobfuscator, null);
   }
 
   /**
    * This function is only for server side use which is why it's not in the
    * LoggingRequest interface.
-   *
+   * 
    * @param dir a directory, specified as a String
    */
   public static void setSymbolMapsDirectory(String dir) {
@@ -63,7 +62,7 @@
 
   /**
    * Returns the id of this instance.
-   *
+   * 
    * @return a String id
    * @see #setId(String)
    */
@@ -73,7 +72,7 @@
 
   /**
    * Returns the version of this instance.
-   *
+   * 
    * @return an Integer version number
    * @see #setVersion(Integer)
    */
@@ -83,7 +82,7 @@
 
   /**
    * Sets the id on this instance.
-   *
+   * 
    * @param id a String id
    * @see #getId()
    */
@@ -93,7 +92,7 @@
 
   /**
    * Sets the version of this instance.
-   *
+   * 
    * @param version an Integer version number
    * @see #getVersion()
    */
diff --git a/user/src/com/google/gwt/requestfactory/server/OperationRegistry.java b/user/src/com/google/gwt/requestfactory/server/OperationRegistry.java
deleted file mode 100644
index 014d7e3..0000000
--- a/user/src/com/google/gwt/requestfactory/server/OperationRegistry.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-/**
- * Maps operation name to {RequestDefinition}.
- */
-interface OperationRegistry {
-
-  /**
-   * Returns the {@link RequestDefinition} associated with the given operation.
-   *
-   * @param operationName the operation name as a String
-   * @return a {@link RequestDefinition} instance
-   */
-  RequestDefinition getOperation(String operationName);
-
-  /**
-   * Returns the {@link RequestSecurityProvider} associated with this
-   * {@link OperationRegistry}.
-   *
-   * @return a {@link RequestSecurityProvider} instance
-   */
-  RequestSecurityProvider getSecurityProvider();
-}
diff --git a/user/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java b/user/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java
deleted file mode 100644
index 1ee6f8f..0000000
--- a/user/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-import com.google.gwt.requestfactory.shared.EntityProxy;
-import com.google.gwt.requestfactory.shared.InstanceRequest;
-import com.google.gwt.requestfactory.shared.ProxyFor;
-import com.google.gwt.requestfactory.shared.ProxyForName;
-import com.google.gwt.requestfactory.shared.Request;
-import com.google.gwt.requestfactory.shared.Service;
-import com.google.gwt.requestfactory.shared.ServiceName;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.List;
-import java.util.Set;
-
-/**
- * OperationRegistry which uses the operation name as a convention for
- * reflection to a method on a class, and returns an appropriate
- * {@link com.google.gwt.requestfactory.server.RequestDefinition}.
- */
-class ReflectionBasedOperationRegistry implements OperationRegistry {
-
-  class ReflectiveRequestDefinition implements RequestDefinition {
-
-    private Class<?> requestClass;
-
-    private Method requestMethod;
-
-    private Class<?> domainClass;
-
-    private Method domainMethod;
-
-    private boolean isInstance;
-
-    public ReflectiveRequestDefinition(Class<?> requestClass,
-        Method requestMethod, Class<?> domainClass, Method domainMethod,
-        boolean isInstance) {
-      this.requestClass = requestClass;
-      this.requestMethod = requestMethod;
-      this.domainClass = domainClass;
-      this.domainMethod = domainMethod;
-      this.isInstance = isInstance;
-    }
-
-    public String getDomainClassName() {
-      return domainClass.getCanonicalName();
-    }
-
-    public Method getDomainMethod() {
-      return domainMethod;
-    }
-
-    public String getDomainMethodName() {
-      return getDomainMethod().getName();
-    }
-
-    public Class<?>[] getParameterTypes() {
-      return domainMethod.getParameterTypes();
-    }
-
-    /**
-     * Treat instance invocations as though they were static implementations.
-     */
-    public Type[] getRequestParameterTypes() {
-      Type[] toReturn = requestMethod.getGenericParameterTypes();
-      if (isInstance()) {
-        // Instance method, add a "this" parameter at the beginning
-        Type[] newReturn = new Type[toReturn.length + 1];
-        newReturn[0] = domainMethod.getDeclaringClass();
-        System.arraycopy(toReturn, 0, newReturn, 1, toReturn.length);
-        toReturn = newReturn;
-      }
-      return toReturn;
-    }
-
-    public Class<?> getReturnType() {
-      Class<?> domainReturnType = getReturnTypeFromParameter(domainMethod,
-          domainMethod.getGenericReturnType());
-      Class<?> requestReturnType = getReturnTypeFromParameter(requestMethod,
-          requestMethod.getGenericReturnType());
-      if (EntityProxy.class.isAssignableFrom(requestReturnType)) {
-        ProxyFor annotation = requestReturnType.getAnnotation(ProxyFor.class);
-        ProxyForName nameAnnotation = requestReturnType.getAnnotation(ProxyForName.class);
-
-        Class<?> dtoClass = null;
-        if (annotation != null) {
-          dtoClass = annotation.value();
-        } else if (nameAnnotation != null) {
-          try {
-            dtoClass = Class.forName(nameAnnotation.value(), false,
-                Thread.currentThread().getContextClassLoader());
-          } catch (ClassNotFoundException e) {
-            throw new IllegalArgumentException(
-                "Unknown type specified in ProxyForName annotation", e);
-          }
-        } else {
-          throw new IllegalArgumentException(
-              "Missing ProxyFor annotation on proxy type " + requestReturnType);
-        }
-        if (!dtoClass.equals(domainReturnType)) {
-          throw new IllegalArgumentException("Type mismatch between "
-              + domainMethod + " return type, and " + requestReturnType
-              + "'s ProxyFor annotation " + dtoClass);
-        }
-        return requestReturnType;
-      }
-      // primitive ?
-      return requestReturnType;
-    }
-
-    public boolean isInstance() {
-      return isInstance;
-    }
-
-    public String name() {
-      return requestClass.getCanonicalName() + SCOPE_SEPARATOR
-          + getDomainMethodName();
-    }
-
-    private Class<?> getReturnTypeFromParameter(Method method, Type type) {
-      if (type instanceof ParameterizedType) {
-        ParameterizedType pType = (ParameterizedType) type;
-        Class<?> rawType = (Class<?>) pType.getRawType();
-        if (List.class.isAssignableFrom(rawType)
-            || Request.class.isAssignableFrom(rawType)
-            || InstanceRequest.class.isAssignableFrom(rawType)) {
-          Class<?> rType = getTypeArgument(pType);
-          if (rType != null) {
-            if (List.class.isAssignableFrom(rType)) {
-              return getReturnTypeFromParameter(method, rType);
-            }
-            return rType;
-          }
-          throw new IllegalArgumentException(
-              "Bad or missing type arguments for "
-                  + "List return type on method " + method);
-        } else if (Set.class.isAssignableFrom(rawType)
-            || Request.class.isAssignableFrom(rawType)
-            || InstanceRequest.class.isAssignableFrom(rawType)) {
-          Class<?> rType = getTypeArgument(pType);
-          if (rType != null) {
-            if (Set.class.isAssignableFrom(rType)) {
-              return getReturnTypeFromParameter(method, rType);
-            }
-            return rType;
-          }
-          throw new IllegalArgumentException(
-              "Bad or missing type arguments for "
-                  + "Set return type on method " + method);
-        }
-      } else {
-        // Primitive?
-        return (Class<?>) type;
-      }
-      return null;
-    }
-
-    @SuppressWarnings("unchecked")
-    private Class<?> getTypeArgument(ParameterizedType type) {
-      Type[] params = type.getActualTypeArguments();
-      Type toExamine;
-      if (params.length == 1) {
-        toExamine = params[0];
-      } else if (InstanceRequest.class.equals(type.getRawType())) {
-        toExamine = params[1];
-      } else {
-        return null;
-      }
-
-      if (toExamine instanceof ParameterizedType) {
-        // if type is for example, RequestObject<List<T>> we return T
-        return getTypeArgument((ParameterizedType) toExamine);
-      }
-      // else, it might be a case like List<T> in which case we return T
-      return (Class<Object>) toExamine;
-    }
-  }
-
-  /**
-   * The separator used to delimit scopes.
-   */
-  public static final String SCOPE_SEPARATOR = "::";
-
-  private RequestSecurityProvider securityProvider;
-
-  /**
-   * Constructs a {@link ReflectionBasedOperationRegistry} instance with a given
-   * {@link RequestSecurityProvider}.
-   * 
-   * @param securityProvider a {@link RequestSecurityProvider} instance.
-   */
-  public ReflectionBasedOperationRegistry(
-      RequestSecurityProvider securityProvider) {
-    this.securityProvider = securityProvider;
-  }
-
-  /**
-   * Turns an operation in the form of package.requestClass::method into a
-   * RequestDefinition via reflection.
-   * 
-   * @param operationName the operation name as a String
-   * @return a {@link RequestDefinition} instance
-   */
-  public RequestDefinition getOperation(String operationName) {
-    String decodedOperationName = securityProvider.mapOperation(operationName);
-    String parts[] = decodedOperationName.split(SCOPE_SEPARATOR);
-    final String reqClassName = parts[0];
-    final String domainMethodName = parts[1];
-    try {
-      // Do not invoke static initializer before checking if this class can be
-      // legally invoked
-      Class<?> requestClass = Class.forName(reqClassName, false,
-          this.getClass().getClassLoader());
-      securityProvider.checkClass(requestClass);
-      Service domainClassAnnotation = requestClass.getAnnotation(Service.class);
-      ServiceName domainClassNameAnnotation = requestClass.getAnnotation(ServiceName.class);
-      Class<?> domainClass;
-      if (domainClassAnnotation != null) {
-        domainClass = domainClassAnnotation.value();
-      } else if (domainClassNameAnnotation != null) {
-        domainClass = Class.forName(domainClassNameAnnotation.value(), false,
-            Thread.currentThread().getContextClassLoader());
-      } else {
-        return null;
-      }
-
-      Method requestMethod = findMethod(requestClass, domainMethodName);
-      Method domainMethod = findMethod(domainClass, domainMethodName);
-      if (requestMethod != null && domainMethod != null) {
-        boolean isInstance = InstanceRequest.class.isAssignableFrom(requestMethod.getReturnType());
-        if (isInstance == Modifier.isStatic(domainMethod.getModifiers())) {
-          throw new IllegalArgumentException("domain method " + domainMethod
-              + " and interface method " + requestMethod
-              + " don't match wrt instance/static");
-        }
-        return new ReflectiveRequestDefinition(requestClass, requestMethod,
-            domainClass, domainMethod, isInstance);
-      }
-
-      return null;
-    } catch (ClassNotFoundException e) {
-      throw new SecurityException("Access to non-existent class "
-          + reqClassName);
-    }
-  }
-
-  public RequestSecurityProvider getSecurityProvider() {
-    return securityProvider;
-  }
-
-  private Method findMethod(Class<?> clazz, String methodName) {
-    for (Method method : clazz.getDeclaredMethods()) {
-      if ((method.getModifiers() & Modifier.PUBLIC) != 0) {
-        if (method.getName().equals(methodName)) {
-          return method;
-        }
-      }
-    }
-    return null;
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/server/ReflectiveServiceLayer.java b/user/src/com/google/gwt/requestfactory/server/ReflectiveServiceLayer.java
new file mode 100644
index 0000000..c2bfc34
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/server/ReflectiveServiceLayer.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server;
+
+import com.google.gwt.autobean.server.impl.TypeUtils;
+import com.google.gwt.autobean.shared.ValueCodex;
+import com.google.gwt.requestfactory.server.SimpleRequestProcessor.ServiceLayer;
+import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.EntityProxyId;
+import com.google.gwt.requestfactory.shared.ProxyFor;
+import com.google.gwt.requestfactory.shared.ProxyForName;
+import com.google.gwt.requestfactory.shared.RequestContext;
+import com.google.gwt.requestfactory.shared.Service;
+import com.google.gwt.requestfactory.shared.ServiceName;
+import com.google.gwt.requestfactory.shared.messages.EntityCodex;
+import com.google.gwt.requestfactory.shared.messages.EntityCodex.EntitySource;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+/**
+ * A reflection-based implementation of ServiceLayer.
+ */
+public class ReflectiveServiceLayer implements ServiceLayer {
+
+  private static final Validator jsr303Validator;
+
+  private static final Logger log = Logger.getLogger(ReflectiveServiceLayer.class.getName());
+
+  /**
+   * All instances of the service layer that are loaded by the same classloader
+   * can use a shared validator. The use of the validator should be
+   * synchronized, since it is stateful.
+   */
+  private static final RequestFactoryInterfaceValidator validator = new RequestFactoryInterfaceValidator(
+      log, new RequestFactoryInterfaceValidator.ClassLoaderLoader(
+          ReflectiveServiceLayer.class.getClassLoader()));
+
+  static {
+    Validator found;
+    try {
+      ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
+      found = validatorFactory.getValidator();
+    } catch (ValidationException e) {
+      log.log(Level.INFO, "Unable to initialize a JSR 303 Bean Validator", e);
+      found = null;
+    }
+    jsr303Validator = found;
+  }
+
+  private static String capitalize(String name) {
+    return Character.toUpperCase(name.charAt(0))
+        + (name.length() >= 1 ? name.substring(1) : "");
+  }
+
+  public Object createDomainObject(Class<?> clazz) {
+    Throwable ex;
+    try {
+      return clazz.newInstance();
+    } catch (InstantiationException e) {
+      return report("Could not create a new instance of the requested type");
+    } catch (IllegalAccessException e) {
+      ex = e;
+    }
+    return die(ex, "Could not create a new instance of domain type %s",
+        clazz.getCanonicalName());
+  }
+
+  public Class<?> getClientType(Class<?> domainClass) {
+    String name;
+    synchronized (validator) {
+      name = validator.getEntityProxyTypeName(domainClass.getName());
+    }
+    if (name != null) {
+      return forName(name).asSubclass(EntityProxy.class);
+    }
+    if (List.class.isAssignableFrom(domainClass)) {
+      return List.class;
+    }
+    if (Set.class.isAssignableFrom(domainClass)) {
+      return Set.class;
+    }
+    if (TypeUtils.isValueType(domainClass)) {
+      return domainClass;
+    }
+    return die(null, "The domain type %s cannot be sent to the client",
+        domainClass.getCanonicalName());
+  }
+
+  public Class<?> getDomainClass(Class<?> clazz) {
+    if (List.class.equals(clazz)) {
+      return List.class;
+    } else if (Set.class.equals(clazz)) {
+      return Set.class;
+    } else if (EntityProxy.class.isAssignableFrom(clazz)) {
+      ProxyFor pf = clazz.getAnnotation(ProxyFor.class);
+      if (pf != null) {
+        return pf.value();
+      }
+      ProxyForName pfn = clazz.getAnnotation(ProxyForName.class);
+      if (pfn != null) {
+        Class<?> toReturn = forName(pfn.value());
+        return toReturn;
+      }
+    }
+    return die(null, "Could not resolve a domain type for client type %s",
+        clazz.getCanonicalName());
+  }
+
+  public String getFlatId(EntitySource source, Object domainObject) {
+    Object id = getProperty(domainObject, "id");
+    if (id == null) {
+      report("Could not retrieve id property for domain object");
+    }
+    if (!isKeyType(id.getClass())) {
+      die(null, "The type %s is not a valid key type",
+          id.getClass().getCanonicalName());
+    }
+    return EntityCodex.encode(source, id).getPayload();
+  }
+
+  public Object getProperty(Object domainObject, String property) {
+    Throwable toReport;
+    try {
+      Method method = domainObject.getClass().getMethod(
+          "get" + capitalize(property));
+      Object value = method.invoke(domainObject);
+      return value;
+    } catch (SecurityException e) {
+      toReport = e;
+    } catch (NoSuchMethodException e) {
+      toReport = e;
+    } catch (IllegalArgumentException e) {
+      toReport = e;
+    } catch (IllegalAccessException e) {
+      toReport = e;
+    } catch (InvocationTargetException e) {
+      return report(e);
+    }
+    return die(toReport, "Could not retrieve property %s", property);
+  }
+
+  public String getTypeToken(Class<?> clazz) {
+    return clazz.getName();
+  }
+
+  public int getVersion(Object domainObject) {
+    // TODO: Make version any value type
+    Object version = getProperty(domainObject, "version");
+    if (version == null) {
+      report("Could not retrieve version property");
+    }
+    if (!(version instanceof Integer)) {
+      die(null, "The getVersion() method on type %s did not return"
+          + " int or Integer", domainObject.getClass().getCanonicalName());
+    }
+    return ((Integer) version).intValue();
+  }
+
+  public Object invoke(Method domainMethod, Object[] args) {
+    Throwable ex;
+    try {
+      if (Modifier.isStatic(domainMethod.getModifiers())) {
+        return domainMethod.invoke(null, args);
+      } else {
+        Object[] realArgs = new Object[args.length - 1];
+        System.arraycopy(args, 1, realArgs, 0, realArgs.length);
+        return domainMethod.invoke(args[0], realArgs);
+      }
+    } catch (IllegalArgumentException e) {
+      ex = e;
+    } catch (IllegalAccessException e) {
+      ex = e;
+    } catch (InvocationTargetException e) {
+      return report(e);
+    }
+    return die(ex, "Could not invoke method %s", domainMethod.getName());
+  }
+
+  public Object loadDomainObject(EntitySource source, Class<?> clazz,
+      String flatId) {
+    String searchFor = "find" + clazz.getSimpleName();
+    Method found = null;
+    for (Method method : clazz.getMethods()) {
+      if (!Modifier.isStatic(method.getModifiers())) {
+        continue;
+      }
+      if (!searchFor.equals(method.getName())) {
+        continue;
+      }
+      if (method.getParameterTypes().length != 1) {
+        continue;
+      }
+      if (!isKeyType(method.getParameterTypes()[0])) {
+        continue;
+      }
+      found = method;
+      break;
+    }
+    if (found == null) {
+      die(null, "Could not find static method %s with a single"
+          + " parameter of a key type", searchFor);
+    }
+    Object id = EntityCodex.decode(source, found.getParameterTypes()[0], null,
+        flatId);
+    if (id == null) {
+      report("Cannot load a domain object with a null id");
+    }
+    Throwable ex;
+    try {
+      return found.invoke(null, id);
+    } catch (IllegalArgumentException e) {
+      ex = e;
+    } catch (IllegalAccessException e) {
+      ex = e;
+    } catch (InvocationTargetException e) {
+      return report(e);
+    }
+    return die(ex, "Cauld not load domain object using id", id.toString());
+  }
+
+  public Class<? extends EntityProxy> resolveClass(String typeToken) {
+    Class<?> found = forName(typeToken);
+    if (!EntityProxy.class.isAssignableFrom(found)) {
+      die(null, "The requested type %s is not assignable to %s", typeToken,
+          EntityProxy.class.getName());
+    }
+    synchronized (validator) {
+      validator.antidote();
+      validator.validateEntityProxy(found.getName());
+      if (validator.isPoisoned()) {
+        die(null, "The type %s did not pass RequestFactory validation",
+            found.getCanonicalName());
+      }
+    }
+    return found.asSubclass(EntityProxy.class);
+  }
+
+  public Method resolveDomainMethod(Method requestContextMethod) {
+    Class<?> enclosing = requestContextMethod.getDeclaringClass();
+    synchronized (validator) {
+      validator.antidote();
+      validator.validateRequestContext(enclosing.getName());
+      if (validator.isPoisoned()) {
+        die(null, "The type %s did not pass RequestFactory validation",
+            enclosing.getCanonicalName());
+      }
+    }
+
+    Class<?> searchIn = null;
+    Service s = enclosing.getAnnotation(Service.class);
+    if (s != null) {
+      searchIn = s.value();
+    }
+    ServiceName sn = enclosing.getAnnotation(ServiceName.class);
+    if (sn != null) {
+      searchIn = forName(sn.value());
+    }
+    if (searchIn == null) {
+      die(null, "The %s type %s did not specify a service type",
+          RequestContext.class.getSimpleName(), enclosing.getCanonicalName());
+    }
+
+    Class<?>[] parameterTypes = requestContextMethod.getParameterTypes();
+    Class<?>[] domainArgs = new Class<?>[parameterTypes.length];
+    for (int i = 0, j = domainArgs.length; i < j; i++) {
+      if (EntityProxy.class.isAssignableFrom(parameterTypes[i])) {
+        domainArgs[i] = getDomainClass(parameterTypes[i].asSubclass(EntityProxy.class));
+      } else if (EntityProxyId.class.isAssignableFrom(parameterTypes[i])) {
+        domainArgs[i] = TypeUtils.ensureBaseType(TypeUtils.getSingleParameterization(
+            EntityProxyId.class,
+            requestContextMethod.getGenericParameterTypes()[i]));
+      } else {
+        domainArgs[i] = parameterTypes[i];
+      }
+    }
+
+    Throwable ex;
+    try {
+      return searchIn.getMethod(requestContextMethod.getName(), domainArgs);
+    } catch (SecurityException e) {
+      ex = e;
+    } catch (NoSuchMethodException e) {
+      return report("Could not locate domain method %s",
+          requestContextMethod.getName());
+    }
+    return die(ex, "Could not get domain method %s in type %s",
+        requestContextMethod.getName(), searchIn.getCanonicalName());
+  }
+
+  public Method resolveRequestContextMethod(String requestContextClass,
+      String methodName) {
+    Class<?> searchIn = forName(requestContextClass);
+    for (Method method : searchIn.getMethods()) {
+      if (method.getName().equals(methodName)) {
+        return method;
+      }
+    }
+    return report("Could not locate %s method %s::%s",
+        RequestContext.class.getSimpleName(), requestContextClass, methodName);
+  }
+
+  public void setProperty(Object domainObject, String property,
+      Class<?> expectedType, Object value) {
+    Method getId;
+    Throwable ex;
+    try {
+      getId = domainObject.getClass().getMethod("set" + capitalize(property),
+          expectedType);
+      getId.invoke(domainObject, value);
+      return;
+    } catch (SecurityException e) {
+      ex = e;
+    } catch (NoSuchMethodException e) {
+      ex = e;
+    } catch (IllegalArgumentException e) {
+      ex = e;
+    } catch (IllegalAccessException e) {
+      ex = e;
+    } catch (InvocationTargetException e) {
+      report(e);
+      return;
+    }
+    die(ex, "Could not locate getter for property %s in type %s", property,
+        domainObject.getClass().getCanonicalName());
+  }
+
+  public <T> Set<ConstraintViolation<T>> validate(T domainObject) {
+    if (jsr303Validator != null) {
+      return jsr303Validator.validate(domainObject);
+    }
+    return Collections.emptySet();
+  }
+
+  /**
+   * Throw a fatal error up into the top-level processing code. This method
+   * should be used to provide diagnostic information that will help the
+   * end-developer track down problems when that data would expose
+   * implementation details of the server to the client.
+   */
+  private <T> T die(Throwable e, String message, Object... args)
+      throws UnexpectedException {
+    String msg = String.format(message, args);
+    log.log(Level.SEVERE, msg, e);
+    throw new UnexpectedException(msg, e);
+  }
+
+  private Class<?> forName(String name) {
+    try {
+      return Class.forName(name, false,
+          Thread.currentThread().getContextClassLoader());
+    } catch (ClassNotFoundException e) {
+      return die(e, "Could not locate class %s", name);
+    }
+  }
+
+  private boolean isKeyType(Class<?> clazz) {
+    return ValueCodex.canDecode(clazz)
+        || EntityProxy.class.isAssignableFrom(clazz);
+  }
+
+  /**
+   * Report an exception thrown by code that is under the control of the
+   * end-developer.
+   */
+  private <T> T report(InvocationTargetException userGeneratedException)
+      throws ReportableException {
+    throw new ReportableException(userGeneratedException.getCause());
+  }
+
+  /**
+   * Return a message to the client. This method should not include any data
+   * that was not sent to the server by the client to avoid leaking data.
+   * 
+   * @see #die()
+   */
+  private <T> T report(String msg, Object... args) throws ReportableException {
+    throw new ReportableException(String.format(msg, args));
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/server/ReportableException.java b/user/src/com/google/gwt/requestfactory/server/ReportableException.java
new file mode 100644
index 0000000..292b452
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/server/ReportableException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server;
+
+/**
+ * Encapsulates exceptions that should be thrown back to the client.
+ */
+@SuppressWarnings("serial")
+class ReportableException extends RuntimeException {
+  public ReportableException(String msg) {
+    super(msg);
+  }
+
+  public ReportableException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+
+  public ReportableException(Throwable cause) {
+    super("Server Error: " + cause.getMessage(), cause);
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestDefinition.java b/user/src/com/google/gwt/requestfactory/server/RequestDefinition.java
deleted file mode 100644
index 896d88b..0000000
--- a/user/src/com/google/gwt/requestfactory/server/RequestDefinition.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-
-/**
- * Implemented by enums that define the mapping between request objects and
- * service methods.
- */
-interface RequestDefinition {
-  /**
-   * Returns the name of the (domain) class that contains the method to be
-   * invoked on the server.
-   *
-   * @return the domain class name as a String
-   */
-  String getDomainClassName();
-
-  /**
-   * Returns the method to be invoked on the server.
-   *
-   * @return the domain Method
-   */
-  Method getDomainMethod();
-
-  /**
-   * Returns the parameter types of the method to be invoked on the server.
-   *
-   * @return an array of Class objects for each parameter type
-   */
-  Class<?>[] getParameterTypes();
-
-  /**
-   * Returns the request parameter types.
-   *
-   * @return an array of Type objects for each request parameter
-   */
-  Type[] getRequestParameterTypes();
-
-  /**
-   * Returns the return type of the method to be invoked on the server.
-   * 
-   * @return a Class object representing the return type
-   */
-  Class<?> getReturnType();
-
-  /**
-   * Returns whether the domain method is an instance method.
-   *
-   * @return {@code true} if the domain method is an instance method
-   */
-  boolean isInstance();
-
-  /**
-   * Returns the name.
-   * 
-   * @return the name as a String
-   */
-  String name();
-}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidator.java b/user/src/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidator.java
index 7195af0..bbe81e9 100644
--- a/user/src/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidator.java
+++ b/user/src/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidator.java
@@ -28,7 +28,6 @@
 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.gwt.requestfactory.client.impl.FindRequest;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.InstanceRequest;
 import com.google.gwt.requestfactory.shared.ProxyFor;
@@ -61,6 +60,26 @@
  * 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(Thread.currentThread().getContextClassLoader()));
+ *   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.gwt.requestfactory.server.RequestFactoryInterfaceValidator \
+ *   com.example.MyRequestFactory
+ * </pre>
  */
 public class RequestFactoryInterfaceValidator {
   /**
@@ -91,12 +110,16 @@
   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);
   }
@@ -201,12 +224,14 @@
     }
 
     public void poison(String msg, Object... args) {
+      poison();
       logger.logp(Level.SEVERE, currentType(), currentMethod(),
           String.format(msg, args));
       poisoned = true;
     }
 
     public void poison(String msg, Throwable t) {
+      poison();
       logger.logp(Level.SEVERE, currentType(), currentMethod(), msg, t);
       poisoned = true;
     }
@@ -247,6 +272,19 @@
       }
       return null;
     }
+
+    /**
+     * Populate {@link RequestFactoryInterfaceValidator#badTypes} with the
+     * current context.
+     */
+    private void poison() {
+      if (currentType != null) {
+        badTypes.add(currentType.getClassName());
+      }
+      if (parent != null) {
+        parent.poison();
+      }
+    }
   }
 
   /**
@@ -396,9 +434,15 @@
   }
 
   /**
+   * A set of binary type names that are known to be bad.
+   */
+  private final Set<String> badTypes = new HashSet<String>();
+
+  /**
    * Maps client types (e.g. FooProxy) to server domain types (e.g. Foo).
    */
   private final Map<Type, Type> clientToDomainType = new HashMap<Type, Type>();
+  private final Map<Type, Type> domainToClientType = new HashMap<Type, Type>();
   /**
    * The type {@link EntityProxy}.
    */
@@ -417,6 +461,10 @@
    * A cache of all methods defined in a type hierarchy.
    */
   private final Map<Type, Set<RFMethod>> methodsInHierarchy = new HashMap<Type, Set<RFMethod>>();
+  /**
+   * The type {@link Object}.
+   */
+  private final Type objectType = Type.getObjectType("java/lang/Object");
   private final ErrorContext parentLogger;
   private boolean poisoned;
   /**
@@ -450,6 +498,14 @@
   }
 
   /**
+   * Reset the poisoned status of the validator so that it may be reused without
+   * destroying cached state.
+   */
+  public void antidote() {
+    poisoned = false;
+  }
+
+  /**
    * Returns true if validation failed.
    */
   public boolean isPoisoned() {
@@ -481,13 +537,7 @@
    *          EntityProxy subtype
    */
   public void validateEntityProxy(String binaryName) {
-    if (!Name.isBinaryName(binaryName)) {
-      parentLogger.poison("%s is not a binary name", binaryName);
-      return;
-    }
-
-    // Don't revalidate the same type
-    if (!validatedTypes.add(binaryName)) {
+    if (fastFail(binaryName)) {
       return;
     }
 
@@ -555,18 +605,7 @@
    * @see #validateEntityProxy(String)
    */
   public void validateRequestContext(String binaryName) {
-    if (!Name.isBinaryName(binaryName)) {
-      parentLogger.poison("%s is not a binary name", binaryName);
-      return;
-    }
-
-    // Don't revalidate the same type
-    if (!validatedTypes.add(binaryName)) {
-      return;
-    }
-
-    if (FindRequest.class.getName().equals(binaryName)) {
-      // Ignore FindRequest, it's a huge hack
+    if (fastFail(binaryName)) {
       return;
     }
 
@@ -620,13 +659,7 @@
    * @see #validateRequestContext(String)
    */
   public void validateRequestFactory(String binaryName) {
-    if (!Name.isBinaryName(binaryName)) {
-      parentLogger.poison("%s is not a binary name", binaryName);
-      return;
-    }
-
-    // Don't revalidate the same type
-    if (!validatedTypes.add(binaryName)) {
+    if (fastFail(binaryName)) {
       return;
     }
 
@@ -652,6 +685,16 @@
   }
 
   /**
+   * Given the binary name of a domain type, return the EntityProxy type that
+   * has been seen to map to the domain type.
+   */
+  String getEntityProxyTypeName(String domainTypeNameBinaryName) {
+    Type key = Type.getObjectType(BinaryName.toInternalName(domainTypeNameBinaryName));
+    Type found = domainToClientType.get(key);
+    return found == null ? null : found.getClassName();
+  }
+
+  /**
    * Check that a given method RequestContext method declaration can be mapped
    * to the server's domain type.
    */
@@ -687,6 +730,9 @@
    * <code>getVersion</code> methods.
    */
   private void checkIdAndVersion(ErrorContext logger, Type domainType) {
+    if (objectType.equals(domainType)) {
+      return;
+    }
     logger = logger.setType(domainType);
     Method getIdString = new Method("getId", "()Ljava/lang/String;");
     Method getIdLong = new Method("getId", "()Ljava/lang/Long;");
@@ -729,6 +775,29 @@
   }
 
   /**
+   * 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.
    */
@@ -855,6 +924,8 @@
     }
     if (isValueType(logger, clientType) || isCollectionType(logger, clientType)) {
       toReturn = clientType;
+    } else if (entityProxyIntf.equals(clientType)) {
+      toReturn = objectType;
     } else {
       logger = logger.setType(clientType);
       DomainMapper pv = new DomainMapper(logger);
@@ -869,6 +940,15 @@
       }
     }
     clientToDomainType.put(clientType, toReturn);
+    if (isAssignable(logger, entityProxyIntf, clientType)) {
+      Type previousProxyType = domainToClientType.put(toReturn, clientType);
+      if (previousProxyType != null) {
+        logger.poison(
+            "The domain type %s has more than one proxy type: %s and %s",
+            toReturn.getClassName(), previousProxyType.getClassName(),
+            clientType.getClassName());
+      }
+    }
     return toReturn;
   }
 
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java b/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
index 74ff36c..f977c5c 100644
--- a/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
+++ b/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
@@ -51,6 +51,7 @@
 @SuppressWarnings("serial")
 public class RequestFactoryServlet extends HttpServlet {
 
+  private static final boolean DUMP_PAYLOAD = Boolean.getBoolean("gwt.rpc.dumpPayload");
   private static final String JSON_CHARSET = "UTF-8";
   private static final String JSON_CONTENT_TYPE = "application/json";
   private static final Logger log = Logger.getLogger(RequestFactoryServlet.class.getCanonicalName());
@@ -64,7 +65,7 @@
 
   /**
    * Returns the thread-local {@link HttpServletRequest}.
-   *
+   * 
    * @return an {@link HttpServletRequest} instance
    */
   public static HttpServletRequest getThreadLocalRequest() {
@@ -73,14 +74,14 @@
 
   /**
    * Returns the thread-local {@link HttpServletResponse}.
-   *
+   * 
    * @return an {@link HttpServletResponse} instance
    */
   public static HttpServletResponse getThreadLocalResponse() {
     return perThreadResponse.get();
   }
 
-  private final ExceptionHandler exceptionHandler;
+  private final SimpleRequestProcessor processor;
 
   /**
    * Constructs a new {@link RequestFactoryServlet} with a
@@ -93,11 +94,12 @@
   /**
    * Use this constructor in subclasses to provide a custom
    * {@link ExceptionHandler}.
-   *
+   * 
    * @param exceptionHandler an {@link ExceptionHandler} instance
    */
   public RequestFactoryServlet(ExceptionHandler exceptionHandler) {
-    this.exceptionHandler = exceptionHandler;
+    processor = new SimpleRequestProcessor(new ReflectiveServiceLayer());
+    processor.setExceptionHandler(exceptionHandler);
   }
 
   /**
@@ -114,13 +116,15 @@
 
     perThreadRequest.set(request);
     perThreadResponse.set(response);
-    
+
     // No new code should be placed outside of this try block.
     try {
       ensureConfig();
       String jsonRequestString = RPCServletUtils.readContent(request,
           JSON_CONTENT_TYPE, JSON_CHARSET);
-      response.setStatus(HttpServletResponse.SC_OK);
+      if (DUMP_PAYLOAD) {
+        System.out.println(">>> " + jsonRequestString);
+      }
       PrintWriter writer = response.getWriter();
 
       try {
@@ -130,19 +134,18 @@
           response.setHeader("login", userInfo.getLoginUrl());
           response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
         } else {
+          String payload = processor.process(jsonRequestString);
+          if (DUMP_PAYLOAD) {
+            System.out.println("<<< " + payload);
+          }
           response.setHeader("userId", String.format("%s", userInfo.getId()));
           response.setStatus(HttpServletResponse.SC_OK);
-          RequestProcessor<String> requestProcessor = new JsonRequestProcessor();
-          requestProcessor.setOperationRegistry(new ReflectionBasedOperationRegistry(
-              new DefaultSecurityProvider()));
-          requestProcessor.setExceptionHandler(exceptionHandler);
           response.setContentType(RequestFactory.JSON_CONTENT_TYPE_UTF8);
-          writer.print(requestProcessor.decodeAndInvokeRequest(jsonRequestString));
+          writer.print(payload);
           writer.flush();
         }
-      } catch (RequestProcessingException e) {
-        writer.print((String) e.getResponse());
-        writer.flush();
+      } catch (RuntimeException e) {
+        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
         log.log(Level.SEVERE, "Unexpected error", e);
       }
     } finally {
@@ -160,9 +163,9 @@
     if (userInfoClass != null) {
       UserInformation.setUserInformationImplClass(userInfoClass);
     }
-    
-    String symbolMapsDirectory =
-      getServletConfig().getInitParameter("symbolMapsDirectory");
+
+    String symbolMapsDirectory = getServletConfig().getInitParameter(
+        "symbolMapsDirectory");
     if (symbolMapsDirectory != null) {
       Logging.setSymbolMapsDirectory(symbolMapsDirectory);
     }
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestProcessingException.java b/user/src/com/google/gwt/requestfactory/server/RequestProcessingException.java
deleted file mode 100644
index 4c216bd..0000000
--- a/user/src/com/google/gwt/requestfactory/server/RequestProcessingException.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-/**
- * Exception thrown during by a {@link RequestProcessor} when 
- * an unexpected exception is caught. Includes an appropriate
- * response of T to send to the client.
- */
-class RequestProcessingException extends Exception {
-  private final Object response;
-
-  /**
-   * Constructs a new {@link RequestProcessingException} with a given message,
-   * Throwable cause, and response Object.
-   *
-   * @param message a message to display
-   * @param t the Throwable cause
-   * @param response a response Object, may be cast to T by a
-   *     {@link RequestProcessor}&lt;T&gt;
-   */
-  public RequestProcessingException(String message, Throwable t, Object response) {
-    super(message, t);
-    this.response = response;
-  }
-  
-  Object getResponse() {
-    return response;
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestProcessor.java b/user/src/com/google/gwt/requestfactory/server/RequestProcessor.java
deleted file mode 100644
index 0e5718a..0000000
--- a/user/src/com/google/gwt/requestfactory/server/RequestProcessor.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-/**
- * Simple interface to abstract the underlying RequestFactory RPC mechanism. A
- * serialized object of type T is provided, such as a String in the case of JSON
- * requests, and a serialized return value of the same type is returned.
- * @param <T> the type of encoding used to serialize the request (e.g. String)
- */
-interface RequestProcessor<T> {
-  /**
-   * Decodes request, invokes methods, and re-encoded resulting return values.
-   *
-   * @param encodedRequest an encoded request of type T
-   * @return a decoded instance of type T
-   * @throws RequestProcessingException if an error occurs
-   */
-  T decodeAndInvokeRequest(T encodedRequest) throws RequestProcessingException;
-
-  /**
-   * Sets the ExceptionHandler to use to convert exceptions caused by
-   * method invocations into failure messages sent back to the client.
-   * 
-   * @param exceptionHandler an implementation, such as
-   *        {@code DefaultExceptionHandler}
-   */
-  void setExceptionHandler(ExceptionHandler exceptionHandler);
-
-  /**
-   * Sets the OperationRegistry to be used for looking up invocation metadata.
-   * 
-   * @param registry an implementation, such as
-   *          {@link ReflectionBasedOperationRegistry}
-   */
-  void setOperationRegistry(OperationRegistry registry);
-}
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestProperty.java b/user/src/com/google/gwt/requestfactory/server/RequestProperty.java
deleted file mode 100644
index 10ae950..0000000
--- a/user/src/com/google/gwt/requestfactory/server/RequestProperty.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * Represents one piece in a property reference sequence.
- */
-class RequestProperty implements Iterable<RequestProperty> {
-
-  /**
-   * Merge two property chains.
-   * 
-   * @param properties a list of {@link RequestProperty} instances
-   * @return a new {@link RequestProperty} instance
-   */
-  public static RequestProperty coalesce(RequestProperty... properties) {
-    assert properties.length > 0;
-    RequestProperty root = new RequestProperty("");
-    for (RequestProperty prop : properties) {
-      if ("".equals(prop.getPropertyName())) {
-        for (RequestProperty p : prop) {
-          root.mergeProperty(p);
-        }
-      } else {
-        root.mergeProperty(prop);
-      }
-    }
-    return root;
-  }
-
-  /**
-   * Parse selectors to obtain a {@link RequestProperty}.
-   *
-   * @param selectors a String of selectors separated by commas
-   * @return a new {@link RequestProperty} instance
-   */
-  public static RequestProperty parse(String selectors) {
-    String parts[] = selectors.split("\\s*,\\s*");
-    RequestProperty props[] = new RequestProperty[parts.length];
-    for (int i = 0; i < parts.length; i++) {
-      RequestProperty newProp = new RequestProperty("");
-      newProp.parseInternal(parts[i]);
-      props[i] = newProp;
-    }
-    return props.length == 1 ? props[0] : coalesce(props);
-  }
-
-  private String propertyName;
-  private Map<String, RequestProperty> subProperties;
-
-  private RequestProperty(String propertyName) {
-    this.propertyName = propertyName;
-  }
-
-  /**
-   * Add a property reference to this {@link RequestProperty}.
-   *
-   * @param propertyRef a {@link RequestProperty} instance
-   * @return this instance
-   */
-  public RequestProperty add(RequestProperty propertyRef) {
-    if (subProperties == null) {
-      subProperties = new HashMap<String, RequestProperty>();
-    }
-    subProperties.put(propertyRef.getPropertyName(), propertyRef);
-    return this;
-  }
-
-  /**
-   * Returns the value of a property defined as a sub-property of
-   * this instance.
-   *
-   * @param propName the property name as a String
-   * @return a {@link RequestProperty} instance or null
-   */
-  public RequestProperty getProperty(String propName) {
-    return subProperties == null ? null : subProperties.get(propName);
-  }
-
-  /**
-   * Returns the top-level property name associated with this instance.
-   *
-   * @return the property name as a String
-   */
-  public String getPropertyName() {
-    return propertyName;
-  }
-
-  /**
-   * Returns whether a given property is defined as a sub-property of this
-   * instance.
-   * 
-   * @param name the property name as a String
-   * @return {@code} true if the property exists
-   */
-  public boolean hasProperty(String name) {
-    return subProperties == null ? false : subProperties.containsKey(name);
-  }
-
-  /**
-   * Returns an iterator over the properties of this instance.
-   *
-   * @return an Iterator over {@link RequestProperty} instances
-   */
-  public Iterator<RequestProperty> iterator() {
-    return subProperties == null ? emptyIterator()
-        : subProperties.values().iterator();
-  }
-
-  /**
-   * Merge a given property into this instance.
-   * 
-   * @param property a {@link RequestProperty} instance
-   * @return the {@link RequestProperty} from this instance corresponding to the
-   *         name of the given property, or {@code null}.
-   */
-  public RequestProperty mergeProperty(RequestProperty property) {
-    RequestProperty foundProp = getProperty(property.getPropertyName());
-    if (foundProp == null && !"".equals(property.getPropertyName())) {
-      add(property);
-    } else {
-      for (RequestProperty p : property) {
-        if (foundProp == null) {
-          add(p);
-        } else {
-          foundProp.mergeProperty(p);
-        }
-      }
-    }
-    return foundProp;
-  }
-
-  @SuppressWarnings({"cast", "unchecked"})
-  private Iterator<RequestProperty> emptyIterator() {
-    return (Iterator<RequestProperty>) Collections.EMPTY_MAP.values().iterator();
-  }
-
-  private RequestProperty getOrCreate(String part) {
-    RequestProperty prop = getProperty(part);
-    if (prop == null) {
-      prop = new RequestProperty(part);
-      add(prop);
-    }
-    return prop;
-  }
-
-  private RequestProperty parseInternal(String sequence) {
-    int dotIndex = sequence.indexOf('.');
-    String part = dotIndex > -1 ? sequence.substring(0, dotIndex) : sequence;
-    RequestProperty prop = getOrCreate(part);
-    add(prop);
-
-    if (dotIndex > -1) {
-      if (dotIndex < sequence.length() - 1) {
-        String next = sequence.substring(dotIndex + 1);
-        if ("".equals(next)) {
-          throw new IllegalArgumentException("Empty property name '..' not allowed in " + sequence);
-        }
-        if (next.length() > 0) {
-          return prop.parseInternal(next);
-        }
-      }
-      throw new IllegalArgumentException("Trailing '.' in with() call " + sequence);
-    }
-    return prop;
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java b/user/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java
deleted file mode 100644
index 8ff9ae8..0000000
--- a/user/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-/**
- * Enforces security policy for operations and classes, as well as permitting
- * request obfuscation.
- */
-interface RequestSecurityProvider {
-
-  /**
-   * Throws exception if argument is not accessible via remote requests.
-   * 
-   * @param clazz a Class instance
-   * @throws SecurityException if the argument is not accessible via remote
-   *           requests
-   */
-  void checkClass(Class<?> clazz) throws SecurityException;
-
-  /**
-   * Encode a Class type into a String token.
-   *
-   * @param type a Class instance
-   * @return an encoded String token
-   */
-  String encodeClassType(Class<?> type);
-
-  /**
-   * Optionally decodes a previously encoded operation. Throws exception if
-   * argument is not a legal operation.
-   *
-   * @param operationName the operation name as a String
-   * @return a decoded operation name
-   * @throws SecurityException if the argument is not a legal operation
-   */
-  String mapOperation(String operationName) throws SecurityException;
-}
diff --git a/user/src/com/google/gwt/requestfactory/server/SimpleRequestProcessor.java b/user/src/com/google/gwt/requestfactory/server/SimpleRequestProcessor.java
new file mode 100644
index 0000000..e8dede4
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/server/SimpleRequestProcessor.java
@@ -0,0 +1,735 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server;
+
+import com.google.gwt.autobean.server.AutoBeanFactoryMagic;
+import com.google.gwt.autobean.server.Configuration;
+import com.google.gwt.autobean.server.impl.TypeUtils;
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanCodex;
+import com.google.gwt.autobean.shared.AutoBeanUtils;
+import com.google.gwt.autobean.shared.AutoBeanVisitor;
+import com.google.gwt.autobean.shared.Splittable;
+import com.google.gwt.autobean.shared.ValueCodex;
+import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.EntityProxyId;
+import com.google.gwt.requestfactory.shared.InstanceRequest;
+import com.google.gwt.requestfactory.shared.ServerFailure;
+import com.google.gwt.requestfactory.shared.WriteOperation;
+import com.google.gwt.requestfactory.shared.impl.Constants;
+import com.google.gwt.requestfactory.shared.impl.EntityProxyCategory;
+import com.google.gwt.requestfactory.shared.impl.IdFactory;
+import com.google.gwt.requestfactory.shared.impl.SimpleEntityProxyId;
+import com.google.gwt.requestfactory.shared.messages.EntityCodex;
+import com.google.gwt.requestfactory.shared.messages.EntityCodex.EntitySource;
+import com.google.gwt.requestfactory.shared.messages.IdUtil;
+import com.google.gwt.requestfactory.shared.messages.InvocationMessage;
+import com.google.gwt.requestfactory.shared.messages.MessageFactory;
+import com.google.gwt.requestfactory.shared.messages.OperationMessage;
+import com.google.gwt.requestfactory.shared.messages.RequestMessage;
+import com.google.gwt.requestfactory.shared.messages.ResponseMessage;
+import com.google.gwt.requestfactory.shared.messages.ServerFailureMessage;
+import com.google.gwt.requestfactory.shared.messages.ViolationMessage;
+import com.google.gwt.user.server.Base64Utils;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.validation.ConstraintViolation;
+
+/**
+ * Processes request payloads from a RequestFactory client. This implementation
+ * is stateless. A single instance may be reused and is thread-safe.
+ */
+public class SimpleRequestProcessor {
+  /**
+   * Abstracts all reflection operations from the request processor.
+   */
+  public interface ServiceLayer {
+    Object createDomainObject(Class<?> clazz);
+
+    /**
+     * The way to introduce polymorphism.
+     */
+    Class<?> getClientType(Class<?> domainClass);
+
+    Class<?> getDomainClass(Class<?> clazz);
+
+    String getFlatId(EntitySource source, Object domainObject);
+
+    Object getProperty(Object domainObject, String property);
+
+    String getTypeToken(Class<?> domainClass);
+
+    int getVersion(Object domainObject);
+
+    Object invoke(Method domainMethod, Object[] args);
+
+    Object loadDomainObject(EntitySource source, Class<?> clazz, String flatId);
+
+    Class<? extends EntityProxy> resolveClass(String typeToken);
+
+    Method resolveDomainMethod(Method requestContextMethod);
+
+    Method resolveRequestContextMethod(String requestContextClass,
+        String methodName);
+
+    void setProperty(Object domainObject, String property,
+        Class<?> expectedType, Object value);
+
+    <T> Set<ConstraintViolation<T>> validate(T domainObject);
+  }
+
+  /**
+   * This parameterization is so long, it improves readability to have a
+   * specific type.
+   */
+  @SuppressWarnings("serial")
+  private static class IdToEntityMap extends
+      HashMap<SimpleEntityProxyId<?>, AutoBean<? extends EntityProxy>> {
+  }
+
+  private class RequestState implements EntityCodex.EntitySource {
+    private final IdToEntityMap beans = new IdToEntityMap();
+    private final Map<Object, Integer> domainObjectsToClientId;
+    private final IdFactory idFactory;
+
+    public RequestState() {
+      idFactory = new IdFactory() {
+        @Override
+        @SuppressWarnings("unchecked")
+        protected <P extends EntityProxy> Class<P> getTypeFromToken(
+            String typeToken) {
+          return (Class<P>) service.resolveClass(typeToken);
+        }
+
+        @Override
+        protected String getTypeToken(Class<?> clazz) {
+          return service.getTypeToken(clazz);
+        }
+      };
+      domainObjectsToClientId = new IdentityHashMap<Object, Integer>();
+    }
+
+    public RequestState(RequestState parent) {
+      idFactory = parent.idFactory;
+      domainObjectsToClientId = parent.domainObjectsToClientId;
+    }
+
+    public <Q extends EntityProxy> AutoBean<Q> getBeanForPayload(
+        SimpleEntityProxyId<Q> id) {
+      @SuppressWarnings("unchecked")
+      AutoBean<Q> toReturn = (AutoBean<Q>) beans.get(id);
+      if (toReturn == null) {
+        toReturn = AutoBeanFactoryMagic.createBean(id.getProxyClass(),
+            CONFIGURATION);
+        toReturn.setTag(STABLE_ID, id);
+
+        // Resolve the domain object
+        Class<?> domainClass = service.getDomainClass(id.getProxyClass());
+
+        Object domain;
+        if (id.isEphemeral()) {
+          domain = service.createDomainObject(domainClass);
+          // Don't call getFlatId here, resolve the ids after invocations
+          domainObjectsToClientId.put(domain, id.getClientId());
+        } else {
+          domain = service.loadDomainObject(this, domainClass,
+              fromBase64(id.getServerId()));
+        }
+        toReturn.setTag(DOMAIN_OBJECT, domain);
+
+        beans.put(id, toReturn);
+      }
+      return toReturn;
+    }
+
+    /**
+     * EntityCodex support.
+     */
+    public <Q extends EntityProxy> AutoBean<Q> getBeanForPayload(
+        String serializedProxyId) {
+      String typeToken = IdUtil.getTypeToken(serializedProxyId);
+      SimpleEntityProxyId<Q> id;
+      if (IdUtil.isEphemeral(serializedProxyId)) {
+        id = idFactory.getId(typeToken, null,
+            IdUtil.getClientId(serializedProxyId));
+      } else {
+        id = idFactory.getId(typeToken, IdUtil.getServerId(serializedProxyId));
+      }
+      return getBeanForPayload(id);
+    }
+
+    /**
+     * If the domain object was sent with an ephemeral id, return the client id.
+     */
+    public Integer getClientId(Object domainEntity) {
+      return domainObjectsToClientId.get(domainEntity);
+    }
+
+    /**
+     * EntityCodex support.
+     */
+    public String getSerializedProxyId(EntityProxyId<?> stableId) {
+      SimpleEntityProxyId<?> impl = (SimpleEntityProxyId<?>) stableId;
+      if (impl.isEphemeral()) {
+        return IdUtil.ephemeralId(impl.getClientId(),
+            service.getTypeToken(stableId.getProxyClass()));
+      } else {
+        return IdUtil.persistedId(impl.getServerId(),
+            service.getTypeToken(stableId.getProxyClass()));
+      }
+    }
+
+    /**
+     * EntityCodex support.
+     */
+    public boolean isEntityType(Class<?> clazz) {
+      return EntityProxy.class.isAssignableFrom(clazz);
+    }
+  }
+
+  private static final Configuration CONFIGURATION = new Configuration.Builder().setCategories(
+      EntityProxyCategory.class).setNoWrap(EntityProxyId.class).build();
+  private static final MessageFactory FACTORY = AutoBeanFactoryMagic.create(MessageFactory.class);
+
+  // Tag constants
+  private static final String DOMAIN_OBJECT = "domainObject";
+  private static final String IN_RESPONSE = "inResponse";
+  private static final String STABLE_ID = "stableId";
+
+  private static String fromBase64(String encoded) {
+    try {
+      return new String(Base64Utils.fromBase64(encoded), "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new UnexpectedException(e);
+    }
+  }
+
+  private static String toBase64(String data) {
+    try {
+      return Base64Utils.toBase64(data.getBytes("UTF-8"));
+    } catch (UnsupportedEncodingException e) {
+      throw new UnexpectedException(e);
+    }
+  }
+
+  private ExceptionHandler exceptionHandler = new DefaultExceptionHandler();
+  private final ServiceLayer service;
+
+  public SimpleRequestProcessor(ServiceLayer serviceLayer) {
+    this.service = serviceLayer;
+  }
+
+  public String process(String payload) {
+    RequestMessage req = AutoBeanCodex.decode(FACTORY, RequestMessage.class,
+        payload).as();
+    AutoBean<ResponseMessage> responseBean = FACTORY.response();
+    try {
+      process(req, responseBean.as());
+    } catch (ReportableException e) {
+      e.printStackTrace();
+      // Create a new response envelope, since the state is unknown
+      responseBean = FACTORY.response();
+      responseBean.as().setGeneralFailure(createFailureMessage(e).as());
+    }
+    // Return a JSON-formatted payload
+    return AutoBeanCodex.encode(responseBean).getPayload();
+  }
+
+  public void setExceptionHandler(ExceptionHandler exceptionHandler) {
+    this.exceptionHandler = exceptionHandler;
+  }
+
+  /**
+   * Main processing method.
+   */
+  void process(RequestMessage req, ResponseMessage resp) {
+    final RequestState source = new RequestState();
+    // Apply operations
+    processOperationMessages(source, req);
+
+    // Validate entities
+    List<ViolationMessage> errorMessages = validateEntities(source);
+
+    if (!errorMessages.isEmpty()) {
+      resp.setViolations(errorMessages);
+      return;
+    }
+
+    RequestState returnState = new RequestState(source);
+
+    // Invoke methods
+    List<Splittable> invocationResults = new ArrayList<Splittable>();
+    List<Boolean> invocationSuccess = new ArrayList<Boolean>();
+    List<InvocationMessage> invlist = req.getInvocations();
+    processInvocationMessages(source, invlist, invocationResults,
+        invocationSuccess, returnState);
+
+    // Store return objects
+    List<OperationMessage> operations = new ArrayList<OperationMessage>();
+    IdToEntityMap toProcess = new IdToEntityMap();
+    toProcess.putAll(source.beans);
+    toProcess.putAll(returnState.beans);
+    createReturnOperations(operations, returnState, toProcess);
+
+    resp.setInvocationResults(invocationResults);
+    resp.setStatusCodes(invocationSuccess);
+    if (!operations.isEmpty()) {
+      resp.setOperations(operations);
+    }
+  }
+
+  private AutoBean<ServerFailureMessage> createFailureMessage(
+      ReportableException e) {
+    ServerFailure failure = exceptionHandler.createServerFailure(e.getCause());
+    AutoBean<ServerFailureMessage> bean = FACTORY.failure();
+    ServerFailureMessage msg = bean.as();
+    msg.setExceptionType(failure.getExceptionType());
+    msg.setMessage(failure.getMessage());
+    msg.setStackTrace(failure.getStackTraceString());
+    return bean;
+  }
+
+  private void createReturnOperations(List<OperationMessage> operations,
+      RequestState returnState, IdToEntityMap toProcess) {
+    for (Map.Entry<SimpleEntityProxyId<?>, AutoBean<? extends EntityProxy>> entry : toProcess.entrySet()) {
+      SimpleEntityProxyId<?> id = entry.getKey();
+
+      AutoBean<? extends EntityProxy> bean = entry.getValue();
+      Object domainObject = bean.getTag(DOMAIN_OBJECT);
+      WriteOperation writeOperation;
+
+      if (id.isEphemeral()) {
+        resolveClientEntityProxy(returnState, domainObject,
+            Collections.<String> emptySet(), "");
+        if (id.isEphemeral()) {
+          throw new ReportableException("Could not persist entity "
+              + service.getFlatId(returnState, domainObject.toString()));
+        }
+      }
+
+      if (service.loadDomainObject(returnState,
+          service.getDomainClass(id.getProxyClass()),
+          fromBase64(id.getServerId())) == null) {
+        writeOperation = WriteOperation.DELETE;
+      } else if (id.wasEphemeral()) {
+        writeOperation = WriteOperation.PERSIST;
+      } else {
+        writeOperation = WriteOperation.UPDATE;
+      }
+
+      boolean inResponse = bean.getTag(IN_RESPONSE) != null;
+      int version = domainObject == null ? 0 : service.getVersion(domainObject);
+
+      /*
+       * Don't send any data back to the client for an update on an object that
+       * isn't part of the response payload when the client's version matches
+       * the domain version.
+       */
+      if (writeOperation.equals(WriteOperation.UPDATE) && !inResponse) {
+        if (Integer.valueOf(version).equals(
+            bean.getTag(Constants.ENCODED_VERSION_PROPERTY))) {
+          continue;
+        }
+      }
+
+      OperationMessage op = FACTORY.operation().as();
+      if (writeOperation == WriteOperation.PERSIST) {
+        op.setClientId(id.getClientId());
+      }
+      op.setOperation(writeOperation);
+
+      // Only send properties for entities that are part of the return graph
+      if (inResponse) {
+        Map<String, Splittable> propertyMap = new LinkedHashMap<String, Splittable>();
+        // Add all non-null properties to the serialized form
+        Map<String, Object> diff = AutoBeanUtils.getAllProperties(bean);
+        for (Map.Entry<String, Object> d : diff.entrySet()) {
+          Object value = d.getValue();
+          if (value != null) {
+            propertyMap.put(d.getKey(), EntityCodex.encode(returnState, value));
+          }
+        }
+        op.setPropertyMap(propertyMap);
+      }
+
+      op.setServerId(id.getServerId());
+      op.setTypeToken(service.getTypeToken(id.getProxyClass()));
+      op.setVersion(version);
+
+      operations.add(op);
+    }
+  }
+
+  /**
+   * Handles instance invocations as the instance at the 0th parameter.
+   */
+  private List<Object> decodeInvocationArguments(RequestState source,
+      InvocationMessage invocation, Class<?>[] contextArgs, Type[] genericArgs) {
+    if (invocation.getParameters() == null) {
+      return Collections.emptyList();
+    }
+
+    assert invocation.getParameters().size() == contextArgs.length;
+    List<Object> args = new ArrayList<Object>(contextArgs.length);
+    for (int i = 0, j = contextArgs.length; i < j; i++) {
+      Class<?> type = contextArgs[i];
+      Class<?> elementType = null;
+      Splittable split;
+      if (Collection.class.isAssignableFrom(type)) {
+        elementType = TypeUtils.ensureBaseType(TypeUtils.getSingleParameterization(
+            Collection.class, genericArgs[i]));
+        split = invocation.getParameters().get(i);
+      } else {
+        split = invocation.getParameters().get(i);
+      }
+      Object arg = EntityCodex.decode(source, type, elementType, split);
+      arg = resolveDomainValue(arg, !EntityProxyId.class.equals(contextArgs[i]));
+      args.add(arg);
+    }
+
+    return args;
+  }
+
+  /**
+   * Decode the arguments to pass into the domain method. If the domain method
+   * is not static, the instance object will be in the 0th position.
+   */
+  private List<Object> decodeInvocationArguments(RequestState source,
+      InvocationMessage invocation, Method contextMethod, Method domainMethod) {
+    boolean isStatic = Modifier.isStatic(domainMethod.getModifiers());
+    int baseLength = contextMethod.getParameterTypes().length;
+    int length = baseLength + (isStatic ? 0 : 1);
+    int offset = isStatic ? 0 : 1;
+    Class<?>[] contextArgs = new Class<?>[length];
+    Type[] genericArgs = new Type[length];
+
+    if (!isStatic) {
+      genericArgs[0] = TypeUtils.getSingleParameterization(
+          InstanceRequest.class, contextMethod.getGenericReturnType());
+      contextArgs[0] = TypeUtils.ensureBaseType(genericArgs[0]);
+    }
+    System.arraycopy(contextMethod.getParameterTypes(), 0, contextArgs, offset,
+        baseLength);
+    System.arraycopy(contextMethod.getGenericParameterTypes(), 0, genericArgs,
+        offset, baseLength);
+
+    List<Object> args = decodeInvocationArguments(source, invocation,
+        contextArgs, genericArgs);
+    return args;
+  }
+
+  /**
+   * Expand the property references in an InvocationMessage into a
+   * fully-expanded list of properties. For example, <code>[foo.bar.baz]</code>
+   * will be converted into <code>[foo, foo.bar, foo.bar.baz]</code>.
+   */
+  private Set<String> getPropertyRefs(InvocationMessage invocation) {
+    Set<String> refs = invocation.getPropertyRefs();
+    if (refs == null) {
+      return Collections.emptySet();
+    }
+
+    Set<String> toReturn = new TreeSet<String>();
+    for (String raw : refs) {
+      for (int idx = raw.length(); idx >= 0; idx = raw.lastIndexOf('.', idx - 1)) {
+        toReturn.add(raw.substring(0, idx));
+      }
+    }
+    return toReturn;
+  }
+
+  private void processInvocationMessages(RequestState state,
+      List<InvocationMessage> invlist, List<Splittable> results,
+      List<Boolean> success, RequestState returnState) {
+    for (InvocationMessage invocation : invlist) {
+      try {
+        // Find the Method
+        String[] operation = invocation.getOperation().split("::");
+        Method contextMethod = service.resolveRequestContextMethod(
+            operation[0], operation[1]);
+        Method domainMethod = service.resolveDomainMethod(contextMethod);
+
+        // Invoke it
+        List<Object> args = decodeInvocationArguments(state, invocation,
+            contextMethod, domainMethod);
+        Object returnValue = service.invoke(domainMethod, args.toArray());
+
+        // Convert domain object to client object
+        returnValue = resolveClientValue(returnState, returnValue,
+            getPropertyRefs(invocation), "");
+
+        // Convert the client object to a string
+        results.add(EntityCodex.encode(returnState, returnValue));
+        success.add(true);
+      } catch (ReportableException e) {
+        results.add(AutoBeanCodex.encode(createFailureMessage(e)));
+        success.add(false);
+      }
+    }
+  }
+
+  private void processOperationMessages(final RequestState state,
+      RequestMessage req) {
+    List<OperationMessage> operations = req.getOperations();
+    if (operations == null) {
+      return;
+    }
+
+    for (final OperationMessage operation : operations) {
+      // Unflatten properties
+      String payloadId = operation.getOperation().equals(WriteOperation.PERSIST)
+          ? IdUtil.ephemeralId(operation.getClientId(),
+              operation.getTypeToken()) : IdUtil.persistedId(
+              operation.getServerId(), operation.getTypeToken());
+      AutoBean<? extends EntityProxy> bean = state.getBeanForPayload(payloadId);
+      // Use the version later to know which objects need to be sent back
+      bean.setTag(Constants.ENCODED_ID_PROPERTY, operation.getVersion());
+
+      // Load the domain object with properties, if it exists
+      final Object domain = bean.getTag(DOMAIN_OBJECT);
+      if (domain != null) {
+        // Apply any property updates
+        final Map<String, Splittable> flatValueMap = operation.getPropertyMap();
+        if (flatValueMap != null) {
+          bean.accept(new AutoBeanVisitor() {
+            @Override
+            public boolean visitReferenceProperty(String propertyName,
+                AutoBean<?> value, PropertyContext ctx) {
+              // containsKey to distinguish null from unknown
+              if (flatValueMap.containsKey(propertyName)) {
+                Class<?> elementType = ctx instanceof CollectionPropertyContext
+                    ? ((CollectionPropertyContext) ctx).getElementType() : null;
+                Object newValue = EntityCodex.decode(state, ctx.getType(),
+                    elementType, flatValueMap.get(propertyName));
+                Object resolved = resolveDomainValue(newValue, false);
+                service.setProperty(domain, propertyName,
+                    service.getDomainClass(ctx.getType()), resolved);
+              }
+              return false;
+            }
+
+            @Override
+            public boolean visitValueProperty(String propertyName,
+                Object value, PropertyContext ctx) {
+              if (flatValueMap.containsKey(propertyName)) {
+                Splittable split = flatValueMap.get(propertyName);
+                Object newValue = ValueCodex.decode(ctx.getType(), split);
+                Object resolved = resolveDomainValue(newValue, false);
+                service.setProperty(domain, propertyName, ctx.getType(),
+                    resolved);
+              }
+              return false;
+            }
+          });
+        }
+      }
+    }
+  }
+
+  /**
+   * Converts a domain entity into an EntityProxy that will be sent to the
+   * client.
+   */
+  private EntityProxy resolveClientEntityProxy(final RequestState state,
+      final Object domainEntity, final Set<String> propertyRefs,
+      final String prefix) {
+    if (domainEntity == null) {
+      return null;
+    }
+
+    // Compute data needed to return id to the client
+    String flatId = toBase64(service.getFlatId(state, domainEntity));
+    Class<? extends EntityProxy> proxyType = service.getClientType(
+        domainEntity.getClass()).asSubclass(EntityProxy.class);
+
+    // Retrieve the id, possibly setting its persisted value
+    SimpleEntityProxyId<? extends EntityProxy> id = state.idFactory.getId(
+        proxyType, flatId, state.getClientId(domainEntity));
+
+    AutoBean<? extends EntityProxy> bean = state.getBeanForPayload(id);
+    bean.setTag(IN_RESPONSE, true);
+    bean.accept(new AutoBeanVisitor() {
+      @Override
+      public boolean visitReferenceProperty(String propertyName,
+          AutoBean<?> value, PropertyContext ctx) {
+        // Does the user care about the property?
+        String newPrefix = (prefix.length() > 0 ? (prefix + ".") : "")
+            + propertyName;
+
+        /*
+         * Send if the user cares about the property or if it's a collection of
+         * values.
+         */
+        Class<?> elementType = ctx instanceof CollectionPropertyContext
+            ? ((CollectionPropertyContext) ctx).getElementType() : null;
+        boolean shouldSend = propertyRefs.contains(newPrefix)
+            || elementType != null && !state.isEntityType(elementType);
+
+        if (!shouldSend) {
+          return false;
+        }
+
+        // Call the getter
+        Object domainValue = service.getProperty(domainEntity, propertyName);
+        if (domainValue == null) {
+          return false;
+        }
+
+        // Turn the domain object into something usable on the client side
+        Object resolved = resolveClientValue(state, domainValue, propertyRefs,
+            newPrefix);
+
+        ctx.set(ctx.getType().cast(resolved));
+        return false;
+      }
+
+      @Override
+      public boolean visitValueProperty(String propertyName, Object value,
+          PropertyContext ctx) {
+        // Limit unrequested value properties?
+        value = service.getProperty(domainEntity, propertyName);
+        ctx.set(ctx.getType().cast(value));
+        return false;
+      }
+    });
+    bean.setTag(Constants.ENCODED_VERSION_PROPERTY,
+        service.getVersion(domainEntity));
+    return proxyType.cast(bean.as());
+  }
+
+  /**
+   * Given a method a domain object, return a value that can be encoded by the
+   * client.
+   */
+  private Object resolveClientValue(RequestState source, Object domainValue,
+      Set<String> propertyRefs, String prefix) {
+    if (domainValue == null) {
+      return null;
+    }
+
+    Class<?> returnClass = service.getClientType(domainValue.getClass());
+
+    // Pass simple values through
+    if (ValueCodex.canDecode(returnClass)) {
+      return domainValue;
+    }
+
+    // Convert entities to EntityProxies
+    if (EntityProxy.class.isAssignableFrom(returnClass)) {
+      return resolveClientEntityProxy(source, domainValue, propertyRefs, prefix);
+    }
+
+    // Convert collections
+    if (Collection.class.isAssignableFrom(returnClass)) {
+      Collection<Object> accumulator;
+      if (List.class.isAssignableFrom(returnClass)) {
+        accumulator = new ArrayList<Object>();
+      } else if (Set.class.isAssignableFrom(returnClass)) {
+        accumulator = new HashSet<Object>();
+      } else {
+        throw new ReportableException("Unsupported collection type"
+            + returnClass.getName());
+      }
+
+      for (Object o : (Collection<?>) domainValue) {
+        accumulator.add(resolveClientValue(source, o, propertyRefs, prefix));
+      }
+      return accumulator;
+    }
+
+    throw new ReportableException("Unsupported domain type "
+        + returnClass.getCanonicalName());
+  }
+
+  /**
+   * Convert a client-side value into a domain value.
+   * 
+   * @param the client object to resolve
+   * @param detectDeadEntities if <code>true</code> this method will throw a
+   *          ReportableException containing a {@link DeadEntityException} if an
+   *          EntityProxy cannot be resolved
+   */
+  private Object resolveDomainValue(Object maybeEntityProxy,
+      boolean detectDeadEntities) {
+    if (maybeEntityProxy instanceof EntityProxy) {
+      AutoBean<EntityProxy> bean = AutoBeanUtils.getAutoBean((EntityProxy) maybeEntityProxy);
+      Object domain = bean.getTag(DOMAIN_OBJECT);
+      if (domain == null && detectDeadEntities) {
+        throw new ReportableException(new DeadEntityException(
+            "The requested entity is not available on the server"));
+      }
+      return domain;
+    } else if (maybeEntityProxy instanceof Collection<?>) {
+      Collection<Object> accumulator;
+      if (maybeEntityProxy instanceof List) {
+        accumulator = new ArrayList<Object>();
+      } else if (maybeEntityProxy instanceof Set) {
+        accumulator = new HashSet<Object>();
+      } else {
+        throw new ReportableException("Unsupported collection type "
+            + maybeEntityProxy.getClass().getName());
+      }
+      for (Object o : (Collection<?>) maybeEntityProxy) {
+        accumulator.add(resolveDomainValue(o, detectDeadEntities));
+      }
+      return accumulator;
+    }
+    return maybeEntityProxy;
+  }
+
+  /**
+   * Validate all of the entities referenced in a RequestState.
+   */
+  private List<ViolationMessage> validateEntities(RequestState source) {
+    List<ViolationMessage> errorMessages = new ArrayList<ViolationMessage>();
+    for (Map.Entry<SimpleEntityProxyId<?>, AutoBean<? extends EntityProxy>> entry : source.beans.entrySet()) {
+      Object domainObject = entry.getValue().getTag(DOMAIN_OBJECT);
+
+      // The object could have been deleted
+      if (domainObject != null) {
+        Set<ConstraintViolation<Object>> errors = service.validate(domainObject);
+        if (errors != null && !errors.isEmpty()) {
+          SimpleEntityProxyId<?> id = entry.getKey();
+          for (ConstraintViolation<Object> error : errors) {
+            ViolationMessage message = FACTORY.violation().as();
+            message.setClientId(id.getClientId());
+            message.setMessage(error.getMessage());
+            message.setPath(error.getPropertyPath().toString());
+            message.setServerId(id.getServerId());
+            message.setTypeToken(service.getTypeToken(id.getProxyClass()));
+            errorMessages.add(message);
+          }
+        }
+      }
+    }
+    return errorMessages;
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/Version.java b/user/src/com/google/gwt/requestfactory/server/UnexpectedException.java
similarity index 62%
copy from user/src/com/google/gwt/requestfactory/shared/Version.java
copy to user/src/com/google/gwt/requestfactory/server/UnexpectedException.java
index 5e66314..f6cac79 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Version.java
+++ b/user/src/com/google/gwt/requestfactory/server/UnexpectedException.java
@@ -1,23 +1,30 @@
 /*
  * Copyright 2010 Google Inc.
- *
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- *
+ * 
  * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.shared;
+package com.google.gwt.requestfactory.server;
 
 /**
- * Marks the version property of an entity.
+ * Encapsulates exceptions that indicate something went wrong in RequestFactory
+ * code.
  */
-public @interface Version {
-  // TODO prove the servlet will use this info
+class UnexpectedException extends RuntimeException {
+  public UnexpectedException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+
+  public UnexpectedException(Throwable cause) {
+    super(cause);
+  }
 }
diff --git a/user/src/com/google/gwt/requestfactory/server/UserInformation.java b/user/src/com/google/gwt/requestfactory/server/UserInformation.java
index 27d4c4d..c16554b 100644
--- a/user/src/com/google/gwt/requestfactory/server/UserInformation.java
+++ b/user/src/com/google/gwt/requestfactory/server/UserInformation.java
@@ -17,8 +17,8 @@
 package com.google.gwt.requestfactory.server;
 
 /**
- * A base class for providing authentication related information about the
- * user. Services that want real authentication should subclass this class.
+ * A base class for providing authentication related information about the user.
+ * Services that want real authentication should subclass this class.
  */
 public abstract class UserInformation {
 
@@ -38,9 +38,8 @@
     UserInformation userInfo = null;
     if (!"".equals(userInformationImplClass)) {
       try {
-        userInfo = (UserInformation) Class.forName(
-            userInformationImplClass).getConstructor(
-                String.class).newInstance(redirectUrl);
+        userInfo = (UserInformation) Class.forName(userInformationImplClass).getConstructor(
+            String.class).newInstance(redirectUrl);
       } catch (Exception e) {
         e.printStackTrace();
       }
@@ -52,9 +51,9 @@
   }
 
   /**
-   * Sets the implementation class to be used to gather user information
-   * in {@link #getCurrentUserInformation(String)}.
-   *
+   * Sets the implementation class to be used to gather user information in
+   * {@link #getCurrentUserInformation(String)}.
+   * 
    * @param clazz a class name
    */
   public static void setUserInformationImplClass(String clazz) {
@@ -66,10 +65,10 @@
    */
   protected String redirectUrl = "";
   private Integer version = 0;
-  
+
   /**
    * Constructs a new {@link UserInformation} instance.
-   *
+   * 
    * @param redirectUrl the redirect URL as a String
    */
   public UserInformation(String redirectUrl) {
@@ -80,68 +79,68 @@
 
   /**
    * Returns the user's email address.
-   *
+   * 
    * @return the user's email address as a String
    */
   public abstract String getEmail();
-  
+
   /**
    * Returns the user's id.
-   *
+   * 
    * @return the user's id as a Long
    * @see #setId(Long)
    */
   public abstract Long getId();
-  
+
   /**
    * Returns the user's login URL.
-   *
+   * 
    * @return the user's login URL as a String
    */
   public abstract String getLoginUrl();
-  
+
   /**
    * Returns the user's logout URL.
-   *
+   * 
    * @return the user's logout URL as a String
    */
   public abstract String getLogoutUrl();
-  
+
   /**
    * Returns the user's name.
-   *
+   * 
    * @return the user's name as a String
    */
   public abstract String getName();
 
   /**
    * Returns the version of this instance.
-   *
+   * 
    * @return an Integer version number
    * @see #setVersion(Integer)
    */
   public Integer getVersion() {
     return this.version;
   }
-  
+
   /**
    * Returns whether the user is logged in.
-   *
+   * 
    * @return {@code true} if the user is logged in
    */
   public abstract boolean isUserLoggedIn();
 
   /**
    * Sets the id for this user.
-   *
+   * 
    * @param id a String id
    * @see #getId()
    */
   public abstract void setId(Long id);
-  
+
   /**
    * Sets the version of this instance.
-   *
+   * 
    * @param version an Integer version number
    * @see #getVersion()
    */
diff --git a/user/src/com/google/gwt/requestfactory/server/UserInformationSimpleImpl.java b/user/src/com/google/gwt/requestfactory/server/UserInformationSimpleImpl.java
index 46ef176..c9a66eb 100644
--- a/user/src/com/google/gwt/requestfactory/server/UserInformationSimpleImpl.java
+++ b/user/src/com/google/gwt/requestfactory/server/UserInformationSimpleImpl.java
@@ -1,12 +1,12 @@
 /*
  * 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
@@ -16,8 +16,8 @@
 package com.google.gwt.requestfactory.server;
 
 /**
- * This implementation treats the user as constantly signed in, and
- * without any information.
+ * This implementation treats the user as constantly signed in, and without any
+ * information.
  */
 public class UserInformationSimpleImpl extends UserInformation {
 
@@ -25,7 +25,7 @@
 
   /**
    * Constructs an UserInformationSimpleImpl object.
-   *
+   * 
    * @param redirectUrl the redirect URL as a String
    */
   public UserInformationSimpleImpl(String redirectUrl) {
diff --git a/user/src/com/google/gwt/requestfactory/server/package-info.java b/user/src/com/google/gwt/requestfactory/server/package-info.java
index f1e2481..6d9ddab 100644
--- a/user/src/com/google/gwt/requestfactory/server/package-info.java
+++ b/user/src/com/google/gwt/requestfactory/server/package-info.java
@@ -15,11 +15,15 @@
  */
 
 /**
- * Server side classes for mediating between the client side and the persistent datastore.
- *
- * This package contains classes that can receive client side read and write requests in the JSON format, perform the necessary operations on the persistent datastore, and return the results in JSON format.
- *
+ * Server side classes for mediating between the client side and the persistent
+ * datastore.
+ * 
+ * This package contains classes that can receive client side read and write
+ * requests in the JSON format, perform the necessary operations on the
+ * persistent datastore, and return the results in JSON format.
+ * 
  * @since GWT 2.1
  */
 @com.google.gwt.util.PreventSpuriousRebuilds
 package com.google.gwt.requestfactory.server;
+
diff --git a/user/src/com/google/gwt/requestfactory/server/testing/InProcessRequestContext.java b/user/src/com/google/gwt/requestfactory/server/testing/InProcessRequestContext.java
new file mode 100644
index 0000000..2f02c01
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/server/testing/InProcessRequestContext.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server.testing;
+
+import com.google.gwt.autobean.server.impl.TypeUtils;
+import com.google.gwt.requestfactory.shared.InstanceRequest;
+import com.google.gwt.requestfactory.shared.Request;
+import com.google.gwt.requestfactory.shared.RequestContext;
+import com.google.gwt.requestfactory.shared.impl.AbstractRequest;
+import com.google.gwt.requestfactory.shared.impl.AbstractRequestContext;
+import com.google.gwt.requestfactory.shared.impl.AbstractRequestFactory;
+import com.google.gwt.requestfactory.shared.impl.RequestData;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collection;
+
+/**
+ * An in-process implementation of RequestContext
+ */
+class InProcessRequestContext extends AbstractRequestContext {
+  static final Object[] NO_ARGS = new Object[0];
+
+  class RequestContextHandler implements InvocationHandler {
+    public Object invoke(Object proxy, Method method, Object[] args)
+        throws Throwable {
+      // Maybe delegate to superclass
+      Class<?> owner = method.getDeclaringClass();
+      if (Object.class.equals(owner) || RequestContext.class.equals(owner)
+          || AbstractRequestContext.class.equals(owner)) {
+        try {
+          return method.invoke(InProcessRequestContext.this, args);
+        } catch (InvocationTargetException e) {
+          throw e.getCause();
+        }
+      }
+
+      /*
+       * Instance methods treat the 0-th argument as the instance on which to
+       * invoke the method.
+       */
+      final Object[] actualArgs;
+      Type returnGenericType;
+      boolean isInstance = InstanceRequest.class.isAssignableFrom(method.getReturnType());
+      if (isInstance) {
+        returnGenericType = TypeUtils.getParameterization(
+            InstanceRequest.class, method.getGenericReturnType(),
+            method.getReturnType())[1];
+        if (args == null) {
+          actualArgs = new Object[1];
+        } else {
+          // Save a slot for the this argument
+          actualArgs = new Object[args.length + 1];
+          System.arraycopy(args, 0, actualArgs, 1, args.length);
+        }
+      } else {
+        returnGenericType = TypeUtils.getSingleParameterization(Request.class,
+            method.getGenericReturnType(), method.getReturnType());
+        if (args == null) {
+          actualArgs = NO_ARGS;
+        } else {
+          actualArgs = args;
+        }
+      }
+
+      // Calculate request metadata
+      final String operation = method.getDeclaringClass().getName() + "::"
+          + method.getName();
+      final Class<?> returnType = TypeUtils.ensureBaseType(returnGenericType);
+      final Class<?> elementType = Collection.class.isAssignableFrom(returnType)
+          ? TypeUtils.ensureBaseType(TypeUtils.getSingleParameterization(
+              Collection.class, returnGenericType)) : null;
+
+      // Create the request, just filling in the RequestData details
+      AbstractRequest<Object> req = new AbstractRequest<Object>(
+          InProcessRequestContext.this) {
+        @Override
+        protected RequestData makeRequestData() {
+          return new RequestData(operation, actualArgs, propertyRefs,
+              returnType, elementType);
+        }
+      };
+
+      if (!isInstance) {
+        // Instance invocations are enqueued when using() is called
+        addInvocation(req);
+      }
+      return req;
+    }
+  };
+
+  protected InProcessRequestContext(AbstractRequestFactory factory) {
+    super(factory);
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/server/testing/InProcessRequestFactory.java b/user/src/com/google/gwt/requestfactory/server/testing/InProcessRequestFactory.java
new file mode 100644
index 0000000..e6c412b
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/server/testing/InProcessRequestFactory.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server.testing;
+
+import com.google.gwt.autobean.server.AutoBeanFactoryMagic;
+import com.google.gwt.autobean.shared.AutoBeanFactory;
+import com.google.gwt.autobean.shared.AutoBeanFactory.Category;
+import com.google.gwt.autobean.shared.AutoBeanFactory.NoWrap;
+import com.google.gwt.event.shared.EventBus;
+import com.google.gwt.requestfactory.server.testing.InProcessRequestContext.RequestContextHandler;
+import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.EntityProxyId;
+import com.google.gwt.requestfactory.shared.RequestContext;
+import com.google.gwt.requestfactory.shared.RequestFactory;
+import com.google.gwt.requestfactory.shared.impl.AbstractRequestFactory;
+import com.google.gwt.requestfactory.shared.impl.EntityProxyCategory;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * An JRE-compatible implementation of RequestFactory.
+ */
+class InProcessRequestFactory extends AbstractRequestFactory {
+  @Category(EntityProxyCategory.class)
+  @NoWrap(EntityProxyId.class)
+  interface Factory extends AutoBeanFactory {
+  }
+
+  class RequestFactoryHandler implements InvocationHandler {
+    public Object invoke(Object proxy, Method method, Object[] args)
+        throws Throwable {
+      if (Object.class.equals(method.getDeclaringClass())
+          || RequestFactory.class.equals(method.getDeclaringClass())) {
+        try {
+          return method.invoke(InProcessRequestFactory.this, args);
+        } catch (InvocationTargetException e) {
+          throw e.getCause();
+        }
+      }
+
+      Class<? extends RequestContext> context = method.getReturnType().asSubclass(
+          RequestContext.class);
+      RequestContextHandler handler = new InProcessRequestContext(
+          InProcessRequestFactory.this).new RequestContextHandler();
+      return context.cast(Proxy.newProxyInstance(
+          Thread.currentThread().getContextClassLoader(),
+          new Class<?>[]{context}, handler));
+    }
+  }
+
+  @Override
+  public void initialize(EventBus eventBus) {
+    throw new UnsupportedOperationException(
+        "An explicit RequestTransport must be provided");
+  }
+
+  @Override
+  protected AutoBeanFactory getAutoBeanFactory() {
+    return AutoBeanFactoryMagic.create(Factory.class);
+  }
+
+  @Override
+  @SuppressWarnings("unchecked")
+  protected <P extends EntityProxy> Class<P> getTypeFromToken(String typeToken) {
+    try {
+      Class<? extends EntityProxy> found = Class.forName(typeToken, false,
+          Thread.currentThread().getContextClassLoader()).asSubclass(
+          EntityProxy.class);
+      return (Class<P>) found;
+    } catch (ClassNotFoundException e) {
+      return null;
+    }
+  }
+
+  @Override
+  protected String getTypeToken(Class<?> clazz) {
+    return EntityProxy.class.isAssignableFrom(clazz) ? clazz.getName() : null;
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/server/testing/InProcessRequestTransport.java b/user/src/com/google/gwt/requestfactory/server/testing/InProcessRequestTransport.java
new file mode 100644
index 0000000..fa32efb
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/server/testing/InProcessRequestTransport.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server.testing;
+
+import com.google.gwt.requestfactory.server.SimpleRequestProcessor;
+import com.google.gwt.requestfactory.shared.RequestTransport;
+
+/**
+ * A RequesTransports that calls a {@link SimpleRequestProcessor}. This test can
+ * be used for end-to-end tests of RequestFactory service methods in non-GWT
+ * test suites.
+ */
+public class InProcessRequestTransport implements RequestTransport {
+  private static final boolean DUMP_PAYLOAD = Boolean.getBoolean("gwt.rpc.dumpPayload");
+  private final SimpleRequestProcessor processor;
+
+  public InProcessRequestTransport(SimpleRequestProcessor processor) {
+    this.processor = processor;
+  }
+
+  public void send(String payload, TransportReceiver receiver) {
+    try {
+      if (DUMP_PAYLOAD) {
+        System.out.println(">>> " + payload);
+      }
+      String result = processor.process(payload);
+      if (DUMP_PAYLOAD) {
+        System.out.println("<<< " + result);
+      }
+      receiver.onTransportSuccess(result);
+    } catch (RuntimeException e) {
+      e.printStackTrace();
+      receiver.onTransportFailure(e.getMessage());
+    }
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/server/testing/RequestFactoryMagic.java b/user/src/com/google/gwt/requestfactory/server/testing/RequestFactoryMagic.java
new file mode 100644
index 0000000..0b84c27
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/server/testing/RequestFactoryMagic.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server.testing;
+
+import com.google.gwt.requestfactory.server.testing.InProcessRequestFactory.RequestFactoryHandler;
+import com.google.gwt.requestfactory.shared.RequestFactory;
+
+import java.lang.reflect.Proxy;
+
+/**
+ * Create JRE-compatible instances of a RequestFactory interface.
+ */
+public class RequestFactoryMagic {
+  /**
+   * Create an instance of a RequestFactory. The returned RequestFactory must be
+   * initialized with an explicit
+   * {@link com.google.gwt.requestfactory.shared.RequestTransport
+   * RequestTransport} via the
+   * {@link RequestFactory#initialize(com.google.gwt.event.shared.EventBus, com.google.gwt.requestfactory.shared.RequestTransport)
+   * initialize(EventBus, RequestTransport} method.
+   * 
+   * @param <T> the RequestFactory type
+   * @param requestFactory the RequestFactory type
+   * @param processor
+   * @return an instance of the RequestFactory type
+   * @see InProcessRequestTransport
+   */
+  public static <T extends RequestFactory> T create(Class<T> requestFactory) {
+    RequestFactoryHandler handler = new InProcessRequestFactory().new RequestFactoryHandler();
+    return requestFactory.cast(Proxy.newProxyInstance(
+        Thread.currentThread().getContextClassLoader(),
+        new Class<?>[]{requestFactory}, handler));
+  }
+
+  private RequestFactoryMagic() {
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/Version.java b/user/src/com/google/gwt/requestfactory/server/testing/package-info.java
similarity index 75%
rename from user/src/com/google/gwt/requestfactory/shared/Version.java
rename to user/src/com/google/gwt/requestfactory/server/testing/package-info.java
index 5e66314..23f9f88 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Version.java
+++ b/user/src/com/google/gwt/requestfactory/server/testing/package-info.java
@@ -1,23 +1,23 @@
 /*
  * Copyright 2010 Google Inc.
- *
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- *
+ * 
  * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.shared;
 
 /**
- * Marks the version property of an entity.
+ * Classes used for testing the request factory service.
+ *
+ * @since GWT 2.1.1
  */
-public @interface Version {
-  // TODO prove the servlet will use this info
-}
+@com.google.gwt.util.PreventSpuriousRebuilds
+package com.google.gwt.requestfactory.server.testing;
diff --git a/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java b/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java
index a4ca1ce..1e5cecb 100644
--- a/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java
+++ b/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java
@@ -30,7 +30,7 @@
    * Subtypes should override to declare they return a stable id of their own
    * type, to allow type safe use of the request objects returned by
    * {@link RequestFactory#find(EntityProxyId)}.
-   *
+   * 
    * @return an {@link EntityProxyId} instance
    */
   EntityProxyId<?> stableId();
diff --git a/user/src/com/google/gwt/requestfactory/shared/EntityProxyId.java b/user/src/com/google/gwt/requestfactory/shared/EntityProxyId.java
index af81fa7..a64e390 100644
--- a/user/src/com/google/gwt/requestfactory/shared/EntityProxyId.java
+++ b/user/src/com/google/gwt/requestfactory/shared/EntityProxyId.java
@@ -21,14 +21,15 @@
  * <p>
  * In particular, an {@link EntityProxy} foo that is yet to be persisted and a
  * copy of foo after being persisted have equal {@link EntityProxyId}.
- *
+ * 
  * @param <P> the entity type
  */
+@ProxyFor(Object.class)
 public interface EntityProxyId<P extends EntityProxy> {
 
   /**
    * Returns the class of the proxy identified.
-   *
+   * 
    * @return a Class object of type P
    */
   Class<P> getProxyClass();
diff --git a/user/src/com/google/gwt/requestfactory/shared/Id.java b/user/src/com/google/gwt/requestfactory/shared/Id.java
deleted file mode 100644
index 6340eff..0000000
--- a/user/src/com/google/gwt/requestfactory/shared/Id.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.shared;
-
-/**
- * Marks the id property of an entity.
- */
-public @interface Id {
-  // TODO prove the servlet will use this info
-}
diff --git a/user/src/com/google/gwt/requestfactory/shared/RequestFactory.java b/user/src/com/google/gwt/requestfactory/shared/RequestFactory.java
index e06ace1..48d1233 100644
--- a/user/src/com/google/gwt/requestfactory/shared/RequestFactory.java
+++ b/user/src/com/google/gwt/requestfactory/shared/RequestFactory.java
@@ -22,13 +22,13 @@
  * <p>
  * <b>Limitations on the transferrability of types.</b> <br>
  * RequestFactory currently supports the transfer of basic value types, entity
- * types, and collections, with limitations. The basic value types supported
- * are {@link String}, {@link Enum}, {@link Boolean}, {@link Character},
- * subtypes of {@link Number}, and {@link java.util.Date}. Any value type not
- * included in this list may not be declared in the type signature of a service
- * method, or {@link EntityProxy}. {@link java.util.Collection} types supported
- * are {@link java.util.List} and {@link java.util.Set} with the restriction
- * that a collection must be homogeneous and only hold one type of value.
+ * types, and collections, with limitations. The basic value types supported are
+ * {@link String}, {@link Enum}, {@link Boolean}, {@link Character}, subtypes of
+ * {@link Number}, and {@link java.util.Date}. Any value type not included in
+ * this list may not be declared in the type signature of a service method, or
+ * {@link EntityProxy}. {@link java.util.Collection} types supported are
+ * {@link java.util.List} and {@link java.util.Set} with the restriction that a
+ * collection must be homogeneous and only hold one type of value.
  * </p>
  * <p>
  * Polymorphism is not supported at this time. RequestFactory encoding and
@@ -48,16 +48,16 @@
 
   /**
    * Return a request to find a fresh instance of the referenced proxy.
-   *
+   * 
    * @param proxyId an {@link EntityProxyId} instance of type P
    * @return a {@link Request} object
    */
   <P extends EntityProxy> Request<P> find(EntityProxyId<P> proxyId);
 
   /**
-   * Returns the event bus this factory's events are posted on, which was set via
-   * {@link #initialize}.
-   *
+   * Returns the event bus this factory's events are posted on, which was set
+   * via {@link #initialize}.
+   * 
    * @return the {@link EventBus} associated with this instance
    */
   EventBus getEventBus();
@@ -96,7 +96,7 @@
    * type of this token, via {@link RequestContext#create}. The token may
    * represent either a proxy instance (see {@link #getHistoryToken}) or a proxy
    * class (see {@link #getProxyClass}).
-   *
+   * 
    * @param historyToken a String token
    * @return a Class object for an {@link EntityProxy} subclass
    */
@@ -105,7 +105,7 @@
   /**
    * Return the appropriate {@link EntityProxyId} using a string returned from
    * {@link #getHistoryToken(EntityProxyId)}.
-   *
+   * 
    * @param historyToken a String token
    * @return an {@link EntityProxyId}
    */
@@ -114,14 +114,14 @@
   /**
    * Start this request factory with a
    * {@link com.google.gwt.requestfactory.client.DefaultRequestTransport}.
-   *
+   * 
    * @param eventBus an {@link EventBus}
    */
   void initialize(EventBus eventBus);
 
   /**
    * Start this request factory with a user-provided transport.
-   *
+   * 
    * @param eventBus an {@link EventBus}
    * @param transport a {@link RequestTransport} instance
    */
diff --git a/user/src/com/google/gwt/requestfactory/shared/Violation.java b/user/src/com/google/gwt/requestfactory/shared/Violation.java
index c4ddb96..3698740 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Violation.java
+++ b/user/src/com/google/gwt/requestfactory/shared/Violation.java
@@ -22,21 +22,21 @@
 public interface Violation {
   /**
    * Returns the message associated with this {@link Violation}.
-   *
+   * 
    * @return a String message
    */
   String getMessage();
 
   /**
    * Returns the path associated with this {@link Violation}.
-   *
+   * 
    * @return a String path
    */
   String getPath();
 
   /**
    * Returns the proxy id associated with this {@link Violation}.
-   *
+   * 
    * @return an {@link EntityProxyId} instance
    */
   EntityProxyId<?> getProxyId();
diff --git a/user/src/com/google/gwt/requestfactory/shared/WriteOperation.java b/user/src/com/google/gwt/requestfactory/shared/WriteOperation.java
index b1fa575..89b5d9c 100644
--- a/user/src/com/google/gwt/requestfactory/shared/WriteOperation.java
+++ b/user/src/com/google/gwt/requestfactory/shared/WriteOperation.java
@@ -1,12 +1,12 @@
 /*
  * 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
@@ -21,29 +21,26 @@
  * <li>A PERSIST event is fired after a proxy that was created on the client has
  * been persisted on the server.
  * <li>An UPDATE event is fired whenever a client encounters a proxy for the
- * first time, or encounters a proxy with new fields, or encounters a proxy
- * whose fields have been updated.
+ * first time, or encounters a proxy whose version number has changed.
  * <li>A DELETE event is fired after a proxy that was deleted on the client is
  * deleted on the server as well.
  * </ul>
  */
 public enum WriteOperation {
-  PERSIST("PERSIST"), 
-  UPDATE("UPDATE"), 
-  DELETE("DELETE");
-  
-  // use an unObfuscatedEnumName field to bypass the implicit name() method, 
+  PERSIST("PERSIST"), UPDATE("UPDATE"), DELETE("DELETE");
+
+  // use an unObfuscatedEnumName field to bypass the implicit name() method,
   // to be safe in the case enum name obfuscation is enabled.
   private final String unObfuscatedEnumName;
-  
+
   private WriteOperation(String unObfuscatedEnumName) {
     this.unObfuscatedEnumName = unObfuscatedEnumName;
   }
-  
+
   /**
    * Returns the unobfuscated name of the event associated with this
    * {@link WriteOperation}.
-   *
+   * 
    * @return one of "PERSIST", "UPDATE", or "DELETE"
    */
   public String getUnObfuscatedEnumName() {
diff --git a/user/src/com/google/gwt/requestfactory/shared/impl/AbstractRequest.java b/user/src/com/google/gwt/requestfactory/shared/impl/AbstractRequest.java
new file mode 100644
index 0000000..f8b7ff1
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/AbstractRequest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.impl;
+
+import com.google.gwt.autobean.shared.Splittable;
+import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.InstanceRequest;
+import com.google.gwt.requestfactory.shared.Receiver;
+import com.google.gwt.requestfactory.shared.Request;
+import com.google.gwt.requestfactory.shared.RequestContext;
+import com.google.gwt.requestfactory.shared.ServerFailure;
+import com.google.gwt.requestfactory.shared.Violation;
+import com.google.gwt.requestfactory.shared.messages.EntityCodex;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Abstract implementation of {@link Request}. Each request stores a
+ * {@link DeltaValueStoreJsonImpl}.
+ * 
+ * @param <T> return type
+ */
+public abstract class AbstractRequest<T> implements Request<T>,
+    InstanceRequest<EntityProxy, T> {
+
+  /**
+   * Used by generated subtypes.
+   */
+  protected final Set<String> propertyRefs = new HashSet<String>();
+  protected final AbstractRequestContext requestContext;
+  private Receiver<? super T> receiver;
+  private RequestData requestData;
+
+  protected AbstractRequest(AbstractRequestContext requestContext) {
+    this.requestContext = requestContext;
+  }
+
+  public void fire() {
+    requestContext.fire();
+  }
+
+  public void fire(Receiver<? super T> receiver) {
+    to(receiver);
+    fire();
+  }
+
+  /**
+   * Returns the properties.
+   */
+  public Set<String> getPropertyRefs() {
+    return Collections.unmodifiableSet(propertyRefs);
+  }
+
+  public RequestData getRequestData() {
+    if (requestData == null) {
+      requestData = makeRequestData();
+    }
+    return requestData;
+  }
+
+  public RequestContext to(Receiver<? super T> receiver) {
+    this.receiver = receiver;
+    return requestContext;
+  }
+
+  /**
+   * This method comes from the {@link InstanceRequest} interface. Instance
+   * methods place the instance in the first parameter slot.
+   */
+  public Request<T> using(EntityProxy instanceObject) {
+    getRequestData().getParameters()[0] = instanceObject;
+    /*
+     * Instance methods enqueue themselves when their using() method is called.
+     * This ensures that the instance parameter will have been set when
+     * AbstractRequestContext.retainArg() is called.
+     */
+    requestContext.addInvocation(this);
+    return this;
+  }
+
+  public Request<T> with(String... propertyRefs) {
+    this.propertyRefs.addAll(Arrays.asList(propertyRefs));
+    return this;
+  }
+
+  protected abstract RequestData makeRequestData();
+
+  boolean hasReceiver() {
+    return receiver != null;
+  }
+
+  void onFail(ServerFailure failure) {
+    if (receiver != null) {
+      receiver.onFailure(failure);
+    }
+  }
+
+  void onSuccess(Splittable split) {
+    // The user may not have called to()
+    if (receiver != null) {
+      @SuppressWarnings("unchecked")
+      T result = (T) EntityCodex.decode(requestContext,
+          requestData.getReturnType(), requestData.getElementType(), split);
+      receiver.onSuccess(result);
+    }
+  }
+
+  void onViolation(Set<Violation> errors) {
+    // The user may not have called to()
+    if (receiver != null) {
+      receiver.onViolation(errors);
+    }
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/impl/AbstractRequestContext.java b/user/src/com/google/gwt/requestfactory/shared/impl/AbstractRequestContext.java
new file mode 100644
index 0000000..680286b
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/AbstractRequestContext.java
@@ -0,0 +1,652 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.impl;
+
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanCodex;
+import com.google.gwt.autobean.shared.AutoBeanUtils;
+import com.google.gwt.autobean.shared.AutoBeanVisitor;
+import com.google.gwt.autobean.shared.Splittable;
+import com.google.gwt.autobean.shared.ValueCodex;
+import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.EntityProxyChange;
+import com.google.gwt.requestfactory.shared.EntityProxyId;
+import com.google.gwt.requestfactory.shared.Receiver;
+import com.google.gwt.requestfactory.shared.RequestContext;
+import com.google.gwt.requestfactory.shared.RequestTransport.TransportReceiver;
+import com.google.gwt.requestfactory.shared.ServerFailure;
+import com.google.gwt.requestfactory.shared.Violation;
+import com.google.gwt.requestfactory.shared.WriteOperation;
+import com.google.gwt.requestfactory.shared.messages.EntityCodex;
+import com.google.gwt.requestfactory.shared.messages.IdMessage;
+import com.google.gwt.requestfactory.shared.messages.InvocationMessage;
+import com.google.gwt.requestfactory.shared.messages.MessageFactory;
+import com.google.gwt.requestfactory.shared.messages.OperationMessage;
+import com.google.gwt.requestfactory.shared.messages.RequestMessage;
+import com.google.gwt.requestfactory.shared.messages.ResponseMessage;
+import com.google.gwt.requestfactory.shared.messages.ServerFailureMessage;
+import com.google.gwt.requestfactory.shared.messages.ViolationMessage;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Base implementations for RequestContext services.
+ */
+public class AbstractRequestContext implements RequestContext,
+    EntityCodex.EntitySource {
+  private class MyViolation implements Violation {
+
+    private final EntityProxyId<?> id;
+    private final String path;
+    private final String message;
+
+    public MyViolation(ViolationMessage message) {
+      id = getId(message);
+      path = message.getPath();
+      this.message = message.getMessage();
+    }
+
+    public String getMessage() {
+      return message;
+    }
+
+    public String getPath() {
+      return path;
+    }
+
+    public EntityProxyId<?> getProxyId() {
+      return id;
+    }
+  }
+
+  private static final String PARENT_OBJECT = "parentObject";
+
+  private final List<AbstractRequest<?>> invocations = new ArrayList<AbstractRequest<?>>();
+  private boolean locked;
+  private final AbstractRequestFactory requestFactory;
+  /**
+   * A map of all EntityProxies that the RequestContext has interacted with.
+   * Objects are placed into this map by being passed into {@link #edit} or as
+   * an invocation argument.
+   */
+  private final Map<SimpleEntityProxyId<?>, AutoBean<?>> editedProxies = new LinkedHashMap<SimpleEntityProxyId<?>, AutoBean<?>>();
+  /**
+   * A map that contains the canonical instance of an entity to return in the
+   * return graph, since this is built from scratch.
+   */
+  private final Map<SimpleEntityProxyId<?>, AutoBean<?>> returnedProxies = new HashMap<SimpleEntityProxyId<?>, AutoBean<?>>();
+
+  protected AbstractRequestContext(AbstractRequestFactory factory) {
+    this.requestFactory = factory;
+  }
+
+  /**
+   * Create a new object, with an ephemeral id.
+   */
+  public <T extends EntityProxy> T create(Class<T> clazz) {
+    checkLocked();
+
+    AutoBean<T> created = requestFactory.createEntityProxy(clazz,
+        requestFactory.allocateId(clazz));
+    return takeOwnership(created);
+  }
+
+  public <T extends EntityProxy> T edit(T object) {
+    AutoBean<T> bean = checkStreamsNotCrossed(object);
+
+    checkLocked();
+
+    @SuppressWarnings("unchecked")
+    AutoBean<T> previouslySeen = (AutoBean<T>) editedProxies.get(object.stableId());
+    if (previouslySeen != null && !previouslySeen.isFrozen()) {
+      /*
+       * If we've seen the object before, it might be because it was passed in
+       * as a method argument. This does not guarantee its mutability, so check
+       * that here before returning the cached object.
+       */
+      return previouslySeen.as();
+    }
+
+    // Create editable copies
+    AutoBean<T> parent = bean;
+    bean = cloneBeanAndCollections(bean);
+    bean.setTag(PARENT_OBJECT, parent);
+    return takeOwnership(bean);
+  }
+
+  /**
+   * Make sure there's a default receiver so errors don't get dropped. This
+   * behavior should be revisited when chaining is supported, depending on
+   * whether or not chained invocations can fail independently.
+   */
+  public void fire() {
+    boolean needsReceiver = true;
+    for (AbstractRequest<?> request : invocations) {
+      if (request.hasReceiver()) {
+        needsReceiver = false;
+        break;
+      }
+    }
+
+    if (needsReceiver) {
+      doFire(new Receiver<Void>() {
+        @Override
+        public void onSuccess(Void response) {
+          // Don't care
+        }
+      });
+    } else {
+      doFire(null);
+    }
+  }
+
+  public void fire(final Receiver<Void> receiver) {
+    if (receiver == null) {
+      throw new IllegalArgumentException();
+    }
+    doFire(receiver);
+  }
+
+  /**
+   * EntityCodex support.
+   */
+  public <Q extends EntityProxy> AutoBean<Q> getBeanForPayload(
+      String serializedProxyId) {
+    SimpleEntityProxyId<Q> id = requestFactory.getProxyId(serializedProxyId);
+    return getProxyForReturnPayloadGraph(id);
+  }
+
+  public AbstractRequestFactory getRequestFactory() {
+    return requestFactory;
+  }
+
+  /**
+   * EntityCodex support.
+   */
+  public String getSerializedProxyId(EntityProxyId<?> stableId) {
+    return requestFactory.getHistoryToken(stableId);
+  }
+
+  public boolean isChanged() {
+    /*
+     * NB: Don't use the presence of ephemeral objects for this test.
+     * 
+     * Diff the objects until one is found to be different. It's not just a
+     * simple flag-check because of the possibility of "unmaking" a change, per
+     * the JavaDoc.
+     */
+    for (AutoBean<?> bean : editedProxies.values()) {
+      AutoBean<?> previous = bean.getTag(PARENT_OBJECT);
+      if (previous == null) {
+        // Compare to empty object
+        Class<?> proxyClass = ((EntityProxy) bean.as()).stableId().getProxyClass();
+        previous = getRequestFactory().getAutoBeanFactory().create(proxyClass);
+      }
+      if (!AutoBeanUtils.diff(previous, bean).isEmpty()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * EntityCodex support.
+   */
+  public boolean isEntityType(Class<?> clazz) {
+    return requestFactory.getTypeToken(clazz) != null;
+  }
+
+  public boolean isLocked() {
+    return locked;
+  }
+
+  /**
+   * Called by generated subclasses to enqueue a method invocation.
+   */
+  protected void addInvocation(AbstractRequest<?> request) {
+    invocations.add(request);
+    for (Object arg : request.getRequestData().getParameters()) {
+      retainArg(arg);
+    }
+  }
+
+  private void checkLocked() {
+    if (locked) {
+      throw new IllegalStateException("A request is already in progress");
+    }
+  }
+
+  /**
+   * This method checks that a proxy object is either immutable, or already
+   * edited by this context.
+   */
+  private <T> AutoBean<T> checkStreamsNotCrossed(T object) {
+    AutoBean<T> bean = AutoBeanUtils.getAutoBean(object);
+    if (bean == null) {
+      // Unexpected; some kind of foreign implementation?
+      throw new IllegalArgumentException(object.getClass().getName());
+    }
+
+    RequestContext context = bean.getTag(EntityProxyCategory.REQUEST_CONTEXT);
+    if (!bean.isFrozen() && context != this) {
+      /*
+       * This means something is way off in the weeds. If a bean is editable,
+       * it's supposed to be associated with a RequestContext.
+       */
+      assert context != null : "Unfrozen bean with null RequestContext";
+
+      /*
+       * Already editing the object in another context or it would have been in
+       * the editing map.
+       */
+      throw new IllegalArgumentException("Attempting to edit an EntityProxy"
+          + " previously edited by another RequestContext");
+    }
+    return bean;
+  }
+
+  /**
+   * Shallow-clones an autobean and makes duplicates of the collection types. A
+   * regular {@link AutoBean#clone} won't duplicate reference properties.
+   */
+  private <T> AutoBean<T> cloneBeanAndCollections(AutoBean<T> toClone) {
+    AutoBean<T> clone = toClone.clone(false);
+    clone.accept(new AutoBeanVisitor() {
+      @Override
+      public boolean visitReferenceProperty(String propertyName,
+          AutoBean<?> value, PropertyContext ctx) {
+        if (value != null) {
+          if (List.class == ctx.getType()) {
+            ctx.set(new ArrayList<Object>((List<?>) value.as()));
+          } else if (Set.class == ctx.getType()) {
+            ctx.set(new HashSet<Object>((Set<?>) value.as()));
+          }
+        }
+        return false;
+      }
+    });
+    return clone;
+  }
+
+  private void doFire(final Receiver<Void> receiver) {
+    checkLocked();
+    locked = true;
+
+    freezeEntities(true);
+
+    String payload = makePayload();
+    requestFactory.getRequestTransport().send(payload, new TransportReceiver() {
+      public void onTransportFailure(String message) {
+        ServerFailure failure = new ServerFailure(message, null, null);
+        reuse();
+        for (AbstractRequest<?> request : new ArrayList<AbstractRequest<?>>(
+            invocations)) {
+          request.onFail(failure);
+        }
+        if (receiver != null) {
+          receiver.onFailure(failure);
+        }
+      }
+
+      public void onTransportSuccess(String payload) {
+        ResponseMessage response = AutoBeanCodex.decode(
+            MessageFactoryHolder.FACTORY, ResponseMessage.class, payload).as();
+        if (response.getGeneralFailure() != null) {
+          ServerFailureMessage failure = response.getGeneralFailure();
+          ServerFailure fail = new ServerFailure(failure.getMessage(),
+              failure.getExceptionType(), failure.getStackTrace());
+
+          reuse();
+          for (AbstractRequest<?> invocation : new ArrayList<AbstractRequest<?>>(
+              invocations)) {
+            invocation.onFail(fail);
+          }
+          if (receiver != null) {
+            receiver.onFailure(fail);
+          }
+          return;
+        }
+
+        // Process violations and then stop
+        if (response.getViolations() != null) {
+          Set<Violation> errors = new HashSet<Violation>();
+          for (ViolationMessage message : response.getViolations()) {
+            errors.add(new MyViolation(message));
+          }
+
+          reuse();
+          for (AbstractRequest<?> request : new ArrayList<AbstractRequest<?>>(
+              invocations)) {
+            request.onViolation(errors);
+          }
+          if (receiver != null) {
+            receiver.onViolation(errors);
+          }
+          return;
+        }
+
+        // Process operations
+        processReturnOperations(response);
+
+        // Send return values
+        for (int i = 0, j = invocations.size(); i < j; i++) {
+          if (response.getStatusCodes().get(i)) {
+            invocations.get(i).onSuccess(response.getInvocationResults().get(i));
+          } else {
+            ServerFailureMessage failure = AutoBeanCodex.decode(
+                MessageFactoryHolder.FACTORY, ServerFailureMessage.class,
+                response.getInvocationResults().get(i)).as();
+            invocations.get(i).onFail(
+                new ServerFailure(failure.getMessage(),
+                    failure.getExceptionType(), failure.getStackTrace()));
+          }
+        }
+
+        if (receiver != null) {
+          receiver.onSuccess(null);
+        }
+        // After success, shut down the context
+        editedProxies.clear();
+        invocations.clear();
+        returnedProxies.clear();
+      }
+    });
+  }
+
+  /**
+   * Set the frozen status of all EntityProxies owned by this context.
+   */
+  private void freezeEntities(boolean frozen) {
+    for (AutoBean<?> bean : editedProxies.values()) {
+      bean.setFrozen(frozen);
+    }
+  }
+
+  /**
+   * Resolves an IdMessage into an EntityProxyId.
+   */
+  private SimpleEntityProxyId<EntityProxy> getId(IdMessage op) {
+    SimpleEntityProxyId<EntityProxy> id;
+    if (op.getClientId() > 0) {
+      id = requestFactory.getId(op.getTypeToken(), op.getServerId(),
+          op.getClientId());
+    } else {
+      id = requestFactory.getId(op.getTypeToken(), op.getServerId());
+    }
+    return id;
+  }
+
+  /**
+   * Creates or retrieves a new canonical AutoBean to represent the given id in
+   * the returned payload.
+   */
+  private <Q extends EntityProxy> AutoBean<Q> getProxyForReturnPayloadGraph(
+      SimpleEntityProxyId<Q> id) {
+    assert !id.isEphemeral();
+
+    @SuppressWarnings("unchecked")
+    AutoBean<Q> bean = (AutoBean<Q>) returnedProxies.get(id);
+    if (bean == null) {
+      Class<Q> proxyClass = id.getProxyClass();
+      bean = requestFactory.createEntityProxy(proxyClass, id);
+      returnedProxies.put(id, bean);
+    }
+
+    return bean;
+  }
+
+  /**
+   * Make an EntityProxy immutable.
+   */
+  private void makeImmutable(final AutoBean<? extends EntityProxy> toMutate) {
+    // Always diff'ed against itself, producing a no-op
+    toMutate.setTag(PARENT_OBJECT, toMutate);
+    // Act with entity-identity semantics
+    toMutate.setTag(EntityProxyCategory.REQUEST_CONTEXT, null);
+    toMutate.setFrozen(true);
+  }
+
+  /**
+   * Assemble all of the state that has been accumulated in this context. This
+   * includes:
+   * <ul>
+   * <li>Diffs accumulated on objects passed to {@link #edit}.
+   * <li>Invocations accumulated as Request subtypes passed to
+   * {@link #addInvocation}.
+   * </ul>
+   */
+  private String makePayload() {
+    // Get the factory from the runtime-specific holder.
+    MessageFactory f = MessageFactoryHolder.FACTORY;
+
+    List<OperationMessage> operations = new ArrayList<OperationMessage>();
+    // Compute deltas for each entity seen by the context
+    for (AutoBean<?> currentView : editedProxies.values()) {
+      @SuppressWarnings("unchecked")
+      SimpleEntityProxyId<EntityProxy> stableId = EntityProxyCategory.stableId((AutoBean<EntityProxy>) currentView);
+
+      // The OperationMessages describes operations on exactly one entity
+      OperationMessage operation = f.operation().as();
+      operation.setTypeToken(requestFactory.getTypeToken(stableId.getProxyClass()));
+
+      // Find the object to compare against
+      AutoBean<?> parent = currentView.getTag(PARENT_OBJECT);
+      if (parent == null) {
+        // Newly-created object, use a blank object to compare against
+        parent = requestFactory.createEntityProxy(stableId.getProxyClass(),
+            stableId);
+
+        // Newly-created objects go into the persist operation bucket
+        operation.setOperation(WriteOperation.PERSIST);
+        // The ephemeral id is passed to the server
+        operation.setClientId(stableId.getClientId());
+      } else {
+        // Requests involving existing objects use the persisted id
+        operation.setServerId(stableId.getServerId());
+        operation.setOperation(WriteOperation.UPDATE);
+      }
+
+      // Send our version number to the server to cut down on payload size
+      Integer version = currentView.getTag(Constants.ENCODED_VERSION_PROPERTY);
+      if (version != null) {
+        operation.setVersion(version);
+      }
+
+      // Compute what's changed on the client
+      Map<String, Object> diff = AutoBeanUtils.diff(parent, currentView);
+      if (!diff.isEmpty()) {
+        Map<String, Splittable> propertyMap = new HashMap<String, Splittable>();
+        for (Map.Entry<String, Object> entry : diff.entrySet()) {
+          propertyMap.put(entry.getKey(),
+              EntityCodex.encode(this, entry.getValue()));
+        }
+        operation.setPropertyMap(propertyMap);
+      }
+      operations.add(operation);
+    }
+
+    List<InvocationMessage> invocationMessages = new ArrayList<InvocationMessage>();
+    for (AbstractRequest<?> invocation : invocations) {
+      RequestData data = invocation.getRequestData();
+      InvocationMessage message = f.invocation().as();
+
+      String opsToSend = data.getOperation();
+      if (!opsToSend.isEmpty()) {
+        message.setOperation(opsToSend);
+      }
+
+      Set<String> refsToSend = data.getPropertyRefs();
+      if (!refsToSend.isEmpty()) {
+        message.setPropertyRefs(refsToSend);
+      }
+
+      List<Splittable> parameters = new ArrayList<Splittable>(
+          data.getParameters().length);
+      for (Object param : data.getParameters()) {
+        parameters.add(EntityCodex.encode(this, param));
+      }
+      if (!parameters.isEmpty()) {
+        message.setParameters(parameters);
+      }
+
+      invocationMessages.add(message);
+    }
+
+    // Create the outer envelope message
+    AutoBean<RequestMessage> bean = f.request();
+    RequestMessage requestMessage = bean.as();
+    if (!invocationMessages.isEmpty()) {
+      requestMessage.setInvocations(invocationMessages);
+    }
+    if (!operations.isEmpty()) {
+      requestMessage.setOperations(operations);
+    }
+    return AutoBeanCodex.encode(bean).getPayload();
+  }
+
+  /**
+   * Create a new EntityProxy from a snapshot in the return payload.
+   * 
+   * @param id the EntityProxyId of the object
+   * @param returnRecord the JSON map containing property/value pairs
+   * @param operations the WriteOperation eventns to broadcast over the EventBus
+   */
+  private <Q extends EntityProxy> Q processReturnOperation(
+      SimpleEntityProxyId<Q> id, OperationMessage op,
+      WriteOperation... operations) {
+
+    AutoBean<Q> toMutate = getProxyForReturnPayloadGraph(id);
+    toMutate.setTag(Constants.ENCODED_VERSION_PROPERTY, op.getVersion());
+
+    final Map<String, Splittable> properties = op.getPropertyMap();
+    if (properties != null) {
+      // Apply updates
+      toMutate.accept(new AutoBeanVisitor() {
+        @Override
+        public boolean visitReferenceProperty(String propertyName,
+            AutoBean<?> value, PropertyContext ctx) {
+          if (ctx.canSet()) {
+            if (properties.containsKey(propertyName)) {
+              Splittable raw = properties.get(propertyName);
+              Class<?> elementType = ctx instanceof CollectionPropertyContext
+                  ? ((CollectionPropertyContext) ctx).getElementType() : null;
+              Object decoded = EntityCodex.decode(AbstractRequestContext.this,
+                  ctx.getType(), elementType, raw);
+              ctx.set(decoded);
+            }
+          }
+          return false;
+        }
+
+        @Override
+        public boolean visitValueProperty(String propertyName, Object value,
+            PropertyContext ctx) {
+          if (ctx.canSet()) {
+            if (properties.containsKey(propertyName)) {
+              Splittable raw = properties.get(propertyName);
+              Object decoded = ValueCodex.decode(ctx.getType(), raw);
+              ctx.set(decoded);
+            }
+          }
+          return false;
+        }
+      });
+    }
+
+    // Finished applying updates, freeze the bean
+    makeImmutable(toMutate);
+    Q proxy = toMutate.as();
+
+    /*
+     * Notify subscribers if the object differs from when it first came into the
+     * RequestContext.
+     */
+    if (operations != null) {
+      for (WriteOperation writeOperation : operations) {
+        if (writeOperation.equals(WriteOperation.UPDATE)
+            && !requestFactory.hasVersionChanged(id, op.getVersion())) {
+          // No updates if the server reports no change
+          continue;
+        }
+        requestFactory.getEventBus().fireEventFromSource(
+            new EntityProxyChange<EntityProxy>(proxy, writeOperation),
+            id.getProxyClass());
+      }
+    }
+    return proxy;
+  }
+
+  /**
+   * Process an array of OperationMessages.
+   */
+  private void processReturnOperations(ResponseMessage response) {
+    List<OperationMessage> records = response.getOperations();
+
+    // If there are no observable effects, this will be null
+    if (records == null) {
+      return;
+    }
+
+    for (OperationMessage op : records) {
+      SimpleEntityProxyId<EntityProxy> id = getId(op);
+      if (id.wasEphemeral()) {
+        processReturnOperation(id, op, WriteOperation.PERSIST,
+            WriteOperation.UPDATE);
+      } else {
+        processReturnOperation(id, op, WriteOperation.UPDATE);
+      }
+    }
+  }
+
+  /**
+   * Ensures that any method arguments are retained in the context's sphere of
+   * influence.
+   */
+  private void retainArg(Object arg) {
+    if (arg instanceof Iterable<?>) {
+      for (Object o : (Iterable<?>) arg) {
+        retainArg(o);
+      }
+    } else if (arg instanceof EntityProxy) {
+      // Calling edit will validate and set up the tracking we need
+      edit((EntityProxy) arg);
+    }
+  }
+
+  /**
+   * Returns the requests that were dequeued as part of reusing the context.
+   */
+  private void reuse() {
+    freezeEntities(false);
+    locked = false;
+  }
+
+  /**
+   * Make the EnityProxy bean edited and owned by this RequestContext.
+   */
+  private <T extends EntityProxy> T takeOwnership(AutoBean<T> bean) {
+    editedProxies.put(EntityProxyCategory.stableId(bean), bean);
+    bean.setTag(EntityProxyCategory.REQUEST_CONTEXT,
+        AbstractRequestContext.this);
+    return bean.as();
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/impl/AbstractRequestFactory.java b/user/src/com/google/gwt/requestfactory/shared/impl/AbstractRequestFactory.java
new file mode 100644
index 0000000..3689365
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/AbstractRequestFactory.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.impl;
+
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanFactory;
+import com.google.gwt.event.shared.EventBus;
+import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.EntityProxyId;
+import com.google.gwt.requestfactory.shared.Request;
+import com.google.gwt.requestfactory.shared.RequestFactory;
+import com.google.gwt.requestfactory.shared.RequestTransport;
+import com.google.gwt.requestfactory.shared.messages.IdUtil;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * 
+ */
+public abstract class AbstractRequestFactory extends IdFactory implements
+    RequestFactory {
+  private static final int MAX_VERSION_ENTRIES = 10000;
+
+  private EventBus eventBus;
+
+  @SuppressWarnings("serial")
+  private final Map<String, Integer> version = new LinkedHashMap<String, Integer>(
+      16, 0.75f, true) {
+    @Override
+    protected boolean removeEldestEntry(Entry<String, Integer> eldest) {
+      return size() > MAX_VERSION_ENTRIES;
+    }
+  };
+  private RequestTransport transport;
+
+  /**
+   * Creates a new EntityProxy with an assigned ID.
+   */
+  public <T extends EntityProxy> AutoBean<T> createEntityProxy(Class<T> clazz,
+      SimpleEntityProxyId<T> id) {
+    AutoBean<T> created = getAutoBeanFactory().create(clazz);
+    if (created == null) {
+      throw new IllegalArgumentException("Unknown EntityProxy type "
+          + clazz.getName());
+    }
+    created.setTag(EntityProxyCategory.REQUEST_FACTORY, this);
+    created.setTag(EntityProxyCategory.STABLE_ID, id);
+    return created;
+  }
+
+  public <P extends EntityProxy> Request<P> find(final EntityProxyId<P> proxyId) {
+    if (((SimpleEntityProxyId<P>) proxyId).isEphemeral()) {
+      throw new IllegalArgumentException("Cannot fetch unpersisted entity");
+    }
+
+    AbstractRequestContext context = new AbstractRequestContext(
+        AbstractRequestFactory.this);
+    return new AbstractRequest<P>(context) {
+      {
+        requestContext.addInvocation(this);
+      }
+
+      @Override
+      protected RequestData makeRequestData() {
+        return new RequestData(
+            "com.google.gwt.requestfactory.shared.impl.FindRequest::find",
+            new Object[]{proxyId}, propertyRefs, proxyId.getProxyClass(), null);
+      }
+    };
+  }
+
+  public EventBus getEventBus() {
+    return eventBus;
+  }
+
+  public Class<? extends EntityProxy> getProxyClass(String historyToken) {
+    String typeToken = IdUtil.getTypeToken(historyToken);
+    if (typeToken != null) {
+      return getTypeFromToken(typeToken);
+    }
+    return getTypeFromToken(historyToken);
+  }
+
+  public RequestTransport getRequestTransport() {
+    return transport;
+  }
+
+  /**
+   * The choice of a default request transport is runtime-specific.
+   */
+  public abstract void initialize(EventBus eventBus);
+
+  public void initialize(EventBus eventBus, RequestTransport transport) {
+    this.eventBus = eventBus;
+    this.transport = transport;
+  }
+
+  /**
+   * Implementations of EntityProxies are provided by an AutoBeanFactory, which
+   * is itself a generated type.
+   */
+  protected abstract AutoBeanFactory getAutoBeanFactory();
+
+  /**
+   * Used by {@link AbstractRequestContext} to quiesce update events for objects
+   * that haven't truly changed.
+   */
+  protected boolean hasVersionChanged(SimpleEntityProxyId<?> id,
+      int observedVersion) {
+    String key = getHistoryToken(id);
+    Integer existingVersion = version.get(key);
+    // Return true if we haven't seen this before or the versions differ
+    boolean toReturn = existingVersion == null
+        || !existingVersion.equals(observedVersion);
+    if (toReturn) {
+      version.put(key, observedVersion);
+    }
+    return toReturn;
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/impl/Constants.java b/user/src/com/google/gwt/requestfactory/shared/impl/Constants.java
index e2d1a38..9ebc01a 100644
--- a/user/src/com/google/gwt/requestfactory/shared/impl/Constants.java
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/Constants.java
@@ -20,18 +20,6 @@
  */
 public interface Constants {
 
-  String CONTENT_TOKEN = "contentData";
-  String OPERATION_TOKEN = "operation";
-  String PARAM_TOKEN = "param";
-  String PROPERTY_REF_TOKEN = "propertyRefs";
-  String RESULT_TOKEN = "result";
-  String RELATED_TOKEN = "related";
-  String SIDE_EFFECTS_TOKEN = "sideEffects";
-  String VIOLATIONS_TOKEN = "violations";
-  /**
-   * Property on a proxy JSO that holds its futureId.
-   */
-  String ENCODED_FUTUREID_PROPERTY = "!futureId";
   /**
    * Property on a proxy JSO that holds its encoded server side data store id.
    */
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/EntityProxyCategory.java b/user/src/com/google/gwt/requestfactory/shared/impl/EntityProxyCategory.java
similarity index 91%
rename from user/src/com/google/gwt/requestfactory/client/impl/EntityProxyCategory.java
rename to user/src/com/google/gwt/requestfactory/shared/impl/EntityProxyCategory.java
index 561de38..6fe67c6 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/EntityProxyCategory.java
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/EntityProxyCategory.java
@@ -13,11 +13,12 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.client.impl;
+package com.google.gwt.requestfactory.shared.impl;
 
-import com.google.gwt.editor.client.AutoBean;
-import com.google.gwt.editor.client.AutoBeanUtils;
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanUtils;
 import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.RequestFactory;
 
 /**
  * Contains static implementation methods used by the AutoBean generator.
@@ -53,9 +54,9 @@
     return (AbstractRequestContext) bean.getTag(REQUEST_CONTEXT);
   }
 
-  public static AbstractRequestFactory requestFactory(
+  public static RequestFactory requestFactory(
       AutoBean<? extends EntityProxy> bean) {
-    return (AbstractRequestFactory) bean.getTag(REQUEST_FACTORY);
+    return (RequestFactory) bean.getTag(REQUEST_FACTORY);
   }
 
   @SuppressWarnings("unchecked")
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/FindRequest.java b/user/src/com/google/gwt/requestfactory/shared/impl/FindRequest.java
similarity index 86%
rename from user/src/com/google/gwt/requestfactory/client/impl/FindRequest.java
rename to user/src/com/google/gwt/requestfactory/shared/impl/FindRequest.java
index 7bbee53..b314775 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/FindRequest.java
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/FindRequest.java
@@ -14,19 +14,20 @@
  * the License.
  */
 
-package com.google.gwt.requestfactory.client.impl;
+package com.google.gwt.requestfactory.shared.impl;
 
 import com.google.gwt.requestfactory.server.FindService;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
 import com.google.gwt.requestfactory.shared.Request;
+import com.google.gwt.requestfactory.shared.RequestContext;
 import com.google.gwt.requestfactory.shared.Service;
 
 /**
  * Request selector interface for implementing a find method.
  */
 @Service(FindService.class)
-public interface FindRequest {
+public interface FindRequest extends RequestContext {
   /**
    * Use the implicit lookup in passing EntityProxy types to service methods.
    */
diff --git a/user/src/com/google/gwt/requestfactory/shared/impl/IdFactory.java b/user/src/com/google/gwt/requestfactory/shared/impl/IdFactory.java
new file mode 100644
index 0000000..cc106e4
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/IdFactory.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.impl;
+
+import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.EntityProxyId;
+import com.google.gwt.requestfactory.shared.messages.IdUtil;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Handles common code for creating SimpleEntityProxyIds.
+ */
+public abstract class IdFactory {
+  /**
+   * Maps ephemeral history tokens to an id object. This canonicalizing mapping
+   * resolves the problem of EntityProxyIds hashcodes changing after persist.
+   * Only ids that are created in the RequestFactory are stored here.
+   */
+  private final Map<String, SimpleEntityProxyId<?>> ephemeralIds = new HashMap<String, SimpleEntityProxyId<?>>();
+
+  /**
+   * Allocates an ephemeral proxy id. This object is only valid for the lifetime
+   * of the RequestFactory.
+   */
+  public <P extends EntityProxy> SimpleEntityProxyId<P> allocateId(
+      Class<P> clazz) {
+    SimpleEntityProxyId<P> toReturn = new SimpleEntityProxyId<P>(clazz,
+        ephemeralIds.size() + 1);
+    ephemeralIds.put(getHistoryToken(toReturn), toReturn);
+    return toReturn;
+  }
+
+  public String getHistoryToken(Class<? extends EntityProxy> clazz) {
+    return getTypeToken(clazz);
+  }
+
+  public String getHistoryToken(EntityProxyId<?> proxy) {
+    SimpleEntityProxyId<?> id = (SimpleEntityProxyId<?>) proxy;
+    if (id.isEphemeral()) {
+      return IdUtil.ephemeralId(id.getClientId(),
+          getHistoryToken(proxy.getProxyClass()));
+    } else {
+      return IdUtil.persistedId(id.getServerId(),
+          getHistoryToken(proxy.getProxyClass()));
+    }
+  }
+
+  /**
+   * Create or retrieve a SimpleEntityProxyId.
+   */
+  public <P extends EntityProxy> SimpleEntityProxyId<P> getId(Class<P> clazz,
+      String serverId) {
+    return getId(getTypeToken(clazz), serverId);
+  }
+
+  /**
+   * Create or retrieve a SimpleEntityProxyId. If both the serverId and clientId
+   * are specified and the id is ephemeral, it will be updated with the server
+   * id.
+   */
+  public <P extends EntityProxy> SimpleEntityProxyId<P> getId(Class<P> clazz,
+      String serverId, Integer clientId) {
+    return getId(getTypeToken(clazz), serverId, clientId);
+  }
+
+  /**
+   * Create or retrieve a SimpleEntityProxyId.
+   */
+  public <P extends EntityProxy> SimpleEntityProxyId<P> getId(String typeToken,
+      String serverId) {
+    return getId(typeToken, serverId, null);
+  }
+
+  /**
+   * Create or retrieve a SimpleEntityProxyId. If both the serverId and clientId
+   * are specified and the id is ephemeral, it will be updated with the server
+   * id.
+   */
+  public <P extends EntityProxy> SimpleEntityProxyId<P> getId(String typeToken,
+      String serverId, Integer clientId) {
+    /*
+     * If there's a clientId, that probably means we've just created a brand-new
+     * EntityProxy or have just persisted something on the server.
+     */
+    if (clientId != null) {
+      // Try a cache lookup for the ephemeral key
+      String ephemeralKey = IdUtil.ephemeralId(clientId, typeToken);
+      @SuppressWarnings("unchecked")
+      SimpleEntityProxyId<P> toReturn = (SimpleEntityProxyId<P>) ephemeralIds.get(ephemeralKey);
+
+      // Do we need to allocate an ephemeral id?
+      if (toReturn == null) {
+        Class<P> clazz = getTypeFromToken(typeToken);
+        toReturn = new SimpleEntityProxyId<P>(clazz, clientId);
+        ephemeralIds.put(ephemeralKey, toReturn);
+      }
+
+      // If it's ephemeral, see if we have a serverId and save it
+      if (toReturn.isEphemeral()) {
+        // Sanity check
+        assert toReturn.getProxyClass().equals(getTypeFromToken(typeToken));
+
+        if (serverId != null) {
+          /*
+           * Record the server id so a later "find" operation will have an equal
+           * stableId.
+           */
+          toReturn.setServerId(serverId);
+          String serverKey = IdUtil.persistedId(serverId, typeToken);
+          ephemeralIds.put(serverKey, toReturn);
+        }
+      }
+      return toReturn;
+    }
+
+    // Should never get this far without a server id
+    assert serverId != null : "serverId";
+
+    String serverKey = IdUtil.persistedId(serverId, typeToken);
+    @SuppressWarnings("unchecked")
+    SimpleEntityProxyId<P> toReturn = (SimpleEntityProxyId<P>) ephemeralIds.get(serverKey);
+    if (toReturn != null) {
+      // A cache hit for a locally-created object that has been persisted
+      return toReturn;
+    }
+
+    /*
+     * No existing id, so it was never an ephemeral id created by this
+     * RequestFactory, so we don't need to record it. This should be the normal
+     * case for read-dominated applications.
+     */
+    Class<P> clazz = getTypeFromToken(typeToken);
+    return new SimpleEntityProxyId<P>(clazz, serverId);
+  }
+
+  public <P extends EntityProxy> SimpleEntityProxyId<P> getProxyId(
+      String historyToken) {
+    if (IdUtil.isPersisted(historyToken)) {
+      return getId(IdUtil.getTypeToken(historyToken),
+          IdUtil.getServerId(historyToken));
+    }
+    if (IdUtil.isEphemeral(historyToken)) {
+      @SuppressWarnings("unchecked")
+      SimpleEntityProxyId<P> toReturn = (SimpleEntityProxyId<P>) ephemeralIds.get(historyToken);
+
+      /*
+       * This is tested in FindServiceTest.testFetchUnpersistedFutureId. In
+       * order to get here, the user would have to get an unpersisted history
+       * token and attempt to use it with a different RequestFactory instance.
+       * This could occur if an ephemeral token was bookmarked. In this case,
+       * we'll create a token, however it will never match anything.
+       */
+      if (toReturn == null) {
+        Class<P> clazz = checkTypeToken(IdUtil.getTypeToken(historyToken));
+        toReturn = new SimpleEntityProxyId<P>(clazz, -1 * ephemeralIds.size());
+        ephemeralIds.put(historyToken, toReturn);
+      }
+
+      return toReturn;
+    }
+    throw new IllegalArgumentException(historyToken);
+  }
+
+  protected abstract <P extends EntityProxy> Class<P> getTypeFromToken(
+      String typeToken);
+
+  protected abstract String getTypeToken(Class<?> clazz);
+
+  private <P> Class<P> checkTypeToken(String token) {
+    @SuppressWarnings("unchecked")
+    Class<P> clazz = (Class<P>) getTypeFromToken(token);
+    if (clazz == null) {
+      throw new IllegalArgumentException("Unknnown type");
+    }
+    return clazz;
+  }
+
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/requestfactory/shared/Version.java b/user/src/com/google/gwt/requestfactory/shared/impl/MessageFactoryHolder.java
similarity index 60%
copy from user/src/com/google/gwt/requestfactory/shared/Version.java
copy to user/src/com/google/gwt/requestfactory/shared/impl/MessageFactoryHolder.java
index 5e66314..069509d 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Version.java
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/MessageFactoryHolder.java
@@ -1,23 +1,26 @@
 /*
  * Copyright 2010 Google Inc.
- *
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- *
+ * 
  * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.shared;
+package com.google.gwt.requestfactory.shared.impl;
+
+import com.google.gwt.autobean.server.AutoBeanFactoryMagic;
+import com.google.gwt.requestfactory.shared.messages.MessageFactory;
 
 /**
- * Marks the version property of an entity.
+ * This class has a super-source version with a client-only implementation.
  */
-public @interface Version {
-  // TODO prove the servlet will use this info
+interface MessageFactoryHolder {
+  MessageFactory FACTORY = AutoBeanFactoryMagic.create(MessageFactory.class);
 }
diff --git a/user/src/com/google/gwt/requestfactory/shared/impl/RequestData.java b/user/src/com/google/gwt/requestfactory/shared/impl/RequestData.java
new file mode 100644
index 0000000..cb9c659
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/RequestData.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.impl;
+
+import java.util.Set;
+
+/**
+ * A class that encapsulates the parameters and method name to be invoked on the
+ * server.
+ */
+public class RequestData {
+  private final Class<?> elementType;
+  private final String operation;
+  private final Object[] parameters;
+  private final Set<String> propertyRefs;
+  private final Class<?> returnType;
+
+  public RequestData(String operation, Object[] parameters,
+      Set<String> propertyRefs, Class<?> returnType, Class<?> elementType) {
+    this.operation = operation;
+    this.parameters = parameters;
+    this.propertyRefs = propertyRefs;
+    this.returnType = returnType;
+    this.elementType = elementType;
+  }
+
+  /**
+   * Used to interpret the returned payload.
+   */
+  public Class<?> getElementType() {
+    return elementType;
+  }
+
+  public String getOperation() {
+    return operation;
+  }
+
+  /**
+   * Used by InstanceRequest subtypes to reset the instance object in the
+   * <code>using</code> method.
+   */
+  public Object[] getParameters() {
+    return parameters;
+  }
+
+  public Set<String> getPropertyRefs() {
+    return propertyRefs;
+  }
+
+  /**
+   * Used to interpret the returned payload.
+   */
+  public Class<?> getReturnType() {
+    return returnType;
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/SimpleEntityProxyId.java b/user/src/com/google/gwt/requestfactory/shared/impl/SimpleEntityProxyId.java
similarity index 79%
rename from user/src/com/google/gwt/requestfactory/client/impl/SimpleEntityProxyId.java
rename to user/src/com/google/gwt/requestfactory/shared/impl/SimpleEntityProxyId.java
index fd24028..5a98ae6 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/SimpleEntityProxyId.java
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/SimpleEntityProxyId.java
@@ -13,10 +13,11 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.client.impl;
+package com.google.gwt.requestfactory.shared.impl;
 
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
+import com.google.gwt.requestfactory.shared.messages.IdUtil;
 
 /**
  * Nothing fancy.
@@ -29,7 +30,7 @@
    * A placeholder value for {@link #clientId} to indicate the id was not
    * created locally.
    */
-  private static final int NEVER_EPHEMERAL = -1;
+  public static final int NEVER_EPHEMERAL = -1;
 
   /**
    * The client-side id is ephemeral, and is valid only during the lifetime of a
@@ -55,26 +56,29 @@
   private String serverId;
 
   /**
-   * Construct a stable id. May only be called from
-   * {@link AbstractRequestFactory#getId}.
+   * Construct an ephemeral id. May be called only from
+   * {@link IdFactory#getId()}.
+   */
+  SimpleEntityProxyId(Class<P> proxyClass, int clientId) {
+    assert proxyClass != null;
+    this.clientId = clientId;
+    this.proxyClass = proxyClass;
+    hashCode = clientId;
+  }
+
+  /**
+   * Construct a stable id. May only be called from {@link IdFactory#getId()}
    */
   SimpleEntityProxyId(Class<P> proxyClass, String serverId) {
+    assert proxyClass != null;
+    assert serverId != null && !serverId.contains("@")
+        && !"null".equals(serverId);
     setServerId(serverId);
     clientId = NEVER_EPHEMERAL;
     hashCode = serverId.hashCode();
     this.proxyClass = proxyClass;
   }
 
-  /**
-   * Construct an ephemeral id. May be called only from
-   * {@link AbstractRequestFactory#allocateId}.
-   */
-  SimpleEntityProxyId(Class<P> proxyClass, int clientId) {
-    this.clientId = clientId;
-    this.proxyClass = proxyClass;
-    hashCode = clientId;
-  }
-
   @Override
   public boolean equals(Object o) {
     if (this == o) {
@@ -131,6 +135,26 @@
     if (this.serverId != null) {
       throw new IllegalStateException();
     }
+    assert !"null".equals(serverId);
     this.serverId = serverId;
   }
+
+  /**
+   * For debugging use only.
+   */
+  @Override
+  public String toString() {
+    if (isEphemeral()) {
+      return IdUtil.ephemeralId(clientId, proxyClass.getName());
+    } else {
+      return IdUtil.persistedId(serverId, proxyClass.getName());
+    }
+  }
+
+  /**
+   * Returns <code>true</code> if the id was created as an ephemeral id.
+   */
+  public boolean wasEphemeral() {
+    return clientId != NEVER_EPHEMERAL;
+  }
 }
diff --git a/user/src/com/google/gwt/requestfactory/shared/messages/EntityCodex.java b/user/src/com/google/gwt/requestfactory/shared/messages/EntityCodex.java
new file mode 100644
index 0000000..09b8aac
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/EntityCodex.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.messages;
+
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.Splittable;
+import com.google.gwt.autobean.shared.ValueCodex;
+import com.google.gwt.autobean.shared.impl.LazySplittable;
+import com.google.gwt.autobean.shared.impl.StringQuoter;
+import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.EntityProxyId;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Analogous to {@link ValueCodex}, but for object types.
+ */
+public class EntityCodex {
+  /**
+   * Abstracts the process by which EntityProxies are created.
+   */
+  public interface EntitySource {
+    <Q extends EntityProxy> AutoBean<Q> getBeanForPayload(
+        String serializedProxyId);
+
+    String getSerializedProxyId(EntityProxyId<?> stableId);
+
+    boolean isEntityType(Class<?> clazz);
+  }
+
+  /**
+   * Collection support is limited to value types and resolving ids.
+   */
+  public static Object decode(EntitySource source, Class<?> type,
+      Class<?> elementType, Splittable split) {
+    if (split == null || split == LazySplittable.NULL) {
+      return null;
+    }
+
+    // Collection support
+    if (elementType != null) {
+      Collection<Object> collection = null;
+      if (List.class.equals(type)) {
+        collection = new ArrayList<Object>();
+      } else if (Set.class.equals(type)) {
+        collection = new HashSet<Object>();
+      } else {
+        throw new UnsupportedOperationException();
+      }
+
+      // Decode values
+      if (ValueCodex.canDecode(elementType)) {
+        for (int i = 0, j = split.size(); i < j; i++) {
+          if (split.isNull(i)) {
+            collection.add(null);
+          } else {
+            Object element = ValueCodex.decode(elementType, split.get(i));
+            collection.add(element);
+          }
+        }
+      } else {
+        for (int i = 0, j = split.size(); i < j; i++) {
+          if (split.isNull(i)) {
+            collection.add(null);
+          } else {
+            Object element = decode(source, elementType, null, split.get(i));
+            collection.add(element);
+          }
+        }
+      }
+      return collection;
+    }
+
+    if (source.isEntityType(type) || EntityProxyId.class.equals(type)) {
+      return source.getBeanForPayload(split.asString()).as();
+    }
+
+    // Fall back to values
+    return ValueCodex.decode(type, split);
+  }
+
+  /**
+   * Collection support is limited to value types and resolving ids.
+   */
+  public static Object decode(EntitySource source, Class<?> type,
+      Class<?> elementType, String jsonPayload) {
+    Splittable split = StringQuoter.split(jsonPayload);
+    return decode(source, type, elementType, split);
+  }
+
+  /**
+   * Create a wire-format representation of an object.
+   */
+  public static Splittable encode(EntitySource source, Object value) {
+    if (value == null) {
+      return LazySplittable.NULL;
+    }
+
+    if (value instanceof Iterable<?>) {
+      StringBuffer toReturn = new StringBuffer();
+      toReturn.append('[');
+      boolean first = true;
+      for (Object val : ((Iterable<?>) value)) {
+        if (!first) {
+          toReturn.append(',');
+        } else {
+          first = false;
+        }
+        if (val == null) {
+          toReturn.append("null");
+        } else {
+          toReturn.append(encode(source, val).getPayload());
+        }
+      }
+      toReturn.append(']');
+      return new LazySplittable(toReturn.toString());
+    }
+
+    if (value instanceof EntityProxy) {
+      value = source.getSerializedProxyId(((EntityProxy) value).stableId());
+    }
+
+    if (value instanceof EntityProxyId<?>) {
+      value = source.getSerializedProxyId((EntityProxyId<?>) value);
+    }
+
+    return ValueCodex.encode(value);
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/messages/IdMessage.java b/user/src/com/google/gwt/requestfactory/shared/messages/IdMessage.java
new file mode 100644
index 0000000..11c758f
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/IdMessage.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.messages;
+
+import com.google.gwt.autobean.shared.AutoBean.PropertyName;
+
+/**
+ * Used as a base type for messages that are about a particular id.
+ */
+public interface IdMessage {
+  String CLIENT_ID = "C";
+  String SERVER_ID = "S";
+  String TYPE_TOKEN = "T";
+
+  @PropertyName(CLIENT_ID)
+  int getClientId();
+
+  @PropertyName(SERVER_ID)
+  String getServerId();
+
+  @PropertyName(TYPE_TOKEN)
+  String getTypeToken();
+
+  @PropertyName(CLIENT_ID)
+  void setClientId(int value);
+
+  @PropertyName(SERVER_ID)
+  void setServerId(String value);
+
+  @PropertyName(TYPE_TOKEN)
+  void setTypeToken(String value);
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/requestfactory/shared/messages/IdUtil.java b/user/src/com/google/gwt/requestfactory/shared/messages/IdUtil.java
new file mode 100644
index 0000000..de8c906
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/IdUtil.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.messages;
+
+/**
+ * Common functions for slicing and dicing EntityProxy ids.
+ */
+public class IdUtil {
+  private static final String ANY_SEPARATOR_PATTERN = "@[01]@";
+  private static final String EPHEMERAL_SEPARATOR = "@1@";
+  private static final String TOKEN_SEPARATOR = "@0@";
+  private static final int ID_TOKEN_INDEX = 0;
+  private static final int TYPE_TOKEN_INDEX = 1;
+
+  public static String ephemeralId(int clientId, String typeToken) {
+    return clientId + EPHEMERAL_SEPARATOR + typeToken;
+  }
+
+  public static int getClientId(String encodedId) {
+    return Integer.valueOf(asEphemeral(encodedId)[ID_TOKEN_INDEX]);
+  }
+
+  public static String getServerId(String encodedId) {
+    return asPersisted(encodedId)[ID_TOKEN_INDEX];
+  }
+
+  public static String getTypeToken(String encodedId) {
+    String[] split = asAny(encodedId);
+    if (split.length == 2) {
+      return split[TYPE_TOKEN_INDEX];
+    }
+    return null;
+  }
+
+  public static boolean isEphemeral(String encodedId) {
+    return encodedId.contains(EPHEMERAL_SEPARATOR);
+  }
+
+  public static boolean isPersisted(String encodedId) {
+    return encodedId.contains(TOKEN_SEPARATOR);
+  }
+
+  public static String persistedId(String serverId, String typeToken) {
+    return serverId + TOKEN_SEPARATOR + typeToken;
+  }
+
+  private static String[] asAny(String encodedId) {
+    return encodedId.split(ANY_SEPARATOR_PATTERN);
+  }
+
+  private static String[] asEphemeral(String encodedId) {
+    return encodedId.split(EPHEMERAL_SEPARATOR);
+  }
+
+  private static String[] asPersisted(String encodedId) {
+    return encodedId.split(TOKEN_SEPARATOR);
+  }
+
+  /**
+   * Utility class
+   */
+  private IdUtil() {
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/messages/InvocationMessage.java b/user/src/com/google/gwt/requestfactory/shared/messages/InvocationMessage.java
new file mode 100644
index 0000000..0bd07e2
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/InvocationMessage.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.messages;
+
+import com.google.gwt.autobean.shared.AutoBean.PropertyName;
+import com.google.gwt.autobean.shared.Splittable;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Describes a method invocation.
+ */
+public interface InvocationMessage {
+  String OPERATIONS = "O";
+  String PARAMETERS = "P";
+  String PROPERTY_REFS = "R";
+
+  @PropertyName(OPERATIONS)
+  String getOperation();
+
+  @PropertyName(PARAMETERS)
+  List<Splittable> getParameters();
+
+  @PropertyName(PROPERTY_REFS)
+  Set<String> getPropertyRefs();
+
+  @PropertyName(OPERATIONS)
+  void setOperation(String value);
+
+  @PropertyName(PARAMETERS)
+  void setParameters(List<Splittable> value);
+
+  @PropertyName(PROPERTY_REFS)
+  void setPropertyRefs(Set<String> value);
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/messages/MessageFactory.java b/user/src/com/google/gwt/requestfactory/shared/messages/MessageFactory.java
new file mode 100644
index 0000000..cde822c
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/MessageFactory.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.messages;
+
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanFactory;
+
+/**
+ * The factory for creating RequestFactory wire messages.
+ */
+public interface MessageFactory extends AutoBeanFactory {
+  AutoBean<InvocationMessage> invocation();
+
+  AutoBean<ServerFailureMessage> failure();
+
+  AutoBean<OperationMessage> operation();
+
+  AutoBean<RequestMessage> request();
+
+  AutoBean<ResponseMessage> response();
+
+  AutoBean<ViolationMessage> violation();
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/messages/OperationMessage.java b/user/src/com/google/gwt/requestfactory/shared/messages/OperationMessage.java
new file mode 100644
index 0000000..c57c934
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/OperationMessage.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.messages;
+
+import com.google.gwt.autobean.shared.Splittable;
+import com.google.gwt.autobean.shared.AutoBean.PropertyName;
+import com.google.gwt.requestfactory.shared.WriteOperation;
+
+import java.util.Map;
+
+/**
+ * Represents an operation to be carried out on a single entity on the server.
+ */
+public interface OperationMessage extends IdMessage, VersionedMessage {
+  String OPERATION = "O";
+  String PROPERTY_MAP = "P";
+
+  @PropertyName(OPERATION)
+  WriteOperation getOperation();
+
+  @PropertyName(PROPERTY_MAP)
+  Map<String, Splittable> getPropertyMap();
+
+  @PropertyName(OPERATION)
+  void setOperation(WriteOperation value);
+
+  @PropertyName(PROPERTY_MAP)
+  void setPropertyMap(Map<String, Splittable> map);
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/messages/RequestMessage.java b/user/src/com/google/gwt/requestfactory/shared/messages/RequestMessage.java
new file mode 100644
index 0000000..660f50c
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/RequestMessage.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.messages;
+
+import com.google.gwt.autobean.shared.AutoBean.PropertyName;
+
+import java.util.List;
+
+/**
+ * The message sent from the client to the server.
+ */
+public interface RequestMessage extends VersionedMessage {
+  String INVOCATION = "I";
+  String OPERATIONS = "O";
+
+  @PropertyName(INVOCATION)
+  List<InvocationMessage> getInvocations();
+
+  @PropertyName(OPERATIONS)
+  List<OperationMessage> getOperations();
+
+  @PropertyName(INVOCATION)
+  void setInvocations(List<InvocationMessage> value);
+
+  @PropertyName(OPERATIONS)
+  void setOperations(List<OperationMessage> value);
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/messages/ResponseMessage.java b/user/src/com/google/gwt/requestfactory/shared/messages/ResponseMessage.java
new file mode 100644
index 0000000..e4135c1
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/ResponseMessage.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.messages;
+
+import com.google.gwt.autobean.shared.AutoBean.PropertyName;
+import com.google.gwt.autobean.shared.Splittable;
+
+import java.util.List;
+
+/**
+ * The result of fulfilling a request on the server;
+ */
+public interface ResponseMessage extends VersionedMessage {
+  String GENERAL_FAILURE = "F";
+  String INVOCATION_RESULTS = "I";
+  String OPERATIONS = "O";
+  String STATUS_CODES = "S";
+  // V would conflict with versionedMessage
+  String VIOLATIONS = "X";
+
+  @PropertyName(GENERAL_FAILURE)
+  ServerFailureMessage getGeneralFailure();
+
+  @PropertyName(INVOCATION_RESULTS)
+  List<Splittable> getInvocationResults();
+
+  @PropertyName(OPERATIONS)
+  List<OperationMessage> getOperations();
+
+  @PropertyName(STATUS_CODES)
+  List<Boolean> getStatusCodes();
+
+  @PropertyName(VIOLATIONS)
+  List<ViolationMessage> getViolations();
+
+  @PropertyName(GENERAL_FAILURE)
+  void setGeneralFailure(ServerFailureMessage failure);
+
+  @PropertyName(INVOCATION_RESULTS)
+  void setInvocationResults(List<Splittable> value);
+
+  @PropertyName(OPERATIONS)
+  void setOperations(List<OperationMessage> value);
+
+  @PropertyName(STATUS_CODES)
+  void setStatusCodes(List<Boolean> value);
+
+  @PropertyName(VIOLATIONS)
+  void setViolations(List<ViolationMessage> value);
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/messages/ServerFailureMessage.java b/user/src/com/google/gwt/requestfactory/shared/messages/ServerFailureMessage.java
new file mode 100644
index 0000000..f196adf
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/ServerFailureMessage.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.messages;
+
+import com.google.gwt.autobean.shared.AutoBean.PropertyName;
+
+/**
+ * Encapsulates a ServerFailure object.
+ */
+public interface ServerFailureMessage {
+  String EXCEPTION_TYPE = "X";
+  String MESSAGE = "M";
+  String STACK_TRACE = "S";
+
+  @PropertyName(EXCEPTION_TYPE)
+  String getExceptionType();
+
+  @PropertyName(MESSAGE)
+  String getMessage();
+
+  @PropertyName(STACK_TRACE)
+  String getStackTrace();
+
+  @PropertyName(EXCEPTION_TYPE)
+  void setExceptionType(String exceptionType);
+
+  @PropertyName(MESSAGE)
+  void setMessage(String message);
+
+  @PropertyName(STACK_TRACE)
+  void setStackTrace(String stackTrace);
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/Version.java b/user/src/com/google/gwt/requestfactory/shared/messages/VersionedMessage.java
similarity index 62%
copy from user/src/com/google/gwt/requestfactory/shared/Version.java
copy to user/src/com/google/gwt/requestfactory/shared/messages/VersionedMessage.java
index 5e66314..6563ec1 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Version.java
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/VersionedMessage.java
@@ -1,23 +1,31 @@
 /*
  * Copyright 2010 Google Inc.
- *
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- *
+ * 
  * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.shared;
+package com.google.gwt.requestfactory.shared.messages;
+
+import com.google.gwt.autobean.shared.AutoBean.PropertyName;
 
 /**
- * Marks the version property of an entity.
+ * Describes a message that contains version information.
  */
-public @interface Version {
-  // TODO prove the servlet will use this info
+public interface VersionedMessage {
+  String VERSION = "V";
+
+  @PropertyName(VERSION)
+  int getVersion();
+
+  @PropertyName(VERSION)
+  void setVersion(int version);
 }
diff --git a/user/src/com/google/gwt/requestfactory/shared/messages/ViolationMessage.java b/user/src/com/google/gwt/requestfactory/shared/messages/ViolationMessage.java
new file mode 100644
index 0000000..ea57a59
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/ViolationMessage.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.shared.messages;
+
+import com.google.gwt.autobean.shared.AutoBean.PropertyName;
+
+/**
+ * Represents a ConstraintViolation
+ */
+public interface ViolationMessage extends IdMessage {
+  String MESSAGE = "M";
+  String PATH = "P";
+
+  @PropertyName(MESSAGE)
+  String getMessage();
+
+  @PropertyName(PATH)
+  String getPath();
+
+  @PropertyName(MESSAGE)
+  void setMessage(String value);
+
+  @PropertyName(PATH)
+  void setPath(String value);
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/Version.java b/user/src/com/google/gwt/requestfactory/shared/messages/package-info.java
similarity index 74%
copy from user/src/com/google/gwt/requestfactory/shared/Version.java
copy to user/src/com/google/gwt/requestfactory/shared/messages/package-info.java
index 5e66314..b396dfc 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Version.java
+++ b/user/src/com/google/gwt/requestfactory/shared/messages/package-info.java
@@ -1,23 +1,24 @@
 /*
  * Copyright 2010 Google Inc.
- *
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- *
+ * 
  * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.shared;
 
 /**
- * Marks the version property of an entity.
+ * Contains classes that define the RequestFactory wire format.
+ * 
+ * @since GWT 2.1.1
  */
-public @interface Version {
-  // TODO prove the servlet will use this info
-}
+@com.google.gwt.util.PreventSpuriousRebuilds
+package com.google.gwt.requestfactory.shared.messages;
+
diff --git a/user/super/com/google/gwt/autobean/super/com/google/gwt/autobean/shared/impl/StringQuoter.java b/user/super/com/google/gwt/autobean/super/com/google/gwt/autobean/shared/impl/StringQuoter.java
new file mode 100644
index 0000000..7346bec
--- /dev/null
+++ b/user/super/com/google/gwt/autobean/super/com/google/gwt/autobean/shared/impl/StringQuoter.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.shared.impl;
+
+import com.google.gwt.core.client.JsonUtils;
+import com.google.gwt.autobean.client.impl.JsoSplittable;
+import com.google.gwt.autobean.shared.Splittable;
+import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter;
+
+/**
+ * This a super-source version with a client-only implementation.
+ */
+public class StringQuoter {
+  public static String quote(String raw) {
+    return JsonUtils.escapeValue(raw);
+  }
+
+  public static Splittable split(String payload) {
+    return JsoSplittable.create(JsonUtils.safeEval(payload));
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/shared/Version.java b/user/super/com/google/gwt/requestfactory/super/com/google/gwt/requestfactory/shared/impl/MessageFactoryHolder.java
similarity index 63%
copy from user/src/com/google/gwt/requestfactory/shared/Version.java
copy to user/super/com/google/gwt/requestfactory/super/com/google/gwt/requestfactory/shared/impl/MessageFactoryHolder.java
index 5e66314..3e5d3ec 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Version.java
+++ b/user/super/com/google/gwt/requestfactory/super/com/google/gwt/requestfactory/shared/impl/MessageFactoryHolder.java
@@ -1,23 +1,26 @@
 /*
  * Copyright 2010 Google Inc.
- *
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- *
+ * 
  * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.shared;
+package com.google.gwt.requestfactory.shared.impl;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.requestfactory.shared.messages.MessageFactory;
 
 /**
- * Marks the version property of an entity.
+ * This a super-source version with a client-only implementation.
  */
-public @interface Version {
-  // TODO prove the servlet will use this info
+interface MessageFactoryHolder {
+  MessageFactory FACTORY = GWT.create(MessageFactory.class);
 }
diff --git a/user/test/com/google/gwt/autobean/AutoBeanSuite.java b/user/test/com/google/gwt/autobean/AutoBeanSuite.java
new file mode 100644
index 0000000..491e91c
--- /dev/null
+++ b/user/test/com/google/gwt/autobean/AutoBeanSuite.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean;
+
+import com.google.gwt.autobean.client.AutoBeanTest;
+import com.google.gwt.autobean.server.AutoBeanCodexJreTest;
+import com.google.gwt.autobean.server.AutoBeanJreTest;
+import com.google.gwt.autobean.shared.AutoBeanCodexTest;
+import com.google.gwt.junit.tools.GWTTestSuite;
+
+import junit.framework.Test;
+
+/**
+ * Tests of the Editor framework. These tests focus on core Editor behaviors,
+ * rather than on integration with backing stores.
+ */
+public class AutoBeanSuite {
+  public static Test suite() {
+    GWTTestSuite suite = new GWTTestSuite("Test suite for AutoBean functions");
+    suite.addTestSuite(AutoBeanCodexJreTest.class);
+    suite.addTestSuite(AutoBeanCodexTest.class);
+    suite.addTestSuite(AutoBeanJreTest.class);
+    suite.addTestSuite(AutoBeanTest.class);
+    return suite;
+  }
+}
diff --git a/user/test/com/google/gwt/editor/client/AutoBeanTest.java b/user/test/com/google/gwt/autobean/client/AutoBeanTest.java
similarity index 90%
rename from user/test/com/google/gwt/editor/client/AutoBeanTest.java
rename to user/test/com/google/gwt/autobean/client/AutoBeanTest.java
index 048e8a5..5fa00ce 100644
--- a/user/test/com/google/gwt/editor/client/AutoBeanTest.java
+++ b/user/test/com/google/gwt/autobean/client/AutoBeanTest.java
@@ -13,10 +13,14 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.editor.client;
+package com.google.gwt.autobean.client;
 
+import com.google.gwt.autobean.shared.AutoBean;
+import com.google.gwt.autobean.shared.AutoBeanFactory;
+import com.google.gwt.autobean.shared.AutoBeanFactory.Category;
+import com.google.gwt.autobean.shared.AutoBeanUtils;
+import com.google.gwt.autobean.shared.AutoBeanVisitor;
 import com.google.gwt.core.client.GWT;
-import com.google.gwt.editor.client.AutoBeanFactory.Category;
 import com.google.gwt.junit.client.GWTTestCase;
 
 import java.util.ArrayList;
@@ -45,8 +49,11 @@
     }
   }
 
+  /**
+   * The factory being tested.
+   */
   @Category(CallImpl.class)
-  interface Factory extends AutoBeanFactory {
+  protected interface Factory extends AutoBeanFactory {
     AutoBean<HasCall> hasCall();
 
     AutoBean<HasList> hasList();
@@ -115,16 +122,20 @@
     public void setString(String value) {
       this.string = value;
     }
+
+    public String toString() {
+      return "toString";
+    }
   }
 
   interface UnreferencedInFactory {
   }
 
-  private Factory factory;
+  protected Factory factory;
 
   @Override
   public String getModuleName() {
-    return "com.google.gwt.editor.Editor";
+    return "com.google.gwt.autobean.AutoBean";
   }
 
   public void testCategory() {
@@ -251,9 +262,10 @@
     AutoBean<Intf> w = factory.intf(real);
     // AutoBean interface never equals wrapped object
     assertFalse(w.equals(real));
-    // Wrapper interface should delegate hashCode() and equals()
+    // Wrapper interface should delegate hashCode(), equals(), and toString()
     assertEquals(real.hashCode(), w.as().hashCode());
     assertEquals(real, w.as());
+    assertEquals(real.toString(), w.as().toString());
     assertEquals(w.as(), real);
   }
 
@@ -323,8 +335,10 @@
           AutoBean<?> value, PropertyContext ctx) {
         if ("intf".equals(propertyName)) {
           assertSame(intf, value);
+          assertEquals(Intf.class, ctx.getType());
         } else if ("unreferenced".equals(propertyName)) {
           assertNull(value);
+          assertEquals(UnreferencedInFactory.class, ctx.getType());
         } else {
           fail("Unexpecetd property " + propertyName);
         }
@@ -335,8 +349,10 @@
           PropertyContext ctx) {
         if ("int".equals(propertyName)) {
           assertEquals(42, value);
+          assertEquals(int.class, ctx.getType());
         } else if ("string".equals(propertyName)) {
           assertNull(value);
+          assertEquals(String.class, ctx.getType());
         } else {
           fail("Unknown value property " + propertyName);
         }
@@ -364,6 +380,10 @@
     c.check();
   }
 
+  public void testType() {
+    assertEquals(Intf.class, factory.intf().getType());
+  }
+
   /**
    * Ensure that a totally automatic bean can't be unwrapped, since the
    * generated mapper depends on the AutoBean.
diff --git a/user/test/com/google/gwt/autobean/server/AutoBeanCodexJreTest.java b/user/test/com/google/gwt/autobean/server/AutoBeanCodexJreTest.java
new file mode 100644
index 0000000..940331f
--- /dev/null
+++ b/user/test/com/google/gwt/autobean/server/AutoBeanCodexJreTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import com.google.gwt.autobean.shared.AutoBeanCodexTest;
+
+/**
+ * Runs AutoBeanCodexTest in pure-JRE mode.
+ */
+public class AutoBeanCodexJreTest extends AutoBeanCodexTest {
+
+  @Override
+  public String getModuleName() {
+    return null;
+  }
+
+  @Override
+  protected void gwtSetUp() throws Exception {
+    f = AutoBeanFactoryMagic.create(Factory.class);
+  }
+
+}
diff --git a/user/test/com/google/gwt/autobean/server/AutoBeanJreTest.java b/user/test/com/google/gwt/autobean/server/AutoBeanJreTest.java
new file mode 100644
index 0000000..2f35a1a
--- /dev/null
+++ b/user/test/com/google/gwt/autobean/server/AutoBeanJreTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.server;
+
+import com.google.gwt.autobean.client.AutoBeanTest;
+
+/**
+ * Runs the AutoBeanTests against the JRE implementation.
+ */
+public class AutoBeanJreTest extends AutoBeanTest {
+
+  @Override
+  public String getModuleName() {
+    return null;
+  }
+
+  @Override
+  protected void gwtSetUp() throws Exception {
+    factory = AutoBeanFactoryMagic.create(Factory.class);
+  }
+}
diff --git a/user/test/com/google/gwt/autobean/shared/AutoBeanCodexTest.java b/user/test/com/google/gwt/autobean/shared/AutoBeanCodexTest.java
new file mode 100644
index 0000000..3d110a5
--- /dev/null
+++ b/user/test/com/google/gwt/autobean/shared/AutoBeanCodexTest.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.autobean.shared;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.junit.client.GWTTestCase;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Simple encoding / decoding tests for the AutoBeanCodex.
+ */
+public class AutoBeanCodexTest extends GWTTestCase {
+  /**
+   * Protected so that the JRE-only test can instantiate instances.
+   */
+  protected interface Factory extends AutoBeanFactory {
+    AutoBean<HasAutoBean> hasAutoBean();
+
+    /**
+     * @return
+     */
+    AutoBean<HasCycle> hasCycle();
+
+    AutoBean<HasList> hasList();
+
+    /**
+     * @return
+     */
+    AutoBean<HasMap> hasMap();
+
+    AutoBean<HasSimple> hasSimple();
+
+    AutoBean<Simple> simple();
+  }
+
+  interface HasAutoBean {
+    Splittable getSimple();
+
+    List<Splittable> getSimpleList();
+
+    Splittable getString();
+
+    void setSimple(Splittable simple);
+
+    void setSimpleList(List<Splittable> simple);
+
+    void setString(Splittable s);
+  }
+
+  /**
+   * Used to test that cycles are detected.
+   */
+  interface HasCycle {
+    List<HasCycle> getCycle();
+
+    void setCycle(List<HasCycle> cycle);
+  }
+
+  interface HasList {
+    List<Integer> getIntList();
+
+    List<Simple> getList();
+
+    void setIntList(List<Integer> list);
+
+    void setList(List<Simple> list);
+  }
+
+  interface HasMap {
+    Map<Simple, Simple> getComplexMap();
+
+    Map<String, Simple> getSimpleMap();
+
+    void setComplexMap(Map<Simple, Simple> map);
+
+    void setSimpleMap(Map<String, Simple> map);
+  }
+
+  interface HasSimple {
+    Simple getSimple();
+
+    void setSimple(Simple s);
+  }
+
+  interface Simple {
+    int getInt();
+
+    String getString();
+
+    void setInt(int i);
+
+    void setString(String s);
+  }
+
+  protected Factory f;
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.autobean.AutoBean";
+  }
+
+  public void testCycle() {
+    AutoBean<HasCycle> bean = f.hasCycle();
+    bean.as().setCycle(Arrays.asList(bean.as()));
+    try {
+      AutoBeanCodex.encode(bean);
+      fail("Should not have encoded");
+    } catch (UnsupportedOperationException expected) {
+    }
+  }
+
+  public void testEmptyList() {
+    AutoBean<HasList> bean = f.hasList();
+    bean.as().setList(Collections.<Simple> emptyList());
+    Splittable split = AutoBeanCodex.encode(bean);
+    AutoBean<HasList> decodedBean = AutoBeanCodex.decode(f, HasList.class,
+        split);
+    assertNotNull(decodedBean.as().getList());
+    assertTrue(decodedBean.as().getList().isEmpty());
+  }
+
+  public void testMap() {
+    AutoBean<HasMap> bean = f.hasMap();
+    Map<String, Simple> map = new HashMap<String, Simple>();
+    Map<Simple, Simple> complex = new HashMap<Simple, Simple>();
+    bean.as().setSimpleMap(map);
+    bean.as().setComplexMap(complex);
+
+    for (int i = 0, j = 5; i < j; i++) {
+      Simple s = f.simple().as();
+      s.setInt(i);
+      map.put(String.valueOf(i), s);
+
+      Simple key = f.simple().as();
+      key.setString(String.valueOf(i));
+      complex.put(key, s);
+    }
+
+    Splittable split = AutoBeanCodex.encode(bean);
+    AutoBean<HasMap> decoded = AutoBeanCodex.decode(f, HasMap.class, split);
+    map = decoded.as().getSimpleMap();
+    complex = decoded.as().getComplexMap();
+    assertEquals(5, map.size());
+    for (int i = 0, j = 5; i < j; i++) {
+      Simple s = map.get(String.valueOf(i));
+      assertNotNull(s);
+      assertEquals(i, s.getInt());
+    }
+    assertEquals(5, complex.size());
+    for (Map.Entry<Simple, Simple> entry : complex.entrySet()) {
+      assertEquals(entry.getKey().getString(),
+          String.valueOf(entry.getValue().getInt()));
+    }
+  }
+
+  public void testNull() {
+    AutoBean<Simple> bean = f.simple();
+    Splittable split = AutoBeanCodex.encode(bean);
+    AutoBean<Simple> decodedBean = AutoBeanCodex.decode(f, Simple.class, split);
+    assertNull(decodedBean.as().getString());
+  }
+
+  public void testSimple() {
+    AutoBean<Simple> bean = f.simple();
+    Simple simple = bean.as();
+    simple.setInt(42);
+    simple.setString("Hello World!");
+
+    Splittable split = AutoBeanCodex.encode(bean);
+
+    AutoBean<Simple> decodedBean = AutoBeanCodex.decode(f, Simple.class, split);
+    assertTrue(AutoBeanUtils.diff(bean, decodedBean).isEmpty());
+
+    AutoBean<HasSimple> bean2 = f.hasSimple();
+    bean2.as().setSimple(simple);
+    split = AutoBeanCodex.encode(bean2);
+
+    AutoBean<HasSimple> decodedBean2 = AutoBeanCodex.decode(f, HasSimple.class,
+        split);
+    assertNotNull(decodedBean2.as().getSimple());
+    assertTrue(AutoBeanUtils.diff(bean,
+        AutoBeanUtils.getAutoBean(decodedBean2.as().getSimple())).isEmpty());
+
+    AutoBean<HasList> bean3 = f.hasList();
+    bean3.as().setIntList(Arrays.asList(1, 2, 3, null, 4, 5));
+    bean3.as().setList(Arrays.asList(simple));
+    split = AutoBeanCodex.encode(bean3);
+
+    AutoBean<HasList> decodedBean3 = AutoBeanCodex.decode(f, HasList.class,
+        split);
+    assertNotNull(decodedBean3.as().getIntList());
+    assertEquals(Arrays.asList(1, 2, 3, null, 4, 5),
+        decodedBean3.as().getIntList());
+    assertNotNull(decodedBean3.as().getList());
+    assertEquals(1, decodedBean3.as().getList().size());
+    assertTrue(AutoBeanUtils.diff(bean,
+        AutoBeanUtils.getAutoBean(decodedBean3.as().getList().get(0))).isEmpty());
+  }
+
+  public void testSplittable() {
+    AutoBean<Simple> simple = f.simple();
+    simple.as().setString("Simple");
+    AutoBean<HasAutoBean> bean = f.hasAutoBean();
+    bean.as().setSimple(AutoBeanCodex.encode(simple));
+    bean.as().setString(ValueCodex.encode("Hello ['\"] world"));
+    List<Splittable> testList = Arrays.asList(AutoBeanCodex.encode(simple),
+        null, AutoBeanCodex.encode(simple));
+    bean.as().setSimpleList(testList);
+    Splittable split = AutoBeanCodex.encode(bean);
+
+    AutoBean<HasAutoBean> decoded = AutoBeanCodex.decode(f, HasAutoBean.class,
+        split);
+    Splittable toDecode = decoded.as().getSimple();
+    AutoBean<Simple> decodedSimple = AutoBeanCodex.decode(f, Simple.class,
+        toDecode);
+    assertEquals("Simple", decodedSimple.as().getString());
+    assertEquals("Hello ['\"] world",
+        ValueCodex.decode(String.class, decoded.as().getString()));
+
+    List<Splittable> list = decoded.as().getSimpleList();
+    assertEquals(3, list.size());
+    assertNull(list.get(1));
+    assertEquals("Simple",
+        AutoBeanCodex.decode(f, Simple.class, list.get(2)).as().getString());
+  }
+
+  @Override
+  protected void gwtSetUp() throws Exception {
+    f = GWT.create(Factory.class);
+  }
+}
diff --git a/user/test/com/google/gwt/editor/EditorSuite.java b/user/test/com/google/gwt/editor/EditorSuite.java
index aab8247..e69456e 100644
--- a/user/test/com/google/gwt/editor/EditorSuite.java
+++ b/user/test/com/google/gwt/editor/EditorSuite.java
@@ -15,7 +15,8 @@
  */
 package com.google.gwt.editor;
 
-import com.google.gwt.editor.client.AutoBeanTest;
+import com.google.gwt.autobean.client.AutoBeanTest;
+import com.google.gwt.autobean.server.AutoBeanJreTest;
 import com.google.gwt.editor.client.EditorErrorTest;
 import com.google.gwt.editor.client.SimpleBeanEditorTest;
 import com.google.gwt.editor.client.adapters.ListEditorWrapperTest;
@@ -33,6 +34,7 @@
   public static Test suite() {
     GWTTestSuite suite = new GWTTestSuite(
         "Test suite for core Editor functions");
+    suite.addTestSuite(AutoBeanJreTest.class);
     suite.addTestSuite(AutoBeanTest.class);
     suite.addTestSuite(DelegateMapTest.class);
     suite.addTestSuite(EditorModelTest.class);
diff --git a/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java b/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java
index 3aa7f1b..19ea814 100644
--- a/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java
+++ b/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java
@@ -15,12 +15,11 @@
  */
 package com.google.gwt.requestfactory;
 
-import com.google.gwt.requestfactory.client.impl.SimpleEntityProxyIdTest;
 import com.google.gwt.requestfactory.rebind.model.RequestFactoryModelTest;
-import com.google.gwt.requestfactory.server.JsonRequestProcessorTest;
-import com.google.gwt.requestfactory.server.ReflectionBasedOperationRegistryTest;
+import com.google.gwt.requestfactory.server.FindServiceJreTest;
 import com.google.gwt.requestfactory.server.RequestFactoryInterfaceValidatorTest;
-import com.google.gwt.requestfactory.server.RequestPropertyTest;
+import com.google.gwt.requestfactory.server.RequestFactoryJreTest;
+import com.google.gwt.requestfactory.shared.impl.SimpleEntityProxyIdTest;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -32,12 +31,11 @@
   public static Test suite() {
     TestSuite suite = new TestSuite(
         "requestfactory package tests that require the JRE");
+    suite.addTestSuite(FindServiceJreTest.class);
+    suite.addTestSuite(RequestFactoryJreTest.class);
     suite.addTestSuite(SimpleEntityProxyIdTest.class);
-    suite.addTestSuite(JsonRequestProcessorTest.class);
-    suite.addTestSuite(ReflectionBasedOperationRegistryTest.class);
     suite.addTestSuite(RequestFactoryInterfaceValidatorTest.class);
     suite.addTestSuite(RequestFactoryModelTest.class);
-    suite.addTestSuite(RequestPropertyTest.class);
     return suite;
   }
 }
diff --git a/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java b/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java
index d4ec7e4..2efef63 100644
--- a/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java
+++ b/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java
@@ -19,7 +19,6 @@
 import com.google.gwt.requestfactory.client.FindServiceTest;
 import com.google.gwt.requestfactory.client.RequestFactoryExceptionHandlerTest;
 import com.google.gwt.requestfactory.client.RequestFactoryPolymorphicTest;
-import com.google.gwt.requestfactory.client.RequestFactoryStringTest;
 import com.google.gwt.requestfactory.client.RequestFactoryTest;
 import com.google.gwt.requestfactory.client.ui.EditorTest;
 
@@ -34,7 +33,6 @@
         "Test suite for requestfactory gwt code.");
     suite.addTestSuite(EditorTest.class);
     suite.addTestSuite(RequestFactoryTest.class);
-    suite.addTestSuite(RequestFactoryStringTest.class);
     suite.addTestSuite(RequestFactoryExceptionHandlerTest.class);
     suite.addTestSuite(RequestFactoryPolymorphicTest.class);
     suite.addTestSuite(FindServiceTest.class);
diff --git a/user/test/com/google/gwt/requestfactory/client/FindServiceTest.java b/user/test/com/google/gwt/requestfactory/client/FindServiceTest.java
index 95b31dc..6285434 100644
--- a/user/test/com/google/gwt/requestfactory/client/FindServiceTest.java
+++ b/user/test/com/google/gwt/requestfactory/client/FindServiceTest.java
@@ -15,9 +15,7 @@
  */
 package com.google.gwt.requestfactory.client;
 
-import com.google.gwt.core.client.GWT;
 import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.event.shared.SimpleEventBus;
 import com.google.gwt.requestfactory.shared.EntityProxyChange;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
 import com.google.gwt.requestfactory.shared.Receiver;
@@ -150,8 +148,7 @@
 
     // Here's the factory from the "previous invocation" of the client
     {
-      SimpleRequestFactory oldFactory = GWT.create(SimpleRequestFactory.class);
-      oldFactory.initialize(new SimpleEventBus());
+      SimpleRequestFactory oldFactory = createFactory();
       EntityProxyId<SimpleBarProxy> id = oldFactory.simpleBarRequest().create(
           SimpleBarProxy.class).stableId();
       historyToken = oldFactory.getHistoryToken(id);
diff --git a/user/test/com/google/gwt/requestfactory/client/RequestFactoryStringTest.java b/user/test/com/google/gwt/requestfactory/client/RequestFactoryStringTest.java
deleted file mode 100644
index 4f7c75f..0000000
--- a/user/test/com/google/gwt/requestfactory/client/RequestFactoryStringTest.java
+++ /dev/null
@@ -1,770 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.client;
-
-import com.google.gwt.requestfactory.shared.EntityProxyChange;
-import com.google.gwt.requestfactory.shared.Receiver;
-import com.google.gwt.requestfactory.shared.Request;
-import com.google.gwt.requestfactory.shared.RequestContext;
-import com.google.gwt.requestfactory.shared.ServerFailure;
-import com.google.gwt.requestfactory.shared.SimpleBarProxy;
-import com.google.gwt.requestfactory.shared.SimpleBarRequest;
-import com.google.gwt.requestfactory.shared.SimpleFooStringProxy;
-import com.google.gwt.requestfactory.shared.SimpleFooStringRequest;
-import com.google.gwt.requestfactory.shared.Violation;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Tests for {@link com.google.gwt.requestfactory.shared.RequestFactory}.
- */
-public class RequestFactoryStringTest extends RequestFactoryTestBase {
-  /*
-   * DO NOT USE finishTest(). Instead, call finishTestAndReset();
-   */
-
-  private class FailFixAndRefire<T> extends Receiver<T> {
-
-    private final SimpleFooStringProxy proxy;
-    private final Request<T> request;
-    private boolean voidReturnExpected;
-
-    FailFixAndRefire(SimpleFooStringProxy proxy, RequestContext context,
-        Request<T> request) {
-      this.proxy = context.edit(proxy);
-      this.request = request;
-    }
-
-    @Override
-    public void onSuccess(T response) {
-      /*
-       * Make sure your class path includes:
-       * 
-       * tools/lib/apache/log4j/log4j-1.2.16.jar
-       * tools/lib/hibernate/validator/hibernate-validator-4.1.0.Final.jar
-       * tools/lib/slf4j/slf4j-api/slf4j-api-1.6.1.jar
-       * tools/lib/slf4j/slf4j-log4j12/slf4j-log4j12-1.6.1.jar
-       */
-      fail("Violations expected (you might be missing some jars, "
-          + "see the comment above this line)");
-    }
-
-    @Override
-    public void onViolation(Set<Violation> errors) {
-
-      // size violation expected
-
-      assertEquals(1, errors.size());
-      Violation error = errors.iterator().next();
-      assertEquals("userName", error.getPath());
-      assertEquals("size must be between 3 and 30", error.getMessage());
-      assertEquals(proxy.stableId(), error.getProxyId());
-
-      // Now re-used the request to fix the edit
-
-      proxy.setUserName("long enough");
-      request.fire(new Receiver<T>() {
-        @Override
-        public void onSuccess(T response) {
-          if (voidReturnExpected) {
-            assertNull(response);
-          } else {
-            assertEquals(proxy.stableId(),
-                ((SimpleFooStringProxy) response).stableId());
-          }
-          finishTestAndReset();
-        }
-      });
-    }
-
-    void doVoidTest() {
-      voidReturnExpected = true;
-      doTest();
-    }
-
-    void doTest() {
-      proxy.setUserName("a"); // too short
-      request.fire(this);
-    }
-  }
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.requestfactory.RequestFactorySuite";
-  }
-
-  public void testDummyCreate() {
-    delayTestFinish(5000);
-
-    final SimpleFooEventHandler<SimpleFooStringProxy> handler = new SimpleFooEventHandler<SimpleFooStringProxy>();
-    EntityProxyChange.registerForProxyType(req.getEventBus(),
-        SimpleFooStringProxy.class, handler);
-
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    final SimpleFooStringProxy foo = context.create(SimpleFooStringProxy.class);
-    Object futureId = foo.getId();
-    assertEquals(futureId, foo.getId());
-    Request<SimpleFooStringProxy> fooReq = context.persistAndReturnSelf().using(
-        foo);
-    fooReq.fire(new Receiver<SimpleFooStringProxy>() {
-
-      @Override
-      public void onSuccess(final SimpleFooStringProxy returned) {
-        Object futureId = foo.getId();
-        assertEquals(futureId, foo.getId());
-
-        /*
-         * Two events are fired: (i) PERSIST event fired from
-         * DeltaValueStoreJsonImpl because the proxy was persisted, and (ii)
-         * UPDATE event fired from ValueStoreJsonImpl because the new proxy was
-         * part of the return value.
-         */
-        assertEquals(1, handler.persistEventCount);
-        assertEquals(1, handler.updateEventCount);
-        assertEquals(2, handler.totalEventCount);
-
-        checkStableIdEquals(foo, returned);
-        finishTestAndReset();
-      }
-    });
-  }
-
-  public void testDummyCreateBar() {
-    delayTestFinish(5000);
-
-    SimpleBarRequest context = req.simpleBarRequest();
-    final SimpleBarProxy foo = context.create(SimpleBarProxy.class);
-    Request<SimpleBarProxy> fooReq = context.persistAndReturnSelf().using(foo);
-    fooReq.fire(new Receiver<SimpleBarProxy>() {
-
-      @Override
-      public void onSuccess(final SimpleBarProxy returned) {
-        checkStableIdEquals(foo, returned);
-        finishTestAndReset();
-      }
-    });
-  }
-
-  public void testFindFindEdit() {
-    delayTestFinish(5000);
-
-    final SimpleFooEventHandler<SimpleFooStringProxy> handler = new SimpleFooEventHandler<SimpleFooStringProxy>();
-    EntityProxyChange.registerForProxyType(req.getEventBus(),
-        SimpleFooStringProxy.class, handler);
-
-    req.simpleFooStringRequest().findSimpleFooStringById("999x").fire(
-        new Receiver<SimpleFooStringProxy>() {
-
-          @Override
-          public void onSuccess(SimpleFooStringProxy newFoo) {
-            assertEquals(1, handler.updateEventCount);
-            assertEquals(1, handler.totalEventCount);
-
-            req.simpleFooStringRequest().findSimpleFooStringById("999x").fire(
-                new Receiver<SimpleFooStringProxy>() {
-
-                  @Override
-                  public void onSuccess(SimpleFooStringProxy newFoo) {
-                    // no events are fired second time.
-                    assertEquals(1, handler.updateEventCount);
-                    assertEquals(1, handler.totalEventCount);
-                    SimpleFooStringRequest context = req.simpleFooStringRequest();
-                    final Request<Void> mutateRequest = context.persist().using(
-                        newFoo);
-                    newFoo = context.edit(newFoo);
-                    newFoo.setUserName("Ray");
-                    mutateRequest.fire(new Receiver<Void>() {
-                      @Override
-                      public void onSuccess(Void response) {
-                        // events fired on updates.
-                        assertEquals(2, handler.updateEventCount);
-                        assertEquals(2, handler.totalEventCount);
-
-                        finishTestAndReset();
-                      }
-                    });
-                  }
-                });
-          }
-        });
-  }
-
-  public void testFetchEntity() {
-    delayTestFinish(5000);
-    req.simpleFooStringRequest().findSimpleFooStringById("999x").fire(
-        new Receiver<SimpleFooStringProxy>() {
-          @Override
-          public void onSuccess(SimpleFooStringProxy response) {
-            assertEquals(42, (int) response.getIntId());
-            assertEquals("GWT", response.getUserName());
-            assertEquals(8L, (long) response.getLongField());
-            assertEquals(com.google.gwt.requestfactory.shared.SimpleEnum.FOO,
-                response.getEnumField());
-            assertEquals(null, response.getBarField());
-            finishTestAndReset();
-          }
-        });
-  }
-
-  public void testFetchEntityWithRelation() {
-    delayTestFinish(5000);
-    req.simpleFooStringRequest().findSimpleFooStringById("999x").with(
-        "barField").fire(new Receiver<SimpleFooStringProxy>() {
-      @Override
-      public void onSuccess(SimpleFooStringProxy response) {
-        assertEquals(42, (int) response.getIntId());
-        assertEquals("GWT", response.getUserName());
-        assertEquals(8L, (long) response.getLongField());
-        assertEquals(com.google.gwt.requestfactory.shared.SimpleEnum.FOO,
-            response.getEnumField());
-        assertNotNull(response.getBarField());
-        finishTestAndReset();
-      }
-    });
-  }
-
-  public void testGetEventBus() {
-    assertEquals(eventBus, req.getEventBus());
-  }
-
-  public void testGetListStringId() {
-    delayTestFinish(5000);
-
-    // String ids
-    req.simpleBarRequest().findAll().fire(new Receiver<List<SimpleBarProxy>>() {
-      @Override
-      public void onSuccess(List<SimpleBarProxy> response) {
-        assertEquals(2, response.size());
-        for (SimpleBarProxy bar : response) {
-          assertNotNull(bar.stableId());
-          finishTestAndReset();
-        }
-      }
-    });
-  }
-
-  public void testGetListLongId() {
-    delayTestFinish(5000);
-
-    // Long ids
-    req.simpleFooStringRequest().findAll().with("barField.userName").fire(
-        new Receiver<List<SimpleFooStringProxy>>() {
-          @Override
-          public void onSuccess(List<SimpleFooStringProxy> response) {
-            assertEquals(1, response.size());
-            for (SimpleFooStringProxy foo : response) {
-              assertNotNull(foo.stableId());
-              assertEquals("FOO", foo.getBarField().getUserName());
-              finishTestAndReset();
-            }
-          }
-        });
-  }
-
-  /*
-   * tests that (a) any method can have a side effect that is handled correctly.
-   * (b) instance methods are handled correctly and (c) a request cannot be
-   * reused after a successful response is received. (Yet?)
-   */
-  public void testMethodWithSideEffects() {
-    delayTestFinish(5000);
-
-    final SimpleFooEventHandler<SimpleFooStringProxy> handler = new SimpleFooEventHandler<SimpleFooStringProxy>();
-    EntityProxyChange.registerForProxyType(req.getEventBus(),
-        SimpleFooStringProxy.class, handler);
-
-    req.simpleFooStringRequest().findSimpleFooStringById("999x").fire(
-        new Receiver<SimpleFooStringProxy>() {
-
-          @Override
-          public void onSuccess(SimpleFooStringProxy newFoo) {
-            assertEquals(1, handler.updateEventCount);
-            assertEquals(1, handler.totalEventCount);
-            SimpleFooStringRequest context = req.simpleFooStringRequest();
-            final Request<Long> mutateRequest = context.countSimpleFooWithUserNameSideEffect().using(
-                newFoo);
-            newFoo = context.edit(newFoo);
-            newFoo.setUserName("Ray");
-            mutateRequest.fire(new Receiver<Long>() {
-              @Override
-              public void onSuccess(Long response) {
-                assertCannotFire(mutateRequest);
-                assertEquals(new Long(1L), response);
-                assertEquals(2, handler.updateEventCount);
-                assertEquals(2, handler.totalEventCount);
-
-                // confirm that the instance method did have the desired
-                // sideEffect.
-                req.simpleFooStringRequest().findSimpleFooStringById("999x").fire(
-                    new Receiver<SimpleFooStringProxy>() {
-                      @Override
-                      public void onSuccess(SimpleFooStringProxy finalFoo) {
-                        assertEquals("Ray", finalFoo.getUserName());
-                        assertEquals(2, handler.updateEventCount);
-                        assertEquals(2, handler.totalEventCount);
-                        finishTestAndReset();
-                      }
-                    });
-              }
-
-            });
-
-            try {
-              newFoo.setUserName("Barney");
-              fail();
-            } catch (IllegalStateException e) {
-              /* pass, cannot change a request that is in flight */
-            }
-          }
-        });
-  }
-
-  /*
-   * TODO: all these tests should check the final values. It will be easy when
-   * we have better persistence than the singleton pattern.
-   */
-  public void testPersistExistingEntityExistingRelation() {
-    delayTestFinish(5000);
-
-    req.simpleBarRequest().findSimpleBarById("999L").fire(
-        new Receiver<SimpleBarProxy>() {
-          @Override
-          public void onSuccess(final SimpleBarProxy barProxy) {
-            req.simpleFooStringRequest().findSimpleFooStringById("999x").fire(
-                new Receiver<SimpleFooStringProxy>() {
-                  @Override
-                  public void onSuccess(SimpleFooStringProxy fooProxy) {
-                    SimpleFooStringRequest context = req.simpleFooStringRequest();
-                    Request<Void> updReq = context.persist().using(fooProxy);
-                    fooProxy = context.edit(fooProxy);
-                    fooProxy.setBarField(barProxy);
-                    updReq.fire(new Receiver<Void>() {
-                      @Override
-                      public void onSuccess(Void response) {
-
-                        finishTestAndReset();
-                      }
-                    });
-                  }
-                });
-          }
-        });
-  }
-
-  /*
-   * Find Entity Create Entity2 Relate Entity2 to Entity Persist Entity
-   */
-  public void testPersistExistingEntityNewRelation() {
-    delayTestFinish(5000);
-
-    // Make a new bar
-    SimpleBarRequest context = req.simpleBarRequest();
-    SimpleBarProxy makeABar = context.create(SimpleBarProxy.class);
-    Request<SimpleBarProxy> persistRequest = context.persistAndReturnSelf().using(
-        makeABar);
-    makeABar = context.edit(makeABar);
-    makeABar.setUserName("Amit");
-
-    persistRequest.fire(new Receiver<SimpleBarProxy>() {
-      @Override
-      public void onSuccess(final SimpleBarProxy persistedBar) {
-
-        // It was made, now find a foo to assign it to
-        req.simpleFooStringRequest().findSimpleFooStringById("999x").fire(
-            new Receiver<SimpleFooStringProxy>() {
-              @Override
-              public void onSuccess(SimpleFooStringProxy response) {
-
-                // Found the foo, edit it
-                SimpleFooStringRequest context = req.simpleFooStringRequest();
-                Request<Void> fooReq = context.persist().using(response);
-                response = context.edit(response);
-                response.setBarField(persistedBar);
-                fooReq.fire(new Receiver<Void>() {
-                  @Override
-                  public void onSuccess(Void response) {
-
-                    // Foo was persisted, fetch it again check the goods
-                    req.simpleFooStringRequest().findSimpleFooStringById("999x").with(
-                        "barField.userName").fire(
-                        new Receiver<SimpleFooStringProxy>() {
-
-                          // Here it is
-                          @Override
-                          public void onSuccess(
-                              SimpleFooStringProxy finalFooProxy) {
-                            assertEquals("Amit",
-                                finalFooProxy.getBarField().getUserName());
-                            finishTestAndReset();
-                          }
-                        });
-                  }
-                });
-              }
-            });
-      }
-    });
-  }
-
-  /*
-   * Find Entity2 Create Entity, Persist Entity Relate Entity2 to Entity Persist
-   * Entity
-   */
-  public void testPersistNewEntityExistingRelation() {
-    delayTestFinish(5000);
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    SimpleFooStringProxy newFoo = context.create(SimpleFooStringProxy.class);
-    final Request<Void> fooReq = context.persist().using(newFoo);
-
-    newFoo = context.edit(newFoo);
-    newFoo.setUserName("Ray");
-
-    final SimpleFooStringProxy finalFoo = newFoo;
-    req.simpleBarRequest().findSimpleBarById("999L").fire(
-        new Receiver<SimpleBarProxy>() {
-          @Override
-          public void onSuccess(SimpleBarProxy response) {
-            finalFoo.setBarField(response);
-            fooReq.fire(new Receiver<Void>() {
-              @Override
-              public void onSuccess(Void response) {
-                req.simpleFooStringRequest().findSimpleFooStringById("999x").fire(
-                    new Receiver<SimpleFooStringProxy>() {
-                      @Override
-                      public void onSuccess(SimpleFooStringProxy finalFooProxy) {
-                        // newFoo hasn't been persisted, so userName is the old
-                        // value.
-                        assertEquals("GWT", finalFooProxy.getUserName());
-                        finishTestAndReset();
-                      }
-                    });
-              }
-            });
-          }
-        });
-  }
-
-  /*
-   * Create Entity, Persist Entity Create Entity2, Perist Entity2 relate Entity2
-   * to Entity Persist
-   */
-  public void testPersistNewEntityNewRelation() {
-    delayTestFinish(5000);
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    SimpleFooStringProxy newFoo = context.create(SimpleFooStringProxy.class);
-    final Request<SimpleFooStringProxy> fooReq = context.persistAndReturnSelf().using(
-        newFoo);
-
-    newFoo = context.edit(newFoo);
-    newFoo.setUserName("Ray");
-
-    SimpleBarRequest contextBar = req.simpleBarRequest();
-    SimpleBarProxy newBar = contextBar.create(SimpleBarProxy.class);
-    final Request<SimpleBarProxy> barReq = contextBar.persistAndReturnSelf().using(
-        newBar);
-    newBar = contextBar.edit(newBar);
-    newBar.setUserName("Amit");
-
-    fooReq.fire(new Receiver<SimpleFooStringProxy>() {
-      @Override
-      public void onSuccess(final SimpleFooStringProxy persistedFoo) {
-        barReq.fire(new Receiver<SimpleBarProxy>() {
-          @Override
-          public void onSuccess(final SimpleBarProxy persistedBar) {
-            assertEquals("Ray", persistedFoo.getUserName());
-            SimpleFooStringRequest context = req.simpleFooStringRequest();
-            final Request<Void> fooReq2 = context.persist().using(persistedFoo);
-            SimpleFooStringProxy editablePersistedFoo = context.edit(persistedFoo);
-            editablePersistedFoo.setBarField(persistedBar);
-            fooReq2.fire(new Receiver<Void>() {
-              @Override
-              public void onSuccess(Void response) {
-                req.simpleFooStringRequest().findSimpleFooStringById("999x").with(
-                    "barField.userName").fire(
-                    new Receiver<SimpleFooStringProxy>() {
-                      @Override
-                      public void onSuccess(SimpleFooStringProxy finalFooProxy) {
-                        assertEquals("Amit",
-                            finalFooProxy.getBarField().getUserName());
-                        finishTestAndReset();
-                      }
-                    });
-              }
-            });
-          }
-        });
-      }
-    });
-  }
-
-  public void testPersistRecursiveRelation() {
-    delayTestFinish(5000);
-
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    SimpleFooStringProxy rayFoo = context.create(SimpleFooStringProxy.class);
-    final Request<SimpleFooStringProxy> persistRay = context.persistAndReturnSelf().using(
-        rayFoo);
-    rayFoo = context.edit(rayFoo);
-    rayFoo.setUserName("Ray");
-    rayFoo.setFooField(rayFoo);
-    persistRay.fire(new Receiver<SimpleFooStringProxy>() {
-      @Override
-      public void onSuccess(final SimpleFooStringProxy persistedRay) {
-        finishTestAndReset();
-      }
-    });
-  }
-
-  public void testPersistRelation() {
-    delayTestFinish(5000);
-
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    SimpleFooStringProxy rayFoo = context.create(SimpleFooStringProxy.class);
-    final Request<SimpleFooStringProxy> persistRay = context.persistAndReturnSelf().using(
-        rayFoo);
-    rayFoo = context.edit(rayFoo);
-    rayFoo.setUserName("Ray");
-
-    persistRay.fire(new Receiver<SimpleFooStringProxy>() {
-      @Override
-      public void onSuccess(final SimpleFooStringProxy persistedRay) {
-        SimpleBarRequest context = req.simpleBarRequest();
-        SimpleBarProxy amitBar = context.create(SimpleBarProxy.class);
-        final Request<SimpleBarProxy> persistAmit = context.persistAndReturnSelf().using(
-            amitBar);
-        amitBar = context.edit(amitBar);
-        amitBar.setUserName("Amit");
-
-        persistAmit.fire(new Receiver<SimpleBarProxy>() {
-          @Override
-          public void onSuccess(SimpleBarProxy persistedAmit) {
-
-            SimpleFooStringRequest context = req.simpleFooStringRequest();
-            final Request<SimpleFooStringProxy> persistRelationship = context.persistAndReturnSelf().using(
-                persistedRay).with("barField");
-            SimpleFooStringProxy newRec = context.edit(persistedRay);
-            newRec.setBarField(persistedAmit);
-
-            persistRelationship.fire(new Receiver<SimpleFooStringProxy>() {
-              @Override
-              public void onSuccess(SimpleFooStringProxy relatedRay) {
-                assertEquals("Amit", relatedRay.getBarField().getUserName());
-                finishTestAndReset();
-              }
-            });
-          }
-        });
-      }
-    });
-  }
-
-  public void testProxysAsInstanceMethodParams() {
-    delayTestFinish(5000);
-    req.simpleFooStringRequest().findSimpleFooStringById("999x").fire(
-        new Receiver<SimpleFooStringProxy>() {
-          @Override
-          public void onSuccess(SimpleFooStringProxy response) {
-            SimpleFooStringRequest context = req.simpleFooStringRequest();
-            SimpleBarProxy bar = context.create(SimpleBarProxy.class);
-            Request<String> helloReq = context.hello(bar).using(response);
-            bar = context.edit(bar);
-            bar.setUserName("BAR");
-            helloReq.fire(new Receiver<String>() {
-              @Override
-              public void onSuccess(String response) {
-                assertEquals("Greetings BAR from GWT", response);
-                finishTestAndReset();
-              }
-            });
-          }
-        });
-  }
-
-  public void testServerFailure() {
-    delayTestFinish(5000);
-
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    SimpleFooStringProxy newFoo = context.create(SimpleFooStringProxy.class);
-    final Request<SimpleFooStringProxy> persistRequest = context.persistAndReturnSelf().using(
-        newFoo);
-
-    final SimpleFooStringProxy mutableFoo = context.edit(newFoo);
-    mutableFoo.setPleaseCrash(42); // 42 is the crash causing magic number
-
-    persistRequest.fire(new Receiver<SimpleFooStringProxy>() {
-      @Override
-      public void onFailure(ServerFailure error) {
-        assertEquals("Server Error: THIS EXCEPTION IS EXPECTED BY A TEST",
-            error.getMessage());
-        assertEquals("", error.getExceptionType());
-        assertEquals("", error.getStackTraceString());
-
-        // Now show that we can fix the error and try again with the same
-        // request
-
-        mutableFoo.setPleaseCrash(24); // Only 42 crashes
-        persistRequest.fire(new Receiver<SimpleFooStringProxy>() {
-          @Override
-          public void onSuccess(SimpleFooStringProxy response) {
-            finishTestAndReset();
-          }
-        });
-      }
-
-      @Override
-      public void onSuccess(SimpleFooStringProxy response) {
-        fail("Failure expected but onSuccess() was called");
-      }
-
-      @Override
-      public void onViolation(Set<Violation> errors) {
-        fail("Failure expected but onViolation() was called");
-      }
-    });
-  }
-
-  public void testStableId() {
-    delayTestFinish(5000);
-
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    final SimpleFooStringProxy foo = context.create(SimpleFooStringProxy.class);
-    final Object futureId = foo.getId();
-    Request<SimpleFooStringProxy> fooReq = context.persistAndReturnSelf().using(
-        foo);
-
-    final SimpleFooStringProxy newFoo = context.edit(foo);
-    assertEquals(futureId, foo.getId());
-    assertEquals(futureId, newFoo.getId());
-
-    newFoo.setUserName("GWT basic user");
-    fooReq.fire(new Receiver<SimpleFooStringProxy>() {
-
-      @Override
-      public void onSuccess(final SimpleFooStringProxy returned) {
-        assertEquals(futureId, foo.getId());
-        assertEquals(futureId, newFoo.getId());
-
-        checkStableIdEquals(foo, returned);
-        checkStableIdEquals(newFoo, returned);
-
-        SimpleFooStringRequest context = req.simpleFooStringRequest();
-        Request<SimpleFooStringProxy> editRequest = context.persistAndReturnSelf().using(
-            returned);
-        final SimpleFooStringProxy editableFoo = context.edit(returned);
-        editableFoo.setUserName("GWT power user");
-        editRequest.fire(new Receiver<SimpleFooStringProxy>() {
-
-          @Override
-          public void onSuccess(SimpleFooStringProxy returnedAfterEdit) {
-            checkStableIdEquals(editableFoo, returnedAfterEdit);
-            assertEquals(returnedAfterEdit.getId(), returned.getId());
-            finishTestAndReset();
-          }
-        });
-      }
-    });
-  }
-
-  public void testViolationAbsent() {
-    delayTestFinish(5000);
-
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    SimpleFooStringProxy newFoo = context.create(SimpleFooStringProxy.class);
-    final Request<Void> fooReq = context.persist().using(newFoo);
-
-    newFoo = context.edit(newFoo);
-    newFoo.setUserName("Amit"); // will not cause violation.
-
-    fooReq.fire(new Receiver<Void>() {
-      @Override
-      public void onSuccess(Void ignore) {
-        finishTestAndReset();
-      }
-    });
-  }
-
-  public void testViolationsOnCreate() {
-    delayTestFinish(5000);
-
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    SimpleFooStringProxy newFoo = context.create(SimpleFooStringProxy.class);
-    final Request<SimpleFooStringProxy> create = context.persistAndReturnSelf().using(
-        newFoo);
-    new FailFixAndRefire<SimpleFooStringProxy>(newFoo, context, create).doTest();
-  }
-
-  public void testViolationsOnCreateVoidReturn() {
-    delayTestFinish(5000);
-
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    SimpleFooStringProxy newFoo = context.create(SimpleFooStringProxy.class);
-    final Request<Void> create = context.persist().using(newFoo);
-    new FailFixAndRefire<Void>(newFoo, context, create).doVoidTest();
-  }
-
-  public void testViolationsOnEdit() {
-    delayTestFinish(5000);
-
-    fooCreationRequest().fire(new Receiver<SimpleFooStringProxy>() {
-      @Override
-      public void onSuccess(SimpleFooStringProxy returned) {
-        SimpleFooStringRequest context = req.simpleFooStringRequest();
-        Request<SimpleFooStringProxy> editRequest = context.persistAndReturnSelf().using(
-            returned);
-        new FailFixAndRefire<SimpleFooStringProxy>(returned, context,
-            editRequest).doTest();
-      }
-    });
-  }
-
-  public void testViolationsOnEditVoidReturn() {
-    delayTestFinish(5000);
-
-    fooCreationRequest().fire(new Receiver<SimpleFooStringProxy>() {
-      @Override
-      public void onSuccess(SimpleFooStringProxy returned) {
-        SimpleFooStringRequest context = req.simpleFooStringRequest();
-        Request<Void> editRequest = context.persist().using(returned);
-        new FailFixAndRefire<Void>(returned, context, editRequest).doVoidTest();
-      }
-    });
-  }
-
-  private void assertCannotFire(final Request<Long> mutateRequest) {
-    try {
-      mutateRequest.fire(new Receiver<Long>() {
-        @Override
-        public void onSuccess(Long response) {
-          fail("Should not be called");
-        }
-      });
-      fail("Expected IllegalStateException");
-    } catch (IllegalStateException e) {
-      /* cannot reuse a successful request, mores the pity */
-    }
-  }
-
-  private Request<SimpleFooStringProxy> fooCreationRequest() {
-    SimpleFooStringRequest context = req.simpleFooStringRequest();
-    SimpleFooStringProxy originalFoo = context.create(SimpleFooStringProxy.class);
-    final Request<SimpleFooStringProxy> fooReq = context.persistAndReturnSelf().using(
-        originalFoo);
-    originalFoo = context.edit(originalFoo);
-    originalFoo.setUserName("GWT User");
-    return fooReq;
-  }
-}
diff --git a/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java b/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java
index 048745d..642d96a 100644
--- a/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java
+++ b/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java
@@ -15,7 +15,6 @@
  */
 package com.google.gwt.requestfactory.client;
 
-import com.google.gwt.requestfactory.client.impl.SimpleEntityProxyId;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyChange;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
@@ -29,6 +28,7 @@
 import com.google.gwt.requestfactory.shared.SimpleFooProxy;
 import com.google.gwt.requestfactory.shared.SimpleFooRequest;
 import com.google.gwt.requestfactory.shared.Violation;
+import com.google.gwt.requestfactory.shared.impl.SimpleEntityProxyId;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -62,11 +62,11 @@
     @Override
     public void onFailure(ServerFailure error) {
       assertEquals(expectedException, error.getExceptionType());
-      if (expectedException.length() > 0) {
+      if (expectedException != null) {
         assertFalse(error.getStackTraceString().length() == 0);
         assertEquals("THIS EXCEPTION IS EXPECTED BY A TEST", error.getMessage());
       } else {
-        assertEquals("", error.getStackTraceString());
+        assertEquals(null, error.getStackTraceString());
         assertEquals("Server Error: THIS EXCEPTION IS EXPECTED BY A TEST",
             error.getMessage());
       }
@@ -338,7 +338,8 @@
       public void onSuccess(SimpleFooProxy response) {
         assertFalse(((SimpleEntityProxyId<SimpleFooProxy>) response.stableId()).isEphemeral());
         assertEquals(2, handler.persistEventCount); // two bars persisted.
-        assertEquals(2, handler.totalEventCount);
+        assertEquals(2, handler.updateEventCount); // two bars persisted.
+        assertEquals(4, handler.totalEventCount);
         finishTestAndReset();
       }
     });
@@ -924,7 +925,7 @@
    */
   public void testNullValueInIntegerListRequest() {
     delayTestFinish(DELAY_TEST_FINISH);
-    List<Integer> list = Arrays.asList(new Integer[] {1, 2, null});
+    List<Integer> list = Arrays.asList(new Integer[]{1, 2, null});
     final Request<Void> fooReq = req.simpleFooRequest().receiveNullValueInIntegerList(
         list);
     fooReq.fire(new Receiver<Void>() {
@@ -940,7 +941,7 @@
    */
   public void testNullValueInStringListRequest() {
     delayTestFinish(DELAY_TEST_FINISH);
-    List<String> list = Arrays.asList(new String[] {"nonnull", "null", null});
+    List<String> list = Arrays.asList(new String[]{"nonnull", "null", null});
     final Request<Void> fooReq = req.simpleFooRequest().receiveNullValueInStringList(
         list);
     fooReq.fire(new Receiver<Void>() {
@@ -973,7 +974,7 @@
         assertEquals("user name", f.getUserName());
         assertEquals(Byte.valueOf((byte) 100), f.getByteField());
         assertEquals(Short.valueOf((short) 12345), f.getShortField());
-        assertEquals(Float.valueOf(1234.56f), f.getFloatField());
+        assertEquals(0, (int) Math.rint(123456f - 100 * f.getFloatField()));
         assertEquals(Double.valueOf(1.2345), f.getDoubleField());
         assertEquals(Long.valueOf(1234L), f.getLongField());
         assertFalse(f.getBoolField());
@@ -1821,7 +1822,7 @@
     final SimpleFooProxy mutableFoo = context.edit(newFoo);
     // 43 is the crash causing magic number for a checked exception
     mutableFoo.setPleaseCrash(43);
-    persistRequest.fire(new FooReciever(mutableFoo, persistRequest, ""));
+    persistRequest.fire(new FooReciever(mutableFoo, persistRequest, null));
   }
 
   public void testServerFailureRuntimeException() {
@@ -1833,7 +1834,7 @@
     final SimpleFooProxy mutableFoo = context.edit(newFoo);
     // 42 is the crash causing magic number for a runtime exception
     mutableFoo.setPleaseCrash(42);
-    persistRequest.fire(new FooReciever(mutableFoo, persistRequest, ""));
+    persistRequest.fire(new FooReciever(mutableFoo, persistRequest, null));
   }
 
   /**
diff --git a/user/test/com/google/gwt/requestfactory/client/RequestFactoryTestBase.java b/user/test/com/google/gwt/requestfactory/client/RequestFactoryTestBase.java
index 07c780d..c162c63 100644
--- a/user/test/com/google/gwt/requestfactory/client/RequestFactoryTestBase.java
+++ b/user/test/com/google/gwt/requestfactory/client/RequestFactoryTestBase.java
@@ -32,9 +32,6 @@
  */
 public abstract class RequestFactoryTestBase extends GWTTestCase {
 
-  protected SimpleRequestFactory req;
-  protected EventBus eventBus;
-
   /**
    * Class for counting events.
    */
@@ -63,42 +60,13 @@
     }
   }
 
+  protected EventBus eventBus;
+  protected SimpleRequestFactory req;
+
   @Override
   public void gwtSetUp() {
-    eventBus = new SimpleEventBus();
-    req = GWT.create(SimpleRequestFactory.class);
-    req.initialize(eventBus);
-  }
-
-  protected void finishTestAndReset() {
-    final boolean[] reallyDone = {false, false, false};
-    req.simpleFooRequest().reset().fire(new Receiver<Void>() {
-      @Override
-      public void onSuccess(Void response) {
-        reallyDone[0] = true;
-        if (reallyDone[0] && reallyDone[1] && reallyDone[2]) {
-          finishTest();
-        }
-      }
-    });
-    req.simpleFooStringRequest().reset().fire(new Receiver<Void>() {
-      @Override
-      public void onSuccess(Void response) {
-        reallyDone[1] = true;
-        if (reallyDone[0] && reallyDone[1] && reallyDone[2]) {
-          finishTest();
-        }
-      }
-    });
-    req.simpleBarRequest().reset().fire(new Receiver<Void>() {
-      @Override
-      public void onSuccess(Void response) {
-        reallyDone[2] = true;
-        if (reallyDone[0] && reallyDone[1] && reallyDone[2]) {
-          finishTest();
-        }
-      }
-    });
+    req = createFactory();
+    eventBus = req.getEventBus();
   }
 
   protected void checkStableIdEquals(EntityProxy expected, EntityProxy actual) {
@@ -110,4 +78,35 @@
     assertNotSame(expected, actual);
     assertFalse(expected.equals(actual));
   }
+
+  /**
+   * Create and initialize a new {@link SimpleRequestFactory}.
+   */
+  protected SimpleRequestFactory createFactory() {
+    SimpleRequestFactory toReturn = GWT.create(SimpleRequestFactory.class);
+    toReturn.initialize(new SimpleEventBus());
+    return toReturn;
+  }
+
+  protected void finishTestAndReset() {
+    final boolean[] reallyDone = {false, false};
+    req.simpleFooRequest().reset().fire(new Receiver<Void>() {
+      @Override
+      public void onSuccess(Void response) {
+        reallyDone[0] = true;
+        if (reallyDone[0] && reallyDone[1]) {
+          finishTest();
+        }
+      }
+    });
+    req.simpleBarRequest().reset().fire(new Receiver<Void>() {
+      @Override
+      public void onSuccess(Void response) {
+        reallyDone[1] = true;
+        if (reallyDone[0] && reallyDone[1]) {
+          finishTest();
+        }
+      }
+    });
+  }
 }
diff --git a/user/test/com/google/gwt/requestfactory/server/FindServiceJreTest.java b/user/test/com/google/gwt/requestfactory/server/FindServiceJreTest.java
new file mode 100644
index 0000000..de8028b
--- /dev/null
+++ b/user/test/com/google/gwt/requestfactory/server/FindServiceJreTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server;
+
+import com.google.gwt.requestfactory.client.FindServiceTest;
+import com.google.gwt.requestfactory.shared.SimpleRequestFactory;
+
+/**
+ * Run the FindService tests in-process.
+ */
+public class FindServiceJreTest extends FindServiceTest {
+
+  @Override
+  public String getModuleName() {
+    return null;
+  }
+
+  @Override
+  protected SimpleRequestFactory createFactory() {
+    return RequestFactoryJreTest.createInProcess();
+  }
+}
diff --git a/user/test/com/google/gwt/requestfactory/server/JsonRequestProcessorTest.java b/user/test/com/google/gwt/requestfactory/server/JsonRequestProcessorTest.java
deleted file mode 100644
index 919f897..0000000
--- a/user/test/com/google/gwt/requestfactory/server/JsonRequestProcessorTest.java
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-import com.google.gwt.requestfactory.shared.SimpleBarProxy;
-import com.google.gwt.requestfactory.shared.SimpleEnum;
-import com.google.gwt.requestfactory.shared.SimpleFooProxy;
-import com.google.gwt.requestfactory.shared.WriteOperation;
-import com.google.gwt.requestfactory.shared.impl.Constants;
-
-import junit.framework.TestCase;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.lang.reflect.InvocationTargetException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Tests for {@link JsonRequestProcessor} .
- */
-public class JsonRequestProcessorTest extends TestCase {
-
-  enum Foo {
-    BAR, BAZ
-  }
-
-  private JsonRequestProcessor requestProcessor;
-
-  @Override
-  public void setUp() {
-    requestProcessor = new JsonRequestProcessor();
-    requestProcessor.setOperationRegistry(new ReflectionBasedOperationRegistry(
-        new DefaultSecurityProvider()));
-  }
-
-  public void testDecodeParameterValue() throws SecurityException,
-      JSONException, IllegalAccessException, InvocationTargetException,
-      NoSuchMethodException, InstantiationException {
-    // primitives
-    assertTypeAndValueEquals(String.class, "Hello", "Hello");
-    assertTypeAndValueEquals(Integer.class, 1234, "1234");
-    assertTypeAndValueEquals(Byte.class, (byte) 100, "100");
-    assertTypeAndValueEquals(Short.class, (short) 12345, "12345");
-    assertTypeAndValueEquals(Float.class, 1.234f, "1.234");
-    assertTypeAndValueEquals(Double.class, 1.234567, "1.234567");
-    assertTypeAndValueEquals(Long.class, 1234L, "1234");
-    assertTypeAndValueEquals(Boolean.class, true, "true");
-    assertTypeAndValueEquals(Boolean.class, false, "false");
-
-    // dates
-    Date now = new Date();
-    assertTypeAndValueEquals(Date.class, now, "" + now.getTime());
-    // bigdecimal and biginteger
-    BigDecimal dec = new BigDecimal("10").pow(100);
-    assertTypeAndValueEquals(BigDecimal.class, dec, dec.toPlainString());
-    assertTypeAndValueEquals(BigInteger.class, dec.toBigInteger(),
-        dec.toBigInteger().toString());
-    // enums
-    assertTypeAndValueEquals(Foo.class, Foo.BAR, "" + Foo.BAR.ordinal());
-    
-    // nulls
-    assertTypeAndValueEquals(String.class, null, null);
-    assertTypeAndValueEquals(Integer.class, null, null);
-    assertTypeAndValueEquals(Byte.class, null, null);
-    assertTypeAndValueEquals(Short.class, null, null);
-    assertTypeAndValueEquals(Float.class, null, null);
-    assertTypeAndValueEquals(Double.class, null, null);
-    assertTypeAndValueEquals(Long.class, null, null);
-    assertTypeAndValueEquals(Boolean.class, null, null);
-    assertTypeAndValueEquals(Date.class, null, null);
-    assertTypeAndValueEquals(BigDecimal.class, null, null);
-    assertTypeAndValueEquals(BigInteger.class, null, null);
-    assertTypeAndValueEquals(Foo.class, null, null);
-  }
-
-  public void testEncodePropertyValue() {
-    assertEncodedType(String.class, "Hello");
-    // primitive numbers become doubles
-    assertEncodedType(Double.class, (byte) 10);
-    assertEncodedType(Double.class, (short) 1234);
-    assertEncodedType(Double.class, 123.4f);
-    assertEncodedType(Double.class, 1234.0);
-    assertEncodedType(Double.class, 1234);
-    // longs, big nums become strings
-    assertEncodedType(String.class, 1234L);
-    assertEncodedType(String.class, new BigDecimal(1));
-    assertEncodedType(String.class, new BigInteger("1"));
-    assertEncodedType(String.class, new Date());
-    assertEncodedType(Double.class, Foo.BAR);
-    assertEncodedType(Boolean.class, true);
-    assertEncodedType(Boolean.class, false);
-    // nulls becomes JSON Null. Needed because JSONObject stringify treats 'null'
-    // as a reason to not emit the key in the stringified object
-    assertEquals(JSONObject.NULL, requestProcessor.encodePropertyValue(null));
-    assertEquals(new Double(1.0), requestProcessor.encodePropertyValue(new Integer(1)));
-  }
-
-  public void testEndToEnd() throws Exception {
-    com.google.gwt.requestfactory.server.SimpleFoo.reset();
-    // fetch object
-    JSONObject foo = fetchVerifyAndGetInitialObject();
-
-    // modify fields and sync
-    foo.put("intId", 45);
-    foo.put("userName", "JSC");
-    foo.put("longField", "" + 9L);
-    foo.put("enumField", SimpleEnum.BAR.ordinal());
-    foo.put("boolField", false);
-    Date now = new Date();
-    foo.put("created", "" + now.getTime());
-
-    JSONObject result = getResultFromServer(foo);
-
-    // check modified fields and no violations
-    SimpleFoo fooResult = SimpleFoo.findSimpleFooById(999L);
-    JSONArray updateArray = result.getJSONObject("sideEffects").getJSONArray(
-        "UPDATE");
-    assertEquals(1, updateArray.length());
-    assertEquals(2, updateArray.getJSONObject(0).length());
-    assertTrue(updateArray.getJSONObject(0).has(Constants.ENCODED_ID_PROPERTY));
-    assertTrue(updateArray.getJSONObject(0).has(Constants.ENCODED_VERSION_PROPERTY));
-    assertFalse(updateArray.getJSONObject(0).has("violations"));
-    assertEquals(45, (int) fooResult.getIntId());
-    assertEquals("JSC", fooResult.getUserName());
-    assertEquals(now, fooResult.getCreated());
-    assertEquals(9L, (long) fooResult.getLongField());
-    assertEquals(com.google.gwt.requestfactory.shared.SimpleEnum.BAR,
-        fooResult.getEnumField());
-    assertEquals(false, (boolean) fooResult.getBoolField());
-  }
-
-  private String createNoChangeRequestAndGetServerVersion(JSONObject foo) throws Exception {
-    // change the value on the server behind the back
-    SimpleFoo fooResult = SimpleFoo.findSimpleFooById(999L);
-    fooResult.setUserName("JSC");
-    fooResult.setIntId(45);
-    String savedVersion = requestProcessor.encodePropertyValue(fooResult.getVersion() + 1).toString();
-    fooResult.setVersion(fooResult.getVersion() + 1);
-    fooResult.isChanged = false;
-
-    // modify fields and sync -- there should be no change on the server.
-    foo.put("intId", 45);
-    foo.put("userName", "JSC");
-    return savedVersion;
-  }
-
-  public void testEndToEndSmartDiff_NoChange() throws Exception {
-    com.google.gwt.requestfactory.server.SimpleFoo.reset();
-    // fetch object
-    JSONObject foo = fetchVerifyAndGetInitialObject();
-
-    String savedVersion = createNoChangeRequestAndGetServerVersion(foo);
-    JSONObject result = getResultFromServer(foo);
-
-    // check modified fields and no violations
-    assertTrue(result.getJSONObject("sideEffects").has("UPDATE"));
-    JSONArray updateArray = result.getJSONObject("sideEffects").getJSONArray(
-        "UPDATE");
-    // verify that the version number is unchanged.
-    assertEquals(1, updateArray.length());
-    assertEquals(2, updateArray.getJSONObject(0).length());
-    assertTrue(updateArray.getJSONObject(0).has(Constants.ENCODED_ID_PROPERTY));
-    assertTrue(updateArray.getJSONObject(0).has(
-        Constants.ENCODED_VERSION_PROPERTY));
-    assertEquals(savedVersion,
-        updateArray.getJSONObject(0).getString(
-            Constants.ENCODED_VERSION_PROPERTY));
-    // verify that the server values are unchanged.
-    SimpleFoo fooResult = SimpleFoo.findSimpleFooById(999L);
-    assertEquals(45, (int) fooResult.getIntId());
-    assertEquals("JSC", fooResult.getUserName());
-    assertEquals(savedVersion,
-        requestProcessor.encodePropertyValue(fooResult.getVersion()).toString());
-  }
-
-  /*
-   * This test differs from testEndToEndSmartDiff_NoChange in that the version
-   * numbers are not sent. As a result, the server does not send an UPDATE
-   * sideEffect in its response.
-   */
-  public void testEndToEndSmartDiff_NoChange_NoVersion() throws Exception {
-    com.google.gwt.requestfactory.server.SimpleFoo.reset();
-    // fetch object
-    JSONObject foo = fetchVerifyAndGetInitialObject();
-
-    String savedVersion = createNoChangeRequestAndGetServerVersion(foo);
-    // remove version number from the request.
-    foo.remove(Constants.ENCODED_VERSION_PROPERTY);
-    JSONObject result = getResultFromServer(foo);
-
-    // check modified fields and no violations
-    assertFalse(result.getJSONObject("sideEffects").has("UPDATE"));
-
-    // verify that the server values are unchanged.
-    SimpleFoo fooResult = SimpleFoo.findSimpleFooById(999L);
-    assertEquals(45, (int) fooResult.getIntId());
-    assertEquals("JSC", fooResult.getUserName());
-    assertEquals(savedVersion,
-        requestProcessor.encodePropertyValue(fooResult.getVersion()).toString());
-  }
-
-  /*
-   * This test differs from testEndToEndSmartDiff_NoChange in that the property
-   * that is changed here does not cause a version increment. As a result, no
-   * UPDATE is sent back.
-   */
-  public void testEndToEndSmartDiff_NoVersionChange() throws Exception {
-    com.google.gwt.requestfactory.server.SimpleFoo.reset();
-    // fetch object
-    JSONObject foo = fetchVerifyAndGetInitialObject();
-    // change the value on the server behind the back
-    SimpleFoo fooResult = SimpleFoo.findSimpleFooById(999L);
-    fooResult.setLongField(45L);
-    String savedVersion = requestProcessor.encodePropertyValue(fooResult.getVersion()).toString();
-    
-    // modify fields and sync -- there should be no change on the server.
-    foo.put("longField", 45L);
-    JSONObject result = getResultFromServer(foo);
-
-    // check modified fields and no violations
-    assertFalse(result.getJSONObject("sideEffects").has("UPDATE"));
-
-    // verify that the server values are unchanged.
-    fooResult = SimpleFoo.findSimpleFooById(999L);
-    assertEquals(45L, (long) fooResult.getLongField());
-    assertEquals(savedVersion,
-        requestProcessor.encodePropertyValue(fooResult.getVersion()).toString());
-  }
-
-  public void testEndToEndSmartDiff_SomeChangeWithNull() throws Exception {
-    com.google.gwt.requestfactory.server.SimpleFoo.reset();
-    // fetch object
-    JSONObject foo = fetchVerifyAndGetInitialObject();
-
-    // change some fields but don't change other fields.
-    SimpleFoo fooResult = SimpleFoo.findSimpleFooById(999L);
-    fooResult.setUserName("JSC");
-    fooResult.setIntId(45);
-    fooResult.setNullField(null);
-    fooResult.setBarField(SimpleBar.getSingleton());
-    fooResult.setBarNullField(null);
-    foo.put("userName", JSONObject.NULL);
-    foo.put("intId", 45);
-    foo.put("nullField", "test");
-    foo.put("barNullField",
-        JsonRequestProcessor.base64Encode(SimpleBar.getSingleton().getId())
-            + "@NO@" + SimpleBarProxy.class.getName());
-    foo.put("barField", JSONObject.NULL);
-
-    JSONObject result = getResultFromServer(foo);
-
-    // check modified fields and no violations
-    assertTrue(result.getJSONObject("sideEffects").has("UPDATE"));
-    fooResult = SimpleFoo.findSimpleFooById(999L);
-    assertEquals(45, (int) fooResult.getIntId());
-    assertNull(fooResult.getUserName());
-    assertEquals("test", fooResult.getNullField());
-    assertEquals(SimpleBar.getSingleton(), fooResult.getBarNullField());
-    assertNull(fooResult.getBarField());
-  }
-
-  public void testEndToEndSmartDiff_SomeChange() throws Exception {
-    com.google.gwt.requestfactory.server.SimpleFoo.reset();
-    // fetch object
-    JSONObject foo = fetchVerifyAndGetInitialObject();
-
-    // change some fields but don't change other fields.
-    SimpleFoo fooResult = SimpleFoo.findSimpleFooById(999L);
-    fooResult.setUserName("JSC");
-    fooResult.setIntId(45);
-    foo.put("userName", "JSC");
-    foo.put("intId", 45);
-    Date now = new Date();
-    long newTime = now.getTime() + 10000;
-    foo.put("created", "" + newTime);
-
-    JSONObject result = getResultFromServer(foo);
-
-    // check modified fields and no violations
-    assertTrue(result.getJSONObject("sideEffects").has("UPDATE"));
-    fooResult = SimpleFoo.findSimpleFooById(999L);
-    assertEquals(45, (int) fooResult.getIntId());
-    assertEquals("JSC", fooResult.getUserName());
-    assertEquals(newTime, fooResult.getCreated().getTime());
-  }
-
-  public void testEndToEndNumberList()
-      throws ClassNotFoundException, InvocationTargetException,
-      NoSuchMethodException, JSONException, InstantiationException,
-      IllegalAccessException {
-    fetchVerifyAndGetNumberList();
-  }
-  
-  private void assertEncodedType(Class<?> expected, Object value) {
-    assertEquals(expected,
-        requestProcessor.encodePropertyValue(value).getClass());
-  }
-
-  private <T> void assertTypeAndValueEquals(Class<T> expectedType,
-      T expectedValue, String paramValue) throws SecurityException,
-      JSONException, IllegalAccessException, InvocationTargetException,
-      NoSuchMethodException, InstantiationException {
-    Object val = requestProcessor.decodeParameterValue(expectedType, paramValue);
-    if (val != null) {
-      assertEquals(expectedType, val.getClass());
-    }
-    assertEquals(expectedValue, val);
-  }
-
-  @SuppressWarnings("unchecked")
-  private JSONObject fetchVerifyAndGetInitialObject() throws JSONException,
-      NoSuchMethodException, IllegalAccessException, InvocationTargetException,
-      ClassNotFoundException, SecurityException, InstantiationException {
-    JSONObject results = requestProcessor.processJsonRequest("{ \""
-        + Constants.OPERATION_TOKEN
-        + "\": \""
-        + com.google.gwt.requestfactory.shared.SimpleFooRequest.class.getName()
-        + ReflectionBasedOperationRegistry.SCOPE_SEPARATOR
-        + "findSimpleFooById\", "
-        + "\""
-        + Constants.PARAM_TOKEN
-        + "0\": \"999\", \"" + Constants.PROPERTY_REF_TOKEN  + "\": "
-        + "\"oneToManyField,oneToManySetField,selfOneToManyField\""
-        + "}");
-    JSONObject foo = results.getJSONObject("result");
-    assertEquals(foo.getLong("id"), 999L);
-    assertEquals(foo.getInt("intId"), 42);
-    assertEquals(foo.getString("userName"), "GWT");
-    assertEquals(foo.getLong("longField"), 8L);
-    assertEquals(foo.getInt("enumField"), 0);
-    assertEquals(foo.getInt(Constants.ENCODED_VERSION_PROPERTY), 1);
-    assertEquals(foo.getBoolean("boolField"), true);
-    assertNotNull(foo.getString("!id"));
-    assertTrue(foo.has("created"));
-    List<Double> numList = (List<Double>) foo.get("numberListField");
-    assertEquals(2, numList.size());
-    assertEquals(42.0, numList.get(0));
-    assertEquals(99.0, numList.get(1));
-
-    List<String> oneToMany = (List<String>) foo.get("oneToManyField");
-    assertEquals(2, oneToMany.size());
-    assertEquals(JsonRequestProcessor.base64Encode("1L") + "@NO@com.google.gwt.requestfactory.shared.SimpleBarProxy", oneToMany.get(0));
-    assertEquals(JsonRequestProcessor.base64Encode("1L") + "@NO@com.google.gwt.requestfactory.shared.SimpleBarProxy", oneToMany.get(1));
-
-    List<String> selfOneToMany = (List<String>) foo.get("selfOneToManyField");
-    assertEquals(1, selfOneToMany.size());
-    assertEquals("999@NO@com.google.gwt.requestfactory.shared.SimpleFooProxy", selfOneToMany.get(0));
-
-    Set<String> oneToManySet = (Set<String>) foo.get("oneToManySetField");
-    assertEquals(1, oneToManySet.size());
-    assertEquals(JsonRequestProcessor.base64Encode("1L") + "@NO@com.google.gwt.requestfactory.shared.SimpleBarProxy", oneToManySet.iterator().next());
-    return foo;
-  }
-
-   private JSONArray fetchVerifyAndGetNumberList() throws JSONException,
-      NoSuchMethodException, IllegalAccessException, InvocationTargetException,
-      ClassNotFoundException, SecurityException, InstantiationException {
-    JSONObject results = requestProcessor.processJsonRequest("{ \""
-        + Constants.OPERATION_TOKEN
-        + "\": \""
-        + com.google.gwt.requestfactory.shared.SimpleFooRequest.class.getName()
-        + ReflectionBasedOperationRegistry.SCOPE_SEPARATOR
-        + "getNumberList\" }");
-    JSONArray foo = results.getJSONArray("result");
-    assertEquals(foo.length(), 3);
-    assertEquals(foo.getInt(0), 1);
-    assertEquals(foo.getInt(1), 2);
-    assertEquals(foo.getInt(2), 3);     
-    return foo;
-  }
-
-  public void testPrimitiveListAsParameter() throws JSONException,
-      NoSuchMethodException, IllegalAccessException, InvocationTargetException,
-      ClassNotFoundException, SecurityException, InstantiationException {
-
-    JSONObject results = requestProcessor.processJsonRequest("{ \""
-        + Constants.OPERATION_TOKEN
-        + "\": \""
-        + com.google.gwt.requestfactory.shared.SimpleFooRequest.class.getName()
-        + ReflectionBasedOperationRegistry.SCOPE_SEPARATOR
-        + "sum\", "
-        + "\"" + Constants.PARAM_TOKEN + "0\":"
-        + "\"1@NO@com.google.gwt.requestfactory.shared.SimpleFooProxy\","
-        + "\""
-        + Constants.PARAM_TOKEN
-        + "1\": [1, 2, 3] }");
-    assertEquals(6, results.getInt("result"));
-  }
-
-  public void testProxyListAsParameter() throws JSONException,
-        NoSuchMethodException, IllegalAccessException, InvocationTargetException,
-        ClassNotFoundException, SecurityException, InstantiationException {
-      SimpleFoo.reset();
-      JSONObject results = requestProcessor.processJsonRequest("{ \""
-          + Constants.OPERATION_TOKEN
-          + "\": \""
-          + com.google.gwt.requestfactory.shared.SimpleFooRequest.class.getName()
-          + ReflectionBasedOperationRegistry.SCOPE_SEPARATOR
-          + "processList\", "
-          + "\"" + Constants.PARAM_TOKEN + "0\":"
-          + "\"1@NO@com.google.gwt.requestfactory.shared.SimpleFooProxy\","
-          + "\""
-          + Constants.PARAM_TOKEN
-          + "1\": [\"1@NO@com.google.gwt.requestfactory.shared.SimpleFooProxy\", \"1@NO@com.google.gwt.requestfactory.shared.SimpleFooProxy\", \"1@NO@com.google.gwt.requestfactory.shared.SimpleFooProxy\"] }");
-      assertEquals("GWTGWTGWT", results.getString("result"));
-    }
-
-  private JSONObject getResultFromServer(JSONObject foo) throws JSONException,
-      NoSuchMethodException, IllegalAccessException, InvocationTargetException,
-      ClassNotFoundException, SecurityException, InstantiationException {
-    JSONObject proxyWithSchema = new JSONObject();
-    proxyWithSchema.put(SimpleFooProxy.class.getName(), foo);
-    JSONArray arr = new JSONArray();
-    arr.put(proxyWithSchema);
-    JSONObject operation = new JSONObject();
-    operation.put(WriteOperation.UPDATE.toString(), arr);
-    JSONObject sync = new JSONObject();
-    sync.put(Constants.OPERATION_TOKEN,
-        "com.google.gwt.requestfactory.shared.SimpleFooRequest::persist");
-    sync.put(Constants.CONTENT_TOKEN, operation.toString());
-    sync.put(Constants.PARAM_TOKEN + "0", foo.getString("id") + "@NO" + "@"
-        + SimpleFooProxy.class.getName());
-    return requestProcessor.processJsonRequest(sync.toString());
-  }
-}
diff --git a/user/test/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistryTest.java b/user/test/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistryTest.java
deleted file mode 100644
index 5cb7ceb..0000000
--- a/user/test/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistryTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-import com.google.gwt.requestfactory.shared.SimpleBarProxy;
-import com.google.gwt.requestfactory.shared.SimpleFooProxy;
-
-import junit.framework.TestCase;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Tests for
- * {@link com.google.gwt.requestfactory.server.ReflectionBasedOperationRegistry}
- * .
- */
-public class ReflectionBasedOperationRegistryTest extends TestCase {
-
-  private ReflectionBasedOperationRegistry registry;
-
-  @Override
-  public void setUp() {
-    registry = new ReflectionBasedOperationRegistry(
-        new DefaultSecurityProvider());
-  }
-
-  public void testGetOperationListNoArgs() {
-    RequestDefinition request = registry.getOperation("com.google.gwt.requestfactory.shared.SimpleFooRequest::findAll");
-    assert request != null;
-    assertEquals("com.google.gwt.requestfactory.server.SimpleFoo",
-        request.getDomainClassName());
-    assertEquals("findAll", request.getDomainMethod().getName());
-    assertEquals(SimpleFooProxy.class, request.getReturnType());
-    assertEquals(0, request.getParameterTypes().length);
-    assertTrue(List.class.isAssignableFrom(request.getDomainMethod().getReturnType()));
-  }
-
-  public void testGetOperationScalarNoArgs() {
-    RequestDefinition request = registry.getOperation("com.google.gwt.requestfactory.shared.SimpleFooRequest::countSimpleFoo");
-    assert request != null;
-    assertEquals("com.google.gwt.requestfactory.server.SimpleFoo",
-        request.getDomainClassName());
-    assertEquals("countSimpleFoo", request.getDomainMethod().getName());
-    assertEquals(Long.class, request.getReturnType());
-    assertEquals(0, request.getParameterTypes().length);
-    assertFalse(List.class.isAssignableFrom(request.getDomainMethod().getReturnType()));
-  }
-
-  public void testGetOpertionScalarWithArgs() {
-    {
-      RequestDefinition request = registry.getOperation("com.google.gwt.requestfactory.shared.SimpleFooRequest::findSimpleFooById");
-      assertNotNull(request);
-      assertEquals("com.google.gwt.requestfactory.server.SimpleFoo",
-          request.getDomainClassName());
-      assertEquals("findSimpleFooById", request.getDomainMethod().getName());
-      assertEquals(SimpleFooProxy.class, request.getReturnType());
-      assertEquals(1, request.getParameterTypes().length);
-      assertEquals(Long.class, request.getParameterTypes()[0]);
-      assertFalse(List.class.isAssignableFrom(request.getDomainMethod().getReturnType()));
-    }
-    {
-      RequestDefinition request = registry.getOperation("com.google.gwt.requestfactory.shared.SimpleBarRequest::findSimpleBarById");
-      assertNotNull(request);
-      assertEquals("com.google.gwt.requestfactory.server.SimpleBar",
-          request.getDomainClassName());
-      assertEquals("findSimpleBarById", request.getDomainMethod().getName());
-      assertEquals(SimpleBarProxy.class, request.getReturnType());
-      assertEquals(1, request.getParameterTypes().length);
-      assertEquals(String.class, request.getParameterTypes()[0]);
-      assertFalse(List.class.isAssignableFrom(request.getDomainMethod().getReturnType()));
-    }
-  }
-
-  public void testGetOperationSetNoArgs() {
-    RequestDefinition request = registry.getOperation("com.google.gwt.requestfactory.shared.SimpleBarRequest::findAsSet");
-    assert request != null;
-    assertEquals("com.google.gwt.requestfactory.server.SimpleBar",
-        request.getDomainClassName());
-    assertEquals("findAsSet", request.getDomainMethod().getName());
-    assertEquals(SimpleBarProxy.class, request.getReturnType());
-    assertEquals(0, request.getParameterTypes().length);
-    assertTrue(Set.class.isAssignableFrom(request.getDomainMethod().getReturnType()));
-  }
-
-  public void testInsecureOperations() {
-    try {
-      // bogus class
-      registry.getOperation("com.foo.Foo::bar");
-      fail("Access to non-existent class.");
-    } catch (SecurityException se) {
-      // expected
-    }
-    try {
-      // no @Service
-      registry.getOperation("java.lang.System::currentTimeMillis");
-      fail("Access allowed to class without @Service annotation");
-    } catch (SecurityException se) {
-      // expected
-    }
-  }
-
-  public void testPrivateMethodFails() {
-    RequestDefinition request = registry.getOperation("com.google.gwt.requestfactory.shared.SimpleFooRequest::privateMethod");
-    assert request == null;
-  }
-}
diff --git a/user/test/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidatorTest.java b/user/test/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidatorTest.java
index 75b4f50..24739f7 100644
--- a/user/test/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidatorTest.java
+++ b/user/test/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidatorTest.java
@@ -24,6 +24,7 @@
 import com.google.gwt.requestfactory.shared.RequestFactory;
 import com.google.gwt.requestfactory.shared.Service;
 import com.google.gwt.requestfactory.shared.SimpleRequestFactory;
+import com.google.gwt.requestfactory.shared.impl.FindRequest;
 
 import junit.framework.TestCase;
 
@@ -144,6 +145,26 @@
   RequestFactoryInterfaceValidator v;
 
   /**
+   * 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());
+  }
+
+  /**
+   * Test the {@link FindRequest} context used to implement find().
+   */
+  public void testFindRequestContext() {
+    v.validateRequestContext(FindRequest.class.getName());
+  }
+
+  /**
    * Ensure that the &lt;clinit> methods don't interfere with validation.
    */
   public void testIntecfacesWithClinits() {
diff --git a/user/test/com/google/gwt/requestfactory/server/RequestFactoryJreTest.java b/user/test/com/google/gwt/requestfactory/server/RequestFactoryJreTest.java
new file mode 100644
index 0000000..d0d69b1
--- /dev/null
+++ b/user/test/com/google/gwt/requestfactory/server/RequestFactoryJreTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server;
+
+import com.google.gwt.event.shared.EventBus;
+import com.google.gwt.event.shared.SimpleEventBus;
+import com.google.gwt.requestfactory.client.RequestFactoryTest;
+import com.google.gwt.requestfactory.server.SimpleRequestProcessor.ServiceLayer;
+import com.google.gwt.requestfactory.server.testing.InProcessRequestTransport;
+import com.google.gwt.requestfactory.server.testing.RequestFactoryMagic;
+import com.google.gwt.requestfactory.shared.SimpleRequestFactory;
+
+/**
+ * Runs the RequestFactory tests in-process.
+ */
+public class RequestFactoryJreTest extends RequestFactoryTest {
+
+  public static SimpleRequestFactory createInProcess() {
+    EventBus eventBus = new SimpleEventBus();
+    SimpleRequestFactory req = RequestFactoryMagic.create(SimpleRequestFactory.class);
+    ServiceLayer serviceLayer = new ReflectiveServiceLayer();
+    SimpleRequestProcessor processor = new SimpleRequestProcessor(serviceLayer);
+    req.initialize(eventBus, new InProcessRequestTransport(processor));
+    return req;
+  }
+
+  @Override
+  public String getModuleName() {
+    return null;
+  }
+
+  @Override
+  protected SimpleRequestFactory createFactory() {
+    return createInProcess();
+  }
+}
diff --git a/user/test/com/google/gwt/requestfactory/server/RequestPropertyTest.java b/user/test/com/google/gwt/requestfactory/server/RequestPropertyTest.java
deleted file mode 100644
index 17cc049..0000000
--- a/user/test/com/google/gwt/requestfactory/server/RequestPropertyTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@link com.google.gwt.requestfactory.server.RequestProperty} .
- */
-public class RequestPropertyTest extends TestCase {
-
-  public void testParseMultipleSelector() {
-    RequestProperty prop = RequestProperty.parse("supervisor.name, supervisor.age");
-    RequestProperty sup = prop.getProperty("supervisor");
-    assertNotNull(sup);
-    RequestProperty name = sup.getProperty("name");
-    assertNotNull(name);
-    RequestProperty age = sup.getProperty("age");
-    assertNotNull(age);
-  }
-  public void testParseSingleSelector() {
-    RequestProperty prop = RequestProperty.parse("supervisor.name");
-    RequestProperty sup = prop.getProperty("supervisor");
-    assertNotNull(sup);
-    RequestProperty name = sup.getProperty("name");
-    assertNotNull(name);
-  }
-}
\ No newline at end of file
diff --git a/user/test/com/google/gwt/requestfactory/server/SimpleBar.java b/user/test/com/google/gwt/requestfactory/server/SimpleBar.java
index 80495e9..d75ff3b 100644
--- a/user/test/com/google/gwt/requestfactory/server/SimpleBar.java
+++ b/user/test/com/google/gwt/requestfactory/server/SimpleBar.java
@@ -16,7 +16,6 @@
 package com.google.gwt.requestfactory.server;
 
 import com.google.gwt.dev.util.collect.HashSet;
-import com.google.gwt.requestfactory.shared.Id;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -124,7 +123,6 @@
 
   Integer version = 1;
 
-  @Id
   private String id = "999L";
   private boolean findFails;
   private boolean isNew = true;
diff --git a/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java b/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java
index 6c53ac3..417aef2 100644
--- a/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java
+++ b/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java
@@ -15,7 +15,6 @@
  */
 package com.google.gwt.requestfactory.server;
 
-import com.google.gwt.requestfactory.shared.Id;
 import com.google.gwt.requestfactory.shared.SimpleEnum;
 
 import java.math.BigDecimal;
@@ -39,7 +38,7 @@
   /**
    * DO NOT USE THIS UGLY HACK DIRECTLY! Call {@link #get} instead.
    */
-  private static Map<Long, SimpleFoo> jreTestSingleton = new HashMap<Long, SimpleFoo>();
+  private static Map<Long, SimpleFoo> jreTestSingleton;
 
   private static Long nextId = 1L;
 
@@ -87,6 +86,9 @@
     HttpServletRequest req = RequestFactoryServlet.getThreadLocalRequest();
     if (req == null) {
       // May be in a JRE test case, use the singleton
+      if (jreTestSingleton == null) {
+        jreTestSingleton = resetImpl();
+      }
       return jreTestSingleton;
     } else {
       /*
@@ -278,7 +280,6 @@
 
   Integer version = 1;
 
-  @Id
   private Long id = 1L;
   private boolean isNew = true;
 
diff --git a/user/test/com/google/gwt/requestfactory/server/SimpleFooString.java b/user/test/com/google/gwt/requestfactory/server/SimpleFooString.java
deleted file mode 100644
index aaa4870..0000000
--- a/user/test/com/google/gwt/requestfactory/server/SimpleFooString.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.server;
-
-import com.google.gwt.requestfactory.shared.Id;
-import com.google.gwt.requestfactory.shared.SimpleEnum;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.validation.constraints.Size;
-
-/**
- * Domain object for SimpleFooStringRequest. Ugly copy of SimpleFoo, just
- * changes id to String.
- */
-public class SimpleFooString {
-  /**
-   * DO NOT USE THIS UGLY HACK DIRECTLY! Call {@link #get} instead.
-   */
-  private static SimpleFooString jreTestSingleton = new SimpleFooString();
-
-  private static Long nextId = 1L;
-
-  public static Long countSimpleFoo() {
-    return 1L;
-  }
-
-  public static List<SimpleFooString> findAll() {
-    return Collections.singletonList(get());
-  }
-
-    public static SimpleFooString findSimpleFooString(String id) {
-    return findSimpleFooStringById(id);
-  }
-
-  public static SimpleFooString findSimpleFooStringById(String id) {
-    get().setId(id);
-    return get();
-  }
-
-  public static synchronized SimpleFooString get() {
-    HttpServletRequest req = RequestFactoryServlet.getThreadLocalRequest();
-    if (req == null) {
-      // May be in a JRE test case, use the singleton
-      return jreTestSingleton;
-    } else {
-      /*
-       * This will not behave entirely correctly unless we have a servlet filter
-       * that doesn't allow any requests to be processed unless they're
-       * associated with an existing session.
-       */
-      SimpleFooString value = (SimpleFooString) req.getSession().getAttribute(
-          SimpleFooString.class.getCanonicalName());
-      if (value == null) {
-        value = resetImpl();
-      }
-      return value;
-    }
-  }
-
-  public static List<Integer> getNumberList() {
-    ArrayList<Integer> list = new ArrayList<Integer>();
-    list.add(1);
-    list.add(2);
-    list.add(3);
-    return list;
-  }
-
-  public static Set<Integer> getNumberSet() {
-    Set<Integer> list = new HashSet<Integer>();
-    list.add(1);
-    list.add(2);
-    list.add(3);
-    return list;
-  }
-
-  public static SimpleFooString getSingleton() {
-    return get();
-  }
-
-  public static void reset() {
-    resetImpl();
-  }
-
-  public static synchronized SimpleFooString resetImpl() {
-    SimpleFooString instance = new SimpleFooString();
-    HttpServletRequest req = RequestFactoryServlet.getThreadLocalRequest();
-    if (req == null) {
-      jreTestSingleton = instance;
-    } else {
-      req.getSession().setAttribute(SimpleFooString.class.getCanonicalName(),
-          instance);
-    }
-    return instance;
-  }
-
-  @SuppressWarnings("unused")
-  private static Integer privateMethod() {
-    return 0;
-  }
-
-  Integer version = 1;
-
-  @Id
-  private String id = "1x";
-
-  @Size(min = 3, max = 30)
-  private String userName;
-  private String password;
-
-  private Character charField;
-  private Long longField;
-
-  private BigDecimal bigDecimalField;
-
-  private BigInteger bigIntField;
-  private Integer intId = -1;
-  private Short shortField;
-
-  private Byte byteField;
-
-  private Date created;
-  private Double doubleField;
-
-  private Float floatField;
-
-  private SimpleEnum enumField;
-  private Boolean boolField;
-
-  private Boolean otherBoolField;
-  private Integer pleaseCrash;
-
-  private SimpleBar barField;
-  private SimpleFooString fooField;
-
-  private String nullField;
-  private SimpleBar barNullField;
-
-  private List<SimpleBar> oneToManyField;
-  private List<SimpleFooString> selfOneToManyField;
-  private Set<SimpleBar> oneToManySetField;
-
-  private List<Integer> numberListField;
-
-  public SimpleFooString() {
-    intId = 42;
-    version = 1;
-    userName = "GWT";
-    longField = 8L;
-    enumField = SimpleEnum.FOO;
-    created = new Date();
-    barField = SimpleBar.getSingleton();
-    boolField = true;
-    oneToManyField = new ArrayList<SimpleBar>();
-    oneToManyField.add(barField);
-    oneToManyField.add(barField);
-    numberListField = new ArrayList<Integer>();
-    numberListField.add(42);
-    numberListField.add(99);
-    selfOneToManyField = new ArrayList<SimpleFooString>();
-    selfOneToManyField.add(this);
-    oneToManySetField = new HashSet<SimpleBar>();
-    oneToManySetField.add(barField);
-    nullField = null;
-    barNullField = null;
-    pleaseCrash = 0;
-  }
-
-  public Long countSimpleFooWithUserNameSideEffect() {
-    get().setUserName(userName);
-    version++;
-    return 1L;
-  }
-
-  public SimpleBar getBarField() {
-    return barField;
-  }
-
-  public SimpleBar getBarNullField() {
-    return barNullField;
-  }
-
-  /**
-   * Returns the bigDecimalField.
-   */
-  public BigDecimal getBigDecimalField() {
-    return bigDecimalField;
-  }
-
-  /**
-   * Returns the bigIntegerField.
-   */
-  public BigInteger getBigIntField() {
-    return bigIntField;
-  }
-
-  public Boolean getBoolField() {
-    return boolField;
-  }
-
-  /**
-   * Returns the byteField.
-   */
-  public Byte getByteField() {
-    return byteField;
-  }
-
-  /**
-   * Returns the charField.
-   */
-  public Character getCharField() {
-    return charField;
-  }
-
-  public Date getCreated() {
-    return created;
-  }
-
-  /**
-   * Returns the doubleField.
-   */
-  public Double getDoubleField() {
-    return doubleField;
-  }
-
-  public SimpleEnum getEnumField() {
-    return enumField;
-  }
-
-  /**
-   * Returns the floatField.
-   */
-  public Float getFloatField() {
-    return floatField;
-  }
-
-  public SimpleFooString getFooField() {
-    return fooField;
-  }
-
-  public String getId() {
-    return id;
-  }
-
-  public Integer getIntId() {
-    return intId;
-  }
-
-  public Long getLongField() {
-    return longField;
-  }
-
-  public List<Integer> getNumberListField() {
-    return numberListField;
-  }
-
-  public List<SimpleBar> getOneToManyField() {
-    return oneToManyField;
-  }
-
-  public Set<SimpleBar> getOneToManySetField() {
-    return oneToManySetField;
-  }
-
-  public String getNullField() {
-    return nullField;
-  }
-
-  /**
-   * Returns the otherBoolField.
-   */
-  public Boolean getOtherBoolField() {
-    return otherBoolField;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  public Integer getPleaseCrash() {
-    return pleaseCrash;
-  }
-
-  public List<SimpleFooString> getSelfOneToManyField() {
-    return selfOneToManyField;
-  }
-
-  /**
-   * Returns the shortField.
-   */
-  public Short getShortField() {
-    return shortField;
-  }
-
-  public String getUserName() {
-    return userName;
-  }
-
-  public Integer getVersion() {
-    return version;
-  }
-
-  public String hello(SimpleBar bar) {
-    return "Greetings " + bar.getUserName() + " from " + getUserName();
-  }
-
-  public void persist() {
-    setId(nextId++ + "x");
-    version++;
-  }
-
-  public SimpleFooString persistAndReturnSelf() {
-    persist();
-    return this;
-  }
-
-  public String processList(List<SimpleFooString> values) {
-    String result = "";
-    for (SimpleFooString n : values) {
-      result += n.getUserName();
-    }
-    return result;
-  }
-
-  public void setBarField(SimpleBar barField) {
-    this.barField = barField;
-  }
-
-  public void setBarNullField(SimpleBar barNullField) {
-    this.barNullField = barNullField;
-  }
-
-  /**
-   * @param bigDecimalField the bigDecimalField to set
-   */
-  public void setBigDecimalField(BigDecimal bigDecimalField) {
-    this.bigDecimalField = bigDecimalField;
-  }
-
-  /**
-   * @param bigIntegerField the bigIntegerField to set
-   */
-  public void setBigIntField(BigInteger bigIntegerField) {
-    this.bigIntField = bigIntegerField;
-  }
-
-  public void setBoolField(Boolean bool) {
-    boolField = bool;
-  }
-
-  /**
-   * @param byteField the byteField to set
-   */
-  public void setByteField(Byte byteField) {
-    this.byteField = byteField;
-  }
-
-  /**
-   * @param charField the charField to set
-   */
-  public void setCharField(Character charField) {
-    this.charField = charField;
-  }
-
-  public void setCreated(Date created) {
-    this.created = created;
-  }
-
-  /**
-   * @param doubleField the doubleField to set
-   */
-  public void setDoubleField(Double doubleField) {
-    this.doubleField = doubleField;
-  }
-
-  public void setEnumField(SimpleEnum enumField) {
-    this.enumField = enumField;
-  }
-
-  /**
-   * @param floatField the floatField to set
-   */
-  public void setFloatField(Float floatField) {
-    this.floatField = floatField;
-  }
-
-  public void setFooField(SimpleFooString fooField) {
-    this.fooField = fooField;
-  }
-
-  public void setId(String id) {
-    this.id = id;
-  }
-
-  public void setIntId(Integer id) {
-    this.intId = id;
-  }
-
-  public void setLongField(Long longField) {
-    this.longField = longField;
-  }
-
-  public void setNumberListField(List<Integer> numberListField) {
-    this.numberListField = numberListField;
-  }
-
-  public void setOneToManyField(List<SimpleBar> oneToManyField) {
-    this.oneToManyField = oneToManyField;
-  }
-
-  public void setOneToManySetField(Set<SimpleBar> oneToManySetField) {
-    this.oneToManySetField = oneToManySetField;
-  }
-
-  public void setNullField(String nullField) {
-    this.nullField = nullField;
-  }
-
-  /**
-   * @param otherBoolField the otherBoolField to set
-   */
-  public void setOtherBoolField(Boolean otherBoolField) {
-    this.otherBoolField = otherBoolField;
-  }
-
-  public void setPleaseCrash(Integer crashIf42) {
-    if (crashIf42 == 42) {
-      throw new UnsupportedOperationException("THIS EXCEPTION IS EXPECTED BY A TEST");
-    }
-    pleaseCrash = crashIf42;
-  }
-
-  public void setPassword(String password) {
-    this.password = password;
-  }
-
-  public void setSelfOneToManyField(List<SimpleFooString> selfOneToManyField) {
-    this.selfOneToManyField = selfOneToManyField;
-  }
-
-  /**
-   * @param shortField the shortField to set
-   */
-  public void setShortField(Short shortField) {
-    this.shortField = shortField;
-  }
-
-  public void setUserName(String userName) {
-    this.userName = userName;
-  }
-
-  public void setVersion(Integer version) {
-    this.version = version;
-  }
-
-  public Integer sum(List<Integer> values) {
-    int sum = 0;
-    for (int n : values) {
-      sum += n;
-    }
-    return sum;
-  }
-}
diff --git a/user/test/com/google/gwt/requestfactory/shared/SimpleFooStringProxy.java b/user/test/com/google/gwt/requestfactory/shared/SimpleFooStringProxy.java
deleted file mode 100644
index 875d44c..0000000
--- a/user/test/com/google/gwt/requestfactory/shared/SimpleFooStringProxy.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.shared;
-
-import com.google.gwt.requestfactory.server.SimpleFooString;
-
-/**
- * An extension of AbstractFooProxy with String id.
- */
-@ProxyFor(SimpleFooString.class)
-public interface SimpleFooStringProxy extends BaseFooProxy {
-  SimpleFooStringProxy getFooField();
-
-  String getId();
-
-  void setFooField(SimpleFooStringProxy fooField);
-
-  EntityProxyId<SimpleFooStringProxy> stableId();
-}
diff --git a/user/test/com/google/gwt/requestfactory/shared/SimpleFooStringRequest.java b/user/test/com/google/gwt/requestfactory/shared/SimpleFooStringRequest.java
deleted file mode 100644
index 2a0346f..0000000
--- a/user/test/com/google/gwt/requestfactory/shared/SimpleFooStringRequest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.requestfactory.shared;
-
-import java.util.List;
-
-/**
- * Do nothing test interface.
- */
-@Service(com.google.gwt.requestfactory.server.SimpleFooString.class)
-public interface SimpleFooStringRequest extends RequestContext {
-  Request<Long> countSimpleFoo();
-
-  InstanceRequest<SimpleFooStringProxy, Long> countSimpleFooWithUserNameSideEffect();
-
-  Request<List<SimpleFooStringProxy>> findAll();
-
-  Request<SimpleFooStringProxy> findSimpleFooStringById(String id);
-
-  InstanceRequest<SimpleFooStringProxy, Void> persist();
-
-  InstanceRequest<SimpleFooStringProxy, SimpleFooStringProxy> persistAndReturnSelf();
-
-  Request<Void> reset();
-
-  InstanceRequest<SimpleFooStringProxy, String> hello(SimpleBarProxy proxy);
-}
diff --git a/user/test/com/google/gwt/requestfactory/shared/SimpleRequestFactory.java b/user/test/com/google/gwt/requestfactory/shared/SimpleRequestFactory.java
index f763381..aaea4dc 100644
--- a/user/test/com/google/gwt/requestfactory/shared/SimpleRequestFactory.java
+++ b/user/test/com/google/gwt/requestfactory/shared/SimpleRequestFactory.java
@@ -22,7 +22,5 @@
 
   SimpleFooRequest simpleFooRequest();
 
-  SimpleFooStringRequest simpleFooStringRequest();
-
   SimpleBarRequest simpleBarRequest();
 }
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/SimpleEntityProxyIdTest.java b/user/test/com/google/gwt/requestfactory/shared/impl/SimpleEntityProxyIdTest.java
similarity index 87%
rename from user/test/com/google/gwt/requestfactory/client/impl/SimpleEntityProxyIdTest.java
rename to user/test/com/google/gwt/requestfactory/shared/impl/SimpleEntityProxyIdTest.java
index ab24902..ebb9433 100644
--- a/user/test/com/google/gwt/requestfactory/client/impl/SimpleEntityProxyIdTest.java
+++ b/user/test/com/google/gwt/requestfactory/shared/impl/SimpleEntityProxyIdTest.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.client.impl;
+package com.google.gwt.requestfactory.shared.impl;
 
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.SimpleBarProxy;
@@ -53,16 +53,16 @@
   public void testInequality() {
     assertFalse(isStable(id(EntityProxy.class, 1), id(EntityProxy.class, 2)));
 
-    assertFalse(isStable(id(EntityProxy.class, "server1"), id(
-        EntityProxy.class, "server2")));
+    assertFalse(isStable(id(EntityProxy.class, "server1"),
+        id(EntityProxy.class, "server2")));
 
     // Same client-side id, but different types
-    assertFalse(isStable(id(SimpleFooProxy.class, 1), id(SimpleBarProxy.class,
-        1)));
+    assertFalse(isStable(id(SimpleFooProxy.class, 1),
+        id(SimpleBarProxy.class, 1)));
 
     // Same server id, but different types
-    assertFalse(isStable(id(SimpleFooProxy.class, "server1"), id(
-        SimpleBarProxy.class, "server1")));
+    assertFalse(isStable(id(SimpleFooProxy.class, "server1"),
+        id(SimpleBarProxy.class, "server1")));
   }
 
   private <T extends EntityProxy> SimpleEntityProxyId<T> id(Class<T> clazz,
diff --git a/user/test/com/google/gwt/valuestore/server/SimpleFoo.java b/user/test/com/google/gwt/valuestore/server/SimpleFoo.java
deleted file mode 100644
index 0745240..0000000
--- a/user/test/com/google/gwt/valuestore/server/SimpleFoo.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.valuestore.server;
-
-import com.google.gwt.requestfactory.server.SimpleBar;
-import com.google.gwt.requestfactory.shared.Id;
-import com.google.gwt.requestfactory.shared.SimpleEnum;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
-/**
- * Domain object for SimpleFooRequest.
- */
-public class SimpleFoo {
-
-  static SimpleFoo singleton = new SimpleFoo();
-
-  private static Long nextId = 1L;
-
-  public static Long countSimpleFoo() {
-    return 1L;
-  }
-
-  public static List<SimpleFoo> findAll() {
-    return Collections.singletonList(singleton);
-  }
-
-  public static SimpleFoo findSimpleFoo(Long id) {
-    return findSimpleFooById(id);
-  }
-
-  public static SimpleFoo findSimpleFooById(Long id) {
-    singleton.setId(id);
-    return singleton;
-  }
-
-  public static SimpleFoo getSingleton() {
-    return singleton;
-  }
-
-  public static void reset() {
-    singleton = new SimpleFoo();
-  }
-
-  @SuppressWarnings("unused")
-  private static Integer privateMethod() {
-    return 0;
-  }
-
-  Integer version = 1;
-
-  @Id
-  private Long id = 1L;
-
-  private Integer intId = -1;
-
-  private String password;
-
-  private String userName;
-
-  private Character charField;
-
-  private Long longField;
-
-  private BigDecimal bigDecimalField;
-
-  private BigInteger bigIntField;
-
-  private Short shortField;
-
-  private Byte byteField;
-
-  private Date created;
-
-  private Double doubleField;
-
-  private Float floatField;
-
-  private SimpleEnum enumField;
-
-  private Boolean boolField;
-
-  private Boolean otherBoolField;
-
-  private SimpleBar barField;
-
-  private SimpleFoo fooField;
-
-  public SimpleFoo() {
-    intId = 42;
-    version = 1;
-    userName = "GWT";
-    longField = 8L;
-    enumField = SimpleEnum.FOO;
-    created = new Date();
-    barField = SimpleBar.getSingleton();
-    boolField = true;
-  }
-
-  public Long countSimpleFooWithUserNameSideEffect() {
-    singleton.setUserName(userName);
-    return 1L;
-  }
-
-  public SimpleBar getBarField() {
-    return barField;
-  }
-
-  /**
-   * Returns the bigDecimalField.
-   */
-  public BigDecimal getBigDecimalField() {
-    return bigDecimalField;
-  }
-
-  /**
-   * Returns the bigIntField.
-   */
-  public BigInteger getBigIntField() {
-    return bigIntField;
-  }
-
-  public Boolean getBoolField() {
-    return boolField;
-  }
-
-  /**
-   * Returns the byteField.
-   */
-  public Byte getByteField() {
-    return byteField;
-  }
-
-  /**
-   * Returns the charField.
-   */
-  public Character getCharField() {
-    return charField;
-  }
-
-  public Date getCreated() {
-    return created;
-  }
-
-  /**
-   * Returns the doubleField.
-   */
-  public Double getDoubleField() {
-    return doubleField;
-  }
-
-  public SimpleEnum getEnumField() {
-    return enumField;
-  }
-
-  /**
-   * Returns the floatField.
-   */
-  public Float getFloatField() {
-    return floatField;
-  }
-
-  public SimpleFoo getFooField() {
-    return fooField;
-  }
-
-  public Long getId() {
-    return id;
-  }
-
-  public Integer getIntId() {
-    return intId;
-  }
-
-  public Long getLongField() {
-    return longField;
-  }
-
-  /**
-   * Returns the otherBoolField.
-   */
-  public Boolean getOtherBoolField() {
-    return otherBoolField;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  /**
-   * Returns the shortField.
-   */
-  public Short getShortField() {
-    return shortField;
-  }
-
-  public String getUserName() {
-    return userName;
-  }
-
-  public Integer getVersion() {
-    return version;
-  }
-
-  public String hello(SimpleBar bar) {
-    return "Greetings " + bar.getUserName() + " from " + getUserName();
-  }
-
-  public void persist() {
-    setId(nextId++);
-  }
-
-  public SimpleFoo persistAndReturnSelf() {
-    persist();
-    return this;
-  }
-
-  public void setBarField(SimpleBar barField) {
-    this.barField = barField;
-  }
-
-  /**
-   * @param bigDecimalField the bigDecimalField to set
-   */
-  public void setBigDecimalField(BigDecimal bigDecimalField) {
-    this.bigDecimalField = bigDecimalField;
-  }
-
-  /**
-   * @param bigIntField the bigIntField to set
-   */
-  public void setBigIntField(BigInteger bigIntField) {
-    this.bigIntField = bigIntField;
-  }
-
-  public void setBoolField(Boolean bool) {
-    boolField = bool;
-  }
-
-  /**
-   * @param byteField the byteField to set
-   */
-  public void setByteField(Byte byteField) {
-    this.byteField = byteField;
-  }
-
-  /**
-   * @param charField the charField to set
-   */
-  public void setCharField(Character charField) {
-    this.charField = charField;
-  }
-
-  public void setCreated(Date created) {
-    this.created = created;
-  }
-
-  /**
-   * @param doubleField the doubleField to set
-   */
-  public void setDoubleField(Double doubleField) {
-    this.doubleField = doubleField;
-  }
-
-  public void setEnumField(SimpleEnum enumField) {
-    this.enumField = enumField;
-  }
-
-  /**
-   * @param floatField the floatField to set
-   */
-  public void setFloatField(Float floatField) {
-    this.floatField = floatField;
-  }
-
-  public void setFooField(SimpleFoo fooField) {
-    this.fooField = fooField;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public void setIntId(Integer id) {
-    this.intId = id;
-  }
-
-  public void setLongField(Long longField) {
-    this.longField = longField;
-  }
-
-  /**
-   * @param otherBoolField the otherBoolField to set
-   */
-  public void setOtherBoolField(Boolean otherBoolField) {
-    this.otherBoolField = otherBoolField;
-  }
-
-  public void setPassword(String password) {
-    this.password = password;
-  }
-
-  /**
-   * @param shortField the shortField to set
-   */
-  public void setShortField(Short shortField) {
-    this.shortField = shortField;
-  }
-
-  public void setUserName(String userName) {
-    this.userName = userName;
-  }
-
-  public void setVersion(Integer version) {
-    this.version = version;
-  }
-}
