diff --git a/dev/core/src/com/google/gwt/core/ext/linker/CastableTypeMap.java b/dev/core/src/com/google/gwt/core/ext/linker/CastableTypeMap.java
deleted file mode 100644
index 4a47661..0000000
--- a/dev/core/src/com/google/gwt/core/ext/linker/CastableTypeMap.java
+++ /dev/null
@@ -1,30 +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.core.ext.linker;
-
-import java.io.Serializable;
-
-/**
- * An encapsulation of a JSON map containing a set of castable type ids.
- */
-public interface CastableTypeMap extends Serializable {
-
-    /**
-     * Returns an eval-able JSON object.
-     */
-    String toJs();
-}
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/SymbolData.java b/dev/core/src/com/google/gwt/core/ext/linker/SymbolData.java
index 6378b89..bac46d3 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/SymbolData.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/SymbolData.java
@@ -82,11 +82,6 @@
   }
 
   /**
-   * Returns a JSON map of castableTypes.
-   */
-  CastableTypeMap getCastableTypeMap();
-
-  /**
    * Returns the name of the type or enclosing type if the symbol is a method or
    * field.
    */
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCastableTypeMap.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCastableTypeMap.java
deleted file mode 100644
index d0fff59..0000000
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCastableTypeMap.java
+++ /dev/null
@@ -1,37 +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.core.ext.linker.impl;
-
-import com.google.gwt.core.ext.linker.CastableTypeMap;
-
-/**
- * The standard implementation of {@link CastableTypeMap}.
- */
-public class StandardCastableTypeMap implements CastableTypeMap {
-  // Save some memory by defining this constant string.
-  private static final String EMPTY_JSON_REF = "{}";
-
-  final String jsonData;
-  public StandardCastableTypeMap(String jsonData) {
-    this.jsonData = jsonData.equals(EMPTY_JSON_REF) ? EMPTY_JSON_REF : jsonData;
-  }
-
-  @Override
-  public String toJs() {
-    return jsonData;
-  }
-}
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardSymbolData.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardSymbolData.java
index ee0a0fa..a34a033 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardSymbolData.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardSymbolData.java
@@ -15,7 +15,6 @@
  */
 package com.google.gwt.core.ext.linker.impl;
 
-import com.google.gwt.core.ext.linker.CastableTypeMap;
 import com.google.gwt.core.ext.linker.SymbolData;
 
 import java.io.File;
@@ -32,15 +31,15 @@
 public class StandardSymbolData implements SymbolData {
 
   public static StandardSymbolData forClass(String className, String uriString,
-      int lineNumber, CastableTypeMap castableTypeMap, String typeId) {
+      int lineNumber, String typeId) {
     return new StandardSymbolData(className, null, null, uriString, lineNumber,
-        castableTypeMap, typeId);
+        typeId);
   }
 
   public static StandardSymbolData forMember(String className,
       String memberName, String methodSig, String uriString, int lineNumber) {
     return new StandardSymbolData(className, memberName, methodSig, uriString,
-        lineNumber, null, null);
+        lineNumber, null);
   }
 
   public static String toUriString(String fileName) {
@@ -64,11 +63,9 @@
   private String sourceUri;
   private String symbolName;
   private String typeId;
-  private CastableTypeMap castableTypeMap;
 
   private StandardSymbolData(String className, String memberName,
-      String methodSig, String sourceUri, int sourceLine,
-      CastableTypeMap castableTypeMap, String typeId) {
+      String methodSig, String sourceUri, int sourceLine, String typeId) {
     assert className != null && className.length() > 0 : "className";
     assert memberName != null || methodSig == null : "methodSig without memberName";
     assert sourceLine >= -1 : "sourceLine: " + sourceLine;
@@ -78,16 +75,10 @@
     this.methodSig = methodSig;
     this.sourceUri = sourceUri;
     this.sourceLine = sourceLine;
-    this.castableTypeMap = castableTypeMap;
     this.typeId = typeId;
   }
 
   @Override
-  public CastableTypeMap getCastableTypeMap() {
-    return castableTypeMap;
-  }
-
-  @Override
   public String getClassName() {
     return className;
   }
@@ -179,7 +170,6 @@
     sourceLine = in.readInt();
     sourceUri = (String) in.readObject();
     symbolName = in.readUTF();
-    castableTypeMap = (CastableTypeMap) in.readObject();
     typeId = (String) in.readObject();
     fragmentNumber = in.readInt();
   }
@@ -208,7 +198,6 @@
     out.writeInt(sourceLine);
     out.writeObject(sourceUri);
     out.writeUTF(symbolName);
-    out.writeObject(castableTypeMap);
     out.writeObject(typeId);
     out.writeInt(fragmentNumber);
   }
diff --git a/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java b/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
index c9b3ef9..baa34fa 100644
--- a/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
+++ b/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
@@ -265,8 +265,6 @@
         CompilerEventType.GENERATOR_I18N);
     eventsByGeneratorType.put("com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator",
         CompilerEventType.GENERATOR_RPC);
-    eventsByGeneratorType.put("com.google.gwt.rpc.rebind.RpcServiceGenerator",
-        CompilerEventType.GENERATOR_RPC); // deRPC
     eventsByGeneratorType.put("com.google.gwt.uibinder.rebind.UiBinderGenerator",
         CompilerEventType.GENERATOR_UIBINDER);
     eventsByGeneratorType.put("com.google.gwt.inject.rebind.GinjectorGenerator",
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index cad2e97..3912f5d 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -15,8 +15,6 @@
  */
 package com.google.gwt.dev.jjs.impl;
 
-import com.google.gwt.core.ext.linker.CastableTypeMap;
-import com.google.gwt.core.ext.linker.impl.StandardCastableTypeMap;
 import com.google.gwt.core.ext.linker.impl.StandardSymbolData;
 import com.google.gwt.dev.CompilerContext;
 import com.google.gwt.dev.cfg.PermProps;
@@ -694,29 +692,11 @@
       if (getRuntimeTypeReference(x) == null || !typeOracle.isInstantiatedType(x)) {
         return;
       }
-      // TODO(rluble): Remove castmaps from symbol maps as part of deRPC deprecation.
-      StringBuilder sb = new StringBuilder();
-      sb.append('{');
-      JCastMap castMap = program.getCastMap(x);
-      if (castMap != null) {
-        boolean isFirst = true;
-        for (JExpression castToType : castMap.getCanCastToTypes()) {
-          if (isFirst) {
-            isFirst = false;
-          } else {
-            sb.append(',');
-          }
-          sb.append(castToType.toSource());
-          sb.append(":1");
-        }
-      }
-      sb.append('}');
-      CastableTypeMap castableTypeMap = new StandardCastableTypeMap(sb.toString());
 
       String typeId = getRuntimeTypeReference(x).toSource();
       StandardSymbolData symbolData =
           StandardSymbolData.forClass(x.getName(), x.getSourceInfo().getFileName(),
-              x.getSourceInfo().getStartLine(), castableTypeMap, typeId);
+              x.getSourceInfo().getStartLine(), typeId);
       assert !symbolTable.containsKey(symbolData);
       symbolTable.put(symbolData, jsName);
     }
diff --git a/dev/core/test/com/google/gwt/core/ext/linker/SourceMapTest.java b/dev/core/test/com/google/gwt/core/ext/linker/SourceMapTest.java
index aafe4a6..f2ad2e8 100644
--- a/dev/core/test/com/google/gwt/core/ext/linker/SourceMapTest.java
+++ b/dev/core/test/com/google/gwt/core/ext/linker/SourceMapTest.java
@@ -130,11 +130,6 @@
     }
 
     @Override
-    public CastableTypeMap getCastableTypeMap() {
-      return null;
-    }
-
-    @Override
     public String getClassName() {
       return this.className;
     }
diff --git a/dev/core/test/com/google/gwt/core/ext/linker/SymbolMapTest.java b/dev/core/test/com/google/gwt/core/ext/linker/SymbolMapTest.java
index 442e915..05998b4 100644
--- a/dev/core/test/com/google/gwt/core/ext/linker/SymbolMapTest.java
+++ b/dev/core/test/com/google/gwt/core/ext/linker/SymbolMapTest.java
@@ -92,11 +92,6 @@
     }
 
     @Override
-    public CastableTypeMap getCastableTypeMap() {
-      return null;
-    }
-
-    @Override
     public String getClassName() {
       return this.className;
     }
diff --git a/tools/api-checker/config/gwt26_27userApi.conf b/tools/api-checker/config/gwt26_27userApi.conf
index d76e53a..6df95c2 100644
--- a/tools/api-checker/config/gwt26_27userApi.conf
+++ b/tools/api-checker/config/gwt26_27userApi.conf
@@ -52,6 +52,7 @@
 :com/google/gwt/rpc/client/impl/ClientWriterFactory.java\
 :com/google/gwt/rpc/client/impl/EscapeUtil.java\
 :com/google/gwt/rpc/client/impl/RpcCallbackAdapter.java\
+:com/google/gwt/rpc/client/impl/RpcServiceProxy.java\
 :com/google/gwt/safecss/shared/SafeStylesHostedModeUtils.java\
 :com/google/gwt/safehtml/shared/SafeHtmlHostedModeUtils.java\
 :com/google/gwt/safehtml/shared/SafeUriHostedModeUtils.java\
@@ -109,9 +110,6 @@
 :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/rpc/client/impl/ClientWriterFactory.java\
-:user/src/com/google/gwt/rpc/client/impl/EscapeUtil.java\
-:user/src/com/google/gwt/rpc/client/impl/RpcCallbackAdapter.java\
 :user/src/com/google/gwt/safecss/shared/SafeStylesHostedModeUtils.java\
 :user/src/com/google/gwt/safehtml/shared/SafeHtmlHostedModeUtils.java\
 :user/src/com/google/gwt/safehtml/shared/SafeUriHostedModeUtils.java\
@@ -140,6 +138,7 @@
 :com.google.gwt.junit.client.impl\
 :com.google.gwt.lang\
 :com.google.gwt.resources.client.impl\
+:com.google.gwt.rpc.client.impl\
 :com.google.gwt.user.client.impl\
 :com.google.gwt.user.client.ui.impl\
 :com.google.gwt.xml.client.impl\
@@ -174,3 +173,10 @@
 
 # Removed deprecated c.g.gwt.widgets
 com.google.gwt.widget.client MISSING
+
+# Removed deprecated deRPC
+# TODO(rluble) remove all references to deRPC and com.google.gwt.rpc from next gwtXX_XXuserApi.conf
+# on next version switch..
+com.google.gwt.rpc.client MISSING
+com.google.gwt.rpc.client.ast MISSING
+
diff --git a/user/BUILD b/user/BUILD
index 0ee11f1..1c603a1 100644
--- a/user/BUILD
+++ b/user/BUILD
@@ -279,15 +279,8 @@
             "src/com/google/gwt/user/client/rpc/SerializationException.java",
             "src/com/google/gwt/user/client/rpc/SerializationStreamReader.java",
             "src/com/google/gwt/user/client/rpc/SerializationStreamWriter.java",
-            "src/com/google/gwt/rpc/client/ast/*.java",
-            "src/com/google/gwt/rpc/client/impl/CommandSerializationStreamWriterBase.java",
-            "src/com/google/gwt/rpc/client/impl/CommandClientSerializationStreamReader.java",
-            "src/com/google/gwt/rpc/client/impl/EscapeUtil.java",
             "src/com/google/gwt/user/client/rpc/impl/ClientSerializationStreamWriter.java",
             "src/com/google/gwt/user/client/rpc/impl/Serializer.java",
-            "src/com/google/gwt/rpc/client/impl/HasValuesCommandSink.java",
-            "src/com/google/gwt/rpc/client/impl/SimplePayloadSink.java",
-            "src/com/google/gwt/rpc/client/impl/RemoteException.java",
             # ...which need:
             "src/com/google/gwt/core/client/GWT.java",
             "src/com/google/gwt/core/client/JavaScriptException.java",
diff --git a/user/build.xml b/user/build.xml
index a926fa5..274f4ef 100755
--- a/user/build.xml
+++ b/user/build.xml
@@ -181,7 +181,6 @@
         <pathelement location="${project.build}/bin/com/google/gwt/regexp/RegExp.gwtar"/>
         <pathelement location="${project.build}/bin/com/google/gwt/user/User.gwtar"/>
         <pathelement location="${project.build}/bin/com/google/gwt/xml/XML.gwtar"/>
-        <pathelement location="${project.build}/bin/com/google/gwt/rpc/RPC.gwtar"/>
         <pathelement location="${project.build}/bin/com/google/gwt/debug/Debug.gwtar"/>
         <pathelement location="${project.build}/bin/com/google/gwt/place/Place.gwtar"/>
         <pathelement location="${project.build}/bin/com/google/gwt/activity/Activity.gwtar"/>
@@ -205,7 +204,6 @@
 
             <!-- Below are modules that depend on User           -->
             <arg value="com.google.gwt.xml.XML"/>
-            <arg value="com.google.gwt.rpc.RPC"/>
             <arg value="com.google.gwt.debug.Debug"/>
             <arg value="com.google.gwt.logging.Logging"/>
 
diff --git a/user/src/com/google/gwt/junit/server/JUnitHostImpl.java b/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
index 37c4ecb..8fa4065 100644
--- a/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
+++ b/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
@@ -15,8 +15,6 @@
  */
 package com.google.gwt.junit.server;
 
-import static com.google.gwt.user.client.rpc.RpcRequestBuilder.MODULE_BASE_HEADER;
-
 import com.google.gwt.core.server.StackTraceDeobfuscator;
 import com.google.gwt.junit.JUnitFatalLaunchException;
 import com.google.gwt.junit.JUnitMessageQueue;
@@ -31,8 +29,6 @@
 import com.google.gwt.user.server.rpc.RemoteServiceServlet;
 
 import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.util.HashMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -154,31 +150,6 @@
     return machine + " / " + agent;
   }
 
-  /**
-   * Extract the module's base path from the current request.
-   * 
-   * @return the module's base path, modulo protocol and host, as reported by
-   *         {@link com.google.gwt.core.client.GWT#getModuleBaseURL()} or
-   *         <code>null</code> if the request did not contain the
-   *         {@value com.google.gwt.user.client.rpc.RpcRequestBuilder#MODULE_BASE_HEADER} header
-   */
-  private String getRequestModuleBasePath() {
-    try {
-      String header = getThreadLocalRequest().getHeader(MODULE_BASE_HEADER);
-      if (header == null) {
-        return null;
-      }
-      String path = new URL(header).getPath();
-      String contextPath = getThreadLocalRequest().getContextPath();
-      if (!path.startsWith(contextPath)) {
-        return null;
-      }
-      return path.substring(contextPath.length());
-    } catch (MalformedURLException e) {
-      return null;
-    }
-  }
-
   private void initResult(HttpServletRequest request, JUnitResult result) {
     result.setAgent(request.getHeader("User-Agent"));
     result.setHost(request.getRemoteHost());
diff --git a/user/src/com/google/gwt/rpc/RPC.gwt.xml b/user/src/com/google/gwt/rpc/RPC.gwt.xml
deleted file mode 100644
index c88a958..0000000
--- a/user/src/com/google/gwt/rpc/RPC.gwt.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<module type="fileset">
-  <inherits name="com.google.gwt.core.Core" />
-  <!-- Inherits standard RPC, c.g.g.user.RemoteService is not standalone. -->
-  <inherits name="com.google.gwt.user.User" />
-
-  <source path="client" />
-  <super-source path="super" />
-
-  <define-linker name="clientOracleLinker"
-    class="com.google.gwt.rpc.linker.ClientOracleLinker" />
-  <add-linker name="clientOracleLinker" />
-
-  <define-property name="gwt.rpc.hijackLegacyInterface" values="true,false" />
-  <set-property name="gwt.rpc.hijackLegacyInterface" value="false" />
-
-  <generate-with class="com.google.gwt.rpc.rebind.RpcServiceGenerator">
-    <any>
-      <when-type-assignable class="com.google.gwt.rpc.client.RpcService" />
-      <all>
-        <when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService" />
-        <when-property-is name="gwt.rpc.hijackLegacyInterface"
-          value="true" />
-      </all>
-    </any>
-  </generate-with>
-</module>
diff --git a/user/src/com/google/gwt/rpc/client/RpcService.java b/user/src/com/google/gwt/rpc/client/RpcService.java
deleted file mode 100644
index b482e49..0000000
--- a/user/src/com/google/gwt/rpc/client/RpcService.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client;
-
-import com.google.gwt.user.client.rpc.RemoteService;
-
-/**
- * EXPERIMENTAL and subject to change. Do not use this in production code.
- * <p>
- * Marker interface to be used with RpcServlet.
- */
-public interface RpcService extends RemoteService {
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/ArrayValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/ArrayValueCommand.java
deleted file mode 100644
index 49406b8..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/ArrayValueCommand.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Encapsulates an array of values.
- */
-public class ArrayValueCommand extends IdentityValueCommand {
-  private final Class<?> componentType;
-  private final List<ValueCommand> values = new ArrayList<ValueCommand>();
-
-  public ArrayValueCommand(Class<?> componentType) {
-    this.componentType = componentType;
-  }
-
-  public void add(ValueCommand x) {
-    values.add(x);
-  }
-
-  @Override
-  public void clear() {
-    values.clear();
-  }
-
-  public Class<?> getComponentType() {
-    return componentType;
-  }
-
-  public List<ValueCommand> getComponentValues() {
-    return values;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    if (visitor.visit(this, ctx)) {
-      visitor.accept(values);
-    }
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/BooleanValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/BooleanValueCommand.java
deleted file mode 100644
index ed82909..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/BooleanValueCommand.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a boolean value in the command stream.
- */
-public class BooleanValueCommand extends ScalarValueCommand {
-  private final boolean value;
-
-  public BooleanValueCommand(double value) {
-    this.value = value != 0;
-  }
-
-  public BooleanValueCommand(boolean value) {
-    this.value = value;
-  }
-
-  public BooleanValueCommand(Boolean value) {
-    this.value = value;
-  }
-
-  @Override
-  public Boolean getValue() {
-    return value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/ByteValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/ByteValueCommand.java
deleted file mode 100644
index d29bde0..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/ByteValueCommand.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a boolean value in the command stream.
- */
-public class ByteValueCommand extends ScalarValueCommand {
-  private final byte value;
-
-  public ByteValueCommand(double value) {
-    this.value = (byte) value;
-  }
-
-  public ByteValueCommand(byte value) {
-    this.value = value;
-  }
-
-  public ByteValueCommand(Byte value) {
-    this.value = value;
-  }
-
-  @Override
-  public Byte getValue() {
-    return value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/CharValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/CharValueCommand.java
deleted file mode 100644
index 17850f5..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/CharValueCommand.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a boolean value in the command stream.
- */
-public class CharValueCommand extends ScalarValueCommand {
-  private final char value;
-
-  public CharValueCommand(double value) {
-    this.value = (char) value;
-  }
-
-  public CharValueCommand(char value) {
-    this.value = value;
-  }
-
-  public CharValueCommand(Character value) {
-    this.value = value;
-  }
-
-  @Override
-  public Character getValue() {
-    return value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/CommandSink.java b/user/src/com/google/gwt/rpc/client/ast/CommandSink.java
deleted file mode 100644
index 10f9991..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/CommandSink.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.user.client.rpc.SerializationException;
-
-/**
- * Accepts a stream of RpcCommands.
- */
-public abstract class CommandSink {
-  /**
-   * Accept an RpcCommand for processing.
-   * 
-   * @param command
-   * @throws SerializationException
-   */
-  public abstract void accept(RpcCommand command) throws SerializationException;
-
-  /**
-   * Called when no more commands will be sent.
-   */
-  public abstract void finish() throws SerializationException;
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/DoubleValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/DoubleValueCommand.java
deleted file mode 100644
index 2127185..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/DoubleValueCommand.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a boolean value in the command stream.
- */
-public class DoubleValueCommand extends ScalarValueCommand {
-  private final double value;
-
-  public DoubleValueCommand(double value) {
-    this.value = value;
-  }
-
-  public DoubleValueCommand(Double value) {
-    this.value = value;
-  }
-
-  @Override
-  public Double getValue() {
-    return value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/EnumValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/EnumValueCommand.java
deleted file mode 100644
index 7b66e55..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/EnumValueCommand.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a string value in the command stream.
- */
-public class EnumValueCommand extends IdentityValueCommand {
-  private Enum<?> value;
-
-  public Enum<?> getValue() {
-    return value;
-  }
-
-  /**
-   * Not a constructor argument so that the identity of the EnumValueCommand can
-   * be established before the identity of the value.
-   */
-  public void setValue(Enum<?> value) {
-    this.value = value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/FloatValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/FloatValueCommand.java
deleted file mode 100644
index 1cd4d79..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/FloatValueCommand.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a boolean value in the command stream.
- */
-public class FloatValueCommand extends ScalarValueCommand {
-  private final float value;
-
-  public FloatValueCommand(double value) {
-    this.value = (float) value;
-  }
-
-  public FloatValueCommand(float value) {
-    this.value = value;
-  }
-
-  public FloatValueCommand(Float value) {
-    this.value = value;
-  }
-
-  @Override
-  public Float getValue() {
-    return value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/HasSetters.java b/user/src/com/google/gwt/rpc/client/ast/HasSetters.java
deleted file mode 100644
index 1da97b9..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/HasSetters.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import java.util.List;
-
-/**
- * Describes RpcCommands that have additional field setters.
- */
-public interface HasSetters {
-
-  List<SetCommand> getSetters();
-
-  void set(Class<?> fieldDeclClass, String fieldName, ValueCommand value);
-
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/HasTargetClass.java b/user/src/com/google/gwt/rpc/client/ast/HasTargetClass.java
deleted file mode 100644
index 9a5b428..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/HasTargetClass.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-/**
- * An RpcCommand with a target class.
- */
-public interface HasTargetClass {
-  Class<?> getTargetClass();
-}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/rpc/client/ast/HasValues.java b/user/src/com/google/gwt/rpc/client/ast/HasValues.java
deleted file mode 100644
index 56150e1..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/HasValues.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import java.util.List;
-
-/**
- * An RpcCommand that contains other values.
- */
-public interface HasValues {
-
-  void addValue(ValueCommand value);
-
-  List<ValueCommand> getValues();
-
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/IdentityValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/IdentityValueCommand.java
deleted file mode 100644
index b579719..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/IdentityValueCommand.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-/**
- * Represents a hierarchy of value types that must maintain distinct object
- * identity on the client. This type finalizes <code>equals</code> and
- * <code>hashCode</code> to give subtypes identity equality semantics.
- */
-public abstract class IdentityValueCommand extends ValueCommand {
-  @Override
-  public final boolean equals(Object o) {
-    return this == o;
-  }
-
-  @Override
-  public final int hashCode() {
-    return System.identityHashCode(this);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/InstantiateCommand.java b/user/src/com/google/gwt/rpc/client/ast/InstantiateCommand.java
deleted file mode 100644
index d0ed18d..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/InstantiateCommand.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Triggers the instantiation of an object.
- */
-public class InstantiateCommand extends IdentityValueCommand implements
-    HasSetters, HasTargetClass {
-  private final Class<?> clazz;
-  private final List<SetCommand> setters = new ArrayList<SetCommand>();
-
-  public InstantiateCommand(Class<?> clazz) {
-    this.clazz = clazz;
-  }
-
-  @Override
-  public void clear() {
-    setters.clear();
-  }
-
-  public List<SetCommand> getSetters() {
-    return setters;
-  }
-
-  public Class<?> getTargetClass() {
-    return clazz;
-  }
-
-  public void set(Class<?> fieldDeclClass, String fieldName, ValueCommand value) {
-    setters.add(new SetCommand(fieldDeclClass, fieldName, value));
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    if (visitor.visit(this, ctx)) {
-      visitor.accept(setters);
-    }
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/IntValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/IntValueCommand.java
deleted file mode 100644
index 1684d09..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/IntValueCommand.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a int value in the command stream.
- */
-public class IntValueCommand extends ScalarValueCommand {
-  private final int value;
-
-  public IntValueCommand(double value) {
-    this.value = (int) value;
-  }
-
-  public IntValueCommand(int value) {
-    this.value = value;
-  }
-
-  public IntValueCommand(Integer value) {
-    this.value = value;
-  }
-
-  @Override
-  public Integer getValue() {
-    return value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/InvokeCustomFieldSerializerCommand.java b/user/src/com/google/gwt/rpc/client/ast/InvokeCustomFieldSerializerCommand.java
deleted file mode 100644
index d213050..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/InvokeCustomFieldSerializerCommand.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A placeholder for custom logic invocation.
- */
-public class InvokeCustomFieldSerializerCommand extends IdentityValueCommand
-    implements HasSetters, HasTargetClass, HasValues {
-  private final Class<?> manuallySerializedType;
-  private final Class<?> serializer;
-  private final List<SetCommand> setters = new ArrayList<SetCommand>();
-  private final Class<?> instantiatedType;
-  private final List<ValueCommand> values = new ArrayList<ValueCommand>();
-
-  public InvokeCustomFieldSerializerCommand(Class<?> instantiatedType,
-      Class<?> serializer, Class<?> manuallySerializedType) {
-    this.instantiatedType = instantiatedType;
-    this.serializer = serializer;
-    this.manuallySerializedType = manuallySerializedType;
-  }
-
-  public void addValue(ValueCommand value) {
-    values.add(value);
-  }
-
-  @Override
-  public void clear() {
-    values.clear();
-  }
-
-  public Class<?> getManuallySerializedType() {
-    return manuallySerializedType;
-  }
-
-  public Class<?> getSerializerClass() {
-    return serializer;
-  }
-
-  public List<SetCommand> getSetters() {
-    return setters;
-  }
-
-  public Class<?> getTargetClass() {
-    return instantiatedType;
-  }
-
-  public List<ValueCommand> getValues() {
-    return values;
-  }
-
-  public void set(Class<?> fieldDeclClass, String fieldName, ValueCommand value) {
-    setters.add(new SetCommand(fieldDeclClass, fieldName, value));
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    if (visitor.visit(this, ctx)) {
-      visitor.accept(values);
-      visitor.accept(setters);
-    }
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/LongValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/LongValueCommand.java
deleted file mode 100644
index fde7561..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/LongValueCommand.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a long value in the command stream.
- */
-public class LongValueCommand extends ScalarValueCommand {
-  /*
-   * NB: This does not have a constructor that accepts a double; the client must
-   * send the long
-   */
-  private final long value;
-
-  public LongValueCommand(long value) {
-    this.value = value;
-  }
-
-  public LongValueCommand(Long value) {
-    this.value = value;
-  }
-
-  @Override
-  public Long getValue() {
-    return value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/NullValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/NullValueCommand.java
deleted file mode 100644
index bfb42a1..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/NullValueCommand.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Represents a null or undefined value on the client.
- */
-public class NullValueCommand extends ScalarValueCommand {
-  /**
-   * The singleton instance of NullValueCommand.
-   */
-  public static final NullValueCommand INSTANCE = new NullValueCommand();
-
-  private NullValueCommand() {
-  }
-
-  @Override
-  public Object getValue() {
-    return null;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/ReturnCommand.java b/user/src/com/google/gwt/rpc/client/ast/ReturnCommand.java
deleted file mode 100644
index d068a60..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/ReturnCommand.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Represents a return statement.
- */
-public class ReturnCommand extends RpcCommand implements HasValues {
-  private final List<ValueCommand> values = new ArrayList<ValueCommand>();
-
-  public void addValue(ValueCommand value) {
-    values.add(value);
-  }
-
-  @Override
-  public void clear() {
-    values.clear();
-  }
-
-  public List<ValueCommand> getValues() {
-    return values;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    if (visitor.visit(this, ctx)) {
-      visitor.accept(values);
-    }
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/RpcCommand.java b/user/src/com/google/gwt/rpc/client/ast/RpcCommand.java
deleted file mode 100644
index 12097d9..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/RpcCommand.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a basic operation to be performed in RPC command stream.
- */
-public abstract class RpcCommand {
-  /**
-   * Delete all internal state so that the command may be used only for instance
-   * tracking.
-   */
-  public void clear() {
-  }
-
-  public abstract void traverse(RpcCommandVisitor visitor, Context ctx);
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/RpcCommandVisitor.java b/user/src/com/google/gwt/rpc/client/ast/RpcCommandVisitor.java
deleted file mode 100644
index aeefec8..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/RpcCommandVisitor.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import java.util.List;
-
-/**
- * Describes a visitor that will traverse the RpcCommand structures.
- */
-public class RpcCommandVisitor {
-  /**
-   * The context provides no services at this point and is provided as an
-   * extension point for future development.
-   */
-  public interface Context {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   */
-  public final void accept(List<? extends RpcCommand> x) {
-    doAccept(x);
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   */
-  public final RpcCommand accept(RpcCommand x) {
-    return doAccept(x);
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   */
-  public final void accept(RpcCommand[] x) {
-    doAccept(x);
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(ArrayValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(BooleanValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(ByteValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(CharValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(DoubleValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(EnumValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(FloatValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(InstantiateCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(IntValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(InvokeCustomFieldSerializerCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(LongValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(NullValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(ReturnCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(SetCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(ShortValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(StringValueCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public void endVisit(ThrowCommand x, Context ctx) {
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(ArrayValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(BooleanValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(ByteValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(CharValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(DoubleValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(EnumValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(FloatValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(InstantiateCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(IntValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(InvokeCustomFieldSerializerCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(LongValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(NullValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(ReturnCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(SetCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(ShortValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(StringValueCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   * @param ctx the context for the visit
-   */
-  public boolean visit(ThrowCommand x, Context ctx) {
-    return true;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   */
-  protected void doAccept(List<? extends RpcCommand> x) {
-    for (RpcCommand c : x) {
-      accept(c);
-    }
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   */
-  protected RpcCommand doAccept(RpcCommand x) {
-    x.traverse(this, null);
-    return x;
-  }
-
-  /**
-   * @param x a node in an RpcCommand structure
-   */
-  protected void doAccept(RpcCommand[] x) {
-    for (RpcCommand c : x) {
-      accept(c);
-    }
-  }
-
-  /*
-   * TODO: Make this fail more visibly
-   */
-  protected final void halt(Throwable t) {
-    throw new RuntimeException("Unable to continue", t);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/ScalarValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/ScalarValueCommand.java
deleted file mode 100644
index a2168cb..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/ScalarValueCommand.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-/**
- * Represents a type hierarchy of values that do not maintain object identity on
- * the client.
- */
-public abstract class ScalarValueCommand extends ValueCommand {
-  @Override
-  public final boolean equals(Object o) {
-    if (!(o instanceof ScalarValueCommand)) {
-      return false;
-    }
-    ScalarValueCommand other = (ScalarValueCommand) o;
-    Object myValue = getValue();
-    Object otherValue = other.getValue();
-    if (myValue == null && otherValue == null) {
-      return true;
-    } else if (myValue == null && otherValue != null) {
-      return false;
-    } else {
-      return myValue.equals(otherValue);
-    }
-  }
-
-  /**
-   * Returns the value represented by the ScalarValueCommand.
-   */
-  public abstract Object getValue();
-
-  @Override
-  public final int hashCode() {
-    return getValue() == null ? 0 : getValue().hashCode();
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/SetCommand.java b/user/src/com/google/gwt/rpc/client/ast/SetCommand.java
deleted file mode 100644
index 2410f35..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/SetCommand.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * A command to set the value of an object in the command stream.
- */
-public class SetCommand extends RpcCommand {
-  /*
-   * NB: Not using Field due to lack of GWT compatibility. Consider adding the
-   * Field type to the GWT JRE code.
-   */
-  private String field;
-  /**
-   * The class that defines the field. Used to account for field shadowing.
-   */
-  private Class<?> fieldDeclClass;
-  private ValueCommand value;
-
-  public SetCommand(Class<?> fieldDeclClass, String field, ValueCommand value) {
-    this.fieldDeclClass = fieldDeclClass;
-    this.field = field;
-    this.value = value;
-  }
-
-  @Override
-  public void clear() {
-    field = null;
-    value = null;
-  }
-
-  public String getField() {
-    return field;
-  }
-
-  public Class<?> getFieldDeclClass() {
-    return fieldDeclClass;
-  }
-
-  public ValueCommand getValue() {
-    return value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    if (visitor.visit(this, ctx)) {
-      value.traverse(visitor, ctx);
-    }
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/ShortValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/ShortValueCommand.java
deleted file mode 100644
index 9052a82..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/ShortValueCommand.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a short value in the command stream.
- */
-public class ShortValueCommand extends ScalarValueCommand {
-  private final short value;
-
-  public ShortValueCommand(double value) {
-    this.value = (short) value;
-  }
-
-  public ShortValueCommand(short value) {
-    this.value = value;
-  }
-
-  public ShortValueCommand(Short value) {
-    this.value = value;
-  }
-
-  @Override
-  public Short getValue() {
-    return value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/StringValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/StringValueCommand.java
deleted file mode 100644
index 05db7b9..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/StringValueCommand.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-/**
- * Encapsulates a string value in the command stream.
- */
-public class StringValueCommand extends ScalarValueCommand {
-  private final String value;
-
-  public StringValueCommand(String value) {
-    this.value = value;
-  }
-
-  @Override
-  public String getValue() {
-    return value;
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    visitor.visit(this, ctx);
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/ThrowCommand.java b/user/src/com/google/gwt/rpc/client/ast/ThrowCommand.java
deleted file mode 100644
index f8057a8..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/ThrowCommand.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor.Context;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A command to indicate that a value was thrown by the remote side.
- */
-public class ThrowCommand extends RpcCommand implements HasValues {
-  private ValueCommand toThrow;
-
-  public void addValue(ValueCommand value) {
-    assert toThrow == null;
-    toThrow = value;
-  }
-
-  public ValueCommand getThrownValue() {
-    return toThrow;
-  }
-
-  public List<ValueCommand> getValues() {
-    return Collections.singletonList(toThrow);
-  }
-
-  @Override
-  public void traverse(RpcCommandVisitor visitor, Context ctx) {
-    if (visitor.visit(this, ctx)) {
-      visitor.accept(toThrow);
-    }
-    visitor.endVisit(this, ctx);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/ast/ValueCommand.java b/user/src/com/google/gwt/rpc/client/ast/ValueCommand.java
deleted file mode 100644
index 08b170f..0000000
--- a/user/src/com/google/gwt/rpc/client/ast/ValueCommand.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.ast;
-
-/**
- * Represents an atomic value.
- */
-public abstract class ValueCommand extends RpcCommand {
-  protected ValueCommand() {
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/ClientWriterFactory.java b/user/src/com/google/gwt/rpc/client/impl/ClientWriterFactory.java
deleted file mode 100644
index a9ab98a..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/ClientWriterFactory.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.server.CommandServerSerializationStreamReader;
-import com.google.gwt.rpc.server.CommandServerSerializationStreamWriter;
-import com.google.gwt.rpc.server.HostedModeClientOracle;
-import com.google.gwt.rpc.server.SimplePayloadDecoder;
-import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-import java.util.Collections;
-
-/**
- * Isolates client code from swapping out the command factory in hosted versus
- * Production Mode. This type has a super-source peer which is used in
- * Production Mode.
- */
-public class ClientWriterFactory {
-
-  public static SerializationStreamReader createReader(String payload)
-      throws IncompatibleRemoteServiceException, RemoteException {
-    SimplePayloadDecoder decoder;
-    try {
-      decoder = new SimplePayloadDecoder(new HostedModeClientOracle(), payload);
-    } catch (ClassNotFoundException e) {
-      throw new IncompatibleRemoteServiceException(
-          "Client does not have a type sent by the server", e);
-    }
-    CommandServerSerializationStreamReader reader = new CommandServerSerializationStreamReader();
-    if (decoder.getThrownValue() != null) {
-      reader.prepareToRead(Collections.singletonList(decoder.getThrownValue()));
-      try {
-        throw new RemoteException((Throwable) reader.readObject());
-      } catch (ClassCastException e) {
-        throw new RemoteException(
-            "The remote end threw something other than a Throwable", e);
-      } catch (SerializationException e) {
-        throw new RemoteException(
-            "The remote end threw an exception which could not be deserialized",
-            e);
-      }
-    } else {
-      reader.prepareToRead(decoder.getValues());
-    }
-    return reader;
-  }
-
-  @SuppressWarnings("unused") // used by super-source peer
-  public static SerializationStreamWriter createWriter(
-      TypeOverrides typeOverrides, CommandSink commandSink) {
-    return new CommandServerSerializationStreamWriter(commandSink);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/CommandClientSerializationStreamReader.java b/user/src/com/google/gwt/rpc/client/impl/CommandClientSerializationStreamReader.java
deleted file mode 100644
index 83586a0..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/CommandClientSerializationStreamReader.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.core.client.JavaScriptException;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.core.client.UnsafeNativeLong;
-import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-
-/**
- * A peer to CommandServerSerializationStreamWriter.
- */
-public class CommandClientSerializationStreamReader implements
-    SerializationStreamReader {
-
-  /**
-   * An identifier in the payload evaluation context that is used to hold
-   * backreferences.
-   */
-  public static final String BACKREF_IDENT = "_";
-
-  private static native JsArray<JavaScriptObject> eval(String payload) /*-{
-    return eval(payload);
-  }-*/;
-
-  private static native boolean readBoolean0(JavaScriptObject obj, int idx) /*-{
-    return !!obj[idx];
-  }-*/;
-
-  private static native byte readByte0(JavaScriptObject obj, int idx) /*-{
-    return obj[idx];
-  }-*/;
-
-  private static native char readChar0(JavaScriptObject obj, int idx) /*-{
-    return obj[idx];
-  }-*/;
-
-  private static native double readDouble0(JavaScriptObject obj, int idx) /*-{
-    return obj[idx];
-  }-*/;
-
-  private static native float readFloat0(JavaScriptObject obj, int idx) /*-{
-    return obj[idx];
-  }-*/;
-
-  private static native int readInt0(JavaScriptObject obj, int idx) /*-{
-    return obj[idx];
-  }-*/;
-
-  @UnsafeNativeLong
-  private static native long readLong0(JavaScriptObject obj, int idx) /*-{
-    return obj[idx];
-  }-*/;
-
-  private static native Object readObject0(JavaScriptObject obj, int idx) /*-{
-    return obj[idx];
-  }-*/;
-
-  private static native short readShort0(JavaScriptObject obj, int idx) /*-{
-    return obj[idx];
-  }-*/;
-
-  private static native String readString0(JavaScriptObject obj, int idx) /*-{
-    return obj[idx];
-  }-*/;
-
-  // This field may be reset externally
-  volatile int idx = 0;
-  volatile JsArray<JavaScriptObject> payload;
-
-  public void prepareToRead(String js) throws RemoteException {
-    try {
-      payload = eval("(function(){var " + BACKREF_IDENT + "={};" + js + "})()");
-      assert payload != null : "Payload evaluated to null";
-    } catch (JavaScriptException e) {
-      throw new IncompatibleRemoteServiceException(
-          "Unable to evaluate payload", e);
-    } catch (Throwable e) {
-      throw new RemoteException("Unable to evaluate payload", e);
-    }
-  }
-
-  public boolean readBoolean() throws SerializationException {
-    assert idx < payload.length() : "Attempting to read beyond end of payload";
-    return readBoolean0(payload, idx++);
-  }
-
-  public byte readByte() throws SerializationException {
-    assert idx < payload.length() : "Attempting to read beyond end of payload";
-    return readByte0(payload, idx++);
-  }
-
-  public char readChar() throws SerializationException {
-    assert idx < payload.length() : "Attempting to read beyond end of payload";
-    return readChar0(payload, idx++);
-  }
-
-  public double readDouble() throws SerializationException {
-    assert idx < payload.length() : "Attempting to read beyond end of payload";
-    return readDouble0(payload, idx++);
-  }
-
-  public float readFloat() throws SerializationException {
-    assert idx < payload.length() : "Attempting to read beyond end of payload";
-    return readFloat0(payload, idx++);
-  }
-
-  public int readInt() throws SerializationException {
-    assert idx < payload.length() : "Attempting to read beyond end of payload";
-    return readInt0(payload, idx++);
-  }
-
-  public long readLong() throws SerializationException {
-    assert idx < payload.length() : "Attempting to read beyond end of payload";
-    return readLong0(payload, idx++);
-  }
-
-  public Object readObject() throws SerializationException {
-    assert idx < payload.length() : "Attempting to read beyond end of payload";
-    return readObject0(payload, idx++);
-  }
-
-  public short readShort() throws SerializationException {
-    assert idx < payload.length() : "Attempting to read beyond end of payload";
-    return readShort0(payload, idx++);
-  }
-
-  public String readString() throws SerializationException {
-    assert idx < payload.length() : "Attempting to read beyond end of payload";
-    return readString0(payload, idx++);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/CommandClientSerializationStreamWriter.java b/user/src/com/google/gwt/rpc/client/impl/CommandClientSerializationStreamWriter.java
deleted file mode 100644
index 14416e3..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/CommandClientSerializationStreamWriter.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.core.client.UnsafeNativeLong;
-import com.google.gwt.rpc.client.ast.ArrayValueCommand;
-import com.google.gwt.rpc.client.ast.BooleanValueCommand;
-import com.google.gwt.rpc.client.ast.CharValueCommand;
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.client.ast.DoubleValueCommand;
-import com.google.gwt.rpc.client.ast.EnumValueCommand;
-import com.google.gwt.rpc.client.ast.HasSetters;
-import com.google.gwt.rpc.client.ast.IdentityValueCommand;
-import com.google.gwt.rpc.client.ast.InstantiateCommand;
-import com.google.gwt.rpc.client.ast.InvokeCustomFieldSerializerCommand;
-import com.google.gwt.rpc.client.ast.LongValueCommand;
-import com.google.gwt.rpc.client.ast.NullValueCommand;
-import com.google.gwt.rpc.client.ast.StringValueCommand;
-import com.google.gwt.rpc.client.ast.ValueCommand;
-import com.google.gwt.rpc.client.impl.TypeOverrides.SerializeFunction;
-import com.google.gwt.user.client.rpc.IsSerializable;
-import com.google.gwt.user.client.rpc.SerializationException;
-
-import java.io.Serializable;
-import java.util.IdentityHashMap;
-import java.util.Map;
-
-/**
- * Provides a facade around serialization logic in client code.
- */
-public class CommandClientSerializationStreamWriter extends
-    CommandSerializationStreamWriterBase {
-
-  private static Object anObject = new Object[] {};
-
-  static {
-    // Don't need to explicitly filter $H
-    anObject.hashCode();
-  }
-
-  private final Map<Object, IdentityValueCommand> identityMap;
-  private final TypeOverrides serializer;
-
-  public CommandClientSerializationStreamWriter(TypeOverrides serializer,
-      CommandSink sink) {
-    this(serializer, sink, new IdentityHashMap<Object, IdentityValueCommand>());
-  }
-
-  private CommandClientSerializationStreamWriter(TypeOverrides serializer,
-      CommandSink sink, Map<Object, IdentityValueCommand> identityMap) {
-    super(sink);
-    this.serializer = serializer;
-    this.identityMap = identityMap;
-  }
-
-  /**
-   * Type is passed in to handle primitive types.
-   */
-  @Override
-  protected ValueCommand makeValue(Class<?> type, Object value)
-      throws SerializationException {
-    SerializeFunction customSerializer;
-    ValueCommand toReturn;
-
-    if (value == null) {
-      toReturn = NullValueCommand.INSTANCE;
-    } else if (type.isPrimitive()) {
-      if (type == boolean.class) {
-        toReturn = new BooleanValueCommand((Boolean) value);
-      } else if (type == void.class) {
-        toReturn = NullValueCommand.INSTANCE;
-      } else if (type == long.class) {
-        toReturn = new LongValueCommand((Long) value);
-      } else if (type == char.class) {
-        toReturn = new CharValueCommand((Character) value);
-      } else {
-        assert value instanceof Number : "Expecting Number; had "
-            + value.getClass().getName();
-        toReturn = new DoubleValueCommand(((Number) value).doubleValue());
-      }
-
-    } else if ((toReturn = identityMap.get(value)) != null) {
-      // Fall through
-
-    } else if (type == String.class) {
-      toReturn = new StringValueCommand((String) value);
-
-    } else if (type.isArray()) {
-      ArrayValueCommand array = new ArrayValueCommand(type.getComponentType());
-      identityMap.put(value, array);
-      extractData(array, value);
-      toReturn = array;
-
-    } else if (value instanceof Enum<?>) {
-      EnumValueCommand e = new EnumValueCommand();
-      e.setValue((Enum<?>) value);
-      toReturn = e;
-
-    } else if ((customSerializer = serializer.getOverride(type.getName())) != null) {
-      toReturn = invokeCustomSerializer(customSerializer, type, value);
-
-    } else {
-      toReturn = makeObject(type, value);
-    }
-
-    return toReturn;
-  }
-
-  private native void extractData(ArrayValueCommand x, Object obj) /*-{
-    for (var i = 0, j = obj.length; i < j; i++) {
-      var value = this.@com.google.gwt.rpc.client.impl.CommandClientSerializationStreamWriter::makeValue(Ljava/lang/Object;)(obj[i]);
-      x.@com.google.gwt.rpc.client.ast.ArrayValueCommand::add(Lcom/google/gwt/rpc/client/ast/ValueCommand;)(value);
-    }
-  }-*/;
-
-  private native void extractData(HasSetters x, Object obj) /*-{
-    for (var key in obj) {
-      // Ignore common properties
-      if (key in @com.google.gwt.rpc.client.impl.CommandClientSerializationStreamWriter::anObject) {
-        continue;
-      }
-      this.@com.google.gwt.rpc.client.impl.CommandClientSerializationStreamWriter::extractField(Lcom/google/gwt/rpc/client/ast/HasSetters;Ljava/lang/Object;Ljava/lang/String;)(x,obj,key);
-    }
-  }-*/;
-
-  private native void extractField(HasSetters x, Object obj, String key) /*-{
-    var command = this.@com.google.gwt.rpc.client.impl.CommandClientSerializationStreamWriter::makeValue(Ljava/lang/Object;)(obj[key]);
-
-    // makeValue may return undefined
-    command && x.@com.google.gwt.rpc.client.ast.HasSetters::set(Ljava/lang/Class;Ljava/lang/String;Lcom/google/gwt/rpc/client/ast/ValueCommand;)(null, key, command);
-  }-*/;
-
-  private ValueCommand invokeCustomSerializer(
-      SerializeFunction serializeFunction, Class<?> type, Object value) {
-    InvokeCustomFieldSerializerCommand command = new InvokeCustomFieldSerializerCommand(
-        type, null, null);
-    identityMap.put(value, command);
-
-    /*
-     * Pass the current identityMap into the new writer to allow circular
-     * references through the graph emitted by the CFS.
-     */
-    CommandClientSerializationStreamWriter subWriter = new CommandClientSerializationStreamWriter(
-        serializer, new HasValuesCommandSink(command), identityMap);
-
-    serializeFunction.serialize(subWriter, value);
-    if (serializer.hasExtraFields(type.getName())) {
-      for (String extraField : serializer.getExtraFields(type.getName())) {
-        if (extraField != null) {
-          // Sometimes fields might be pruned
-          extractField(command, value, extraField);
-        }
-      }
-    }
-    return command;
-  }
-
-  private ValueCommand makeObject(Class<?> clazz, Object value)
-      throws SerializationException {
-    if (!(value instanceof Serializable || value instanceof IsSerializable)) {
-      throw new SerializationException(clazz.getName()
-          + " is not a Serializable type");
-    }
-    InstantiateCommand x = new InstantiateCommand(clazz);
-    identityMap.put(value, x);
-
-    if (serializer.hasExtraFields(clazz.getName())) {
-      // Objects with transient fields or non-trivial semantics
-      for (String fieldName : serializer.getExtraFields(clazz.getName())) {
-        extractField(x, value, fieldName);
-      }
-    } else {
-      // Just a for-in loop
-      extractData(x, value);
-    }
-    return x;
-  }
-
-  @UnsafeNativeLong
-  private native ValueCommand makeValue(Object value) /*-{
-    var type;
-    if (value) {
-      // Maybe turn objects into primitives
-      value.valueOf && (value = value.valueOf());
-
-      // See if the value is our web-mode representation of a long
-      if (value.hasOwnProperty('l') && value.hasOwnProperty('m') && value.hasOwnProperty('h')) {
-        type = 'long';
-      }
-    }
-    type || (type = typeof value);
-
-    switch (type) {
-      case 'boolean':
-        return @com.google.gwt.rpc.client.ast.BooleanValueCommand::new(Z)(value);
-
-      case 'number':
-        return @com.google.gwt.rpc.client.ast.DoubleValueCommand::new(D)(value);
-
-      case 'string':
-        return @com.google.gwt.rpc.client.ast.StringValueCommand::new(Ljava/lang/String;)(value);
-
-      case 'long':
-        return @com.google.gwt.rpc.client.ast.LongValueCommand::new(J)(value);
-
-      case 'function':
-        // Not serializable
-        break;
-
-      case 'object':
-        // typeof null == 'object'
-        if (!value) {
-          return @com.google.gwt.rpc.client.ast.NullValueCommand::INSTANCE;
-        }
-
-        if (!value.@java.lang.Object::typeMarker) {
-          // Not a Java object
-          break;
-        }
-
-        return this.@com.google.gwt.rpc.client.impl.CommandClientSerializationStreamWriter::makeValue(Ljava/lang/Class;Ljava/lang/Object;)(value.@java.lang.Object::getClass()(), value);
-
-      case 'undefined':
-        // typeof undefined == 'undefined', but we treat it as null
-        return @com.google.gwt.rpc.client.ast.NullValueCommand::INSTANCE;
-
-      default:
-        throw @java.lang.RuntimeException::new(Ljava/lang/String;)('Unknown type ' + type);
-    }
-
-    // Intentionally return undefined
-  }-*/;
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/CommandSerializationStreamWriterBase.java b/user/src/com/google/gwt/rpc/client/impl/CommandSerializationStreamWriterBase.java
deleted file mode 100644
index 887ee11..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/CommandSerializationStreamWriterBase.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.client.ast.ValueCommand;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-/**
- * Contains base methods for implementing a SerializationStreamWriter.
- */
-public abstract class CommandSerializationStreamWriterBase implements
-    SerializationStreamWriter {
-
-  private final CommandSink commandSink;
-
-  protected CommandSerializationStreamWriterBase(CommandSink sink) {
-    this.commandSink = sink;
-  }
-
-  public void writeBoolean(boolean value) throws SerializationException {
-    commandSink.accept(makeValue(boolean.class, value));
-  }
-
-  public void writeByte(byte value) throws SerializationException {
-    commandSink.accept(makeValue(byte.class, value));
-  }
-
-  public void writeChar(char value) throws SerializationException {
-    commandSink.accept(makeValue(char.class, value));
-  }
-
-  public void writeDouble(double value) throws SerializationException {
-    commandSink.accept(makeValue(double.class, value));
-  }
-
-  public void writeFloat(float value) throws SerializationException {
-    commandSink.accept(makeValue(float.class, value));
-  }
-
-  public void writeInt(int value) throws SerializationException {
-    commandSink.accept(makeValue(int.class, value));
-  }
-
-  public void writeLong(long value) throws SerializationException {
-    commandSink.accept(makeValue(long.class, value));
-  }
-
-  public void writeObject(Object instance) throws SerializationException {
-    commandSink.accept(makeValue(instance != null ? instance.getClass()
-        : void.class, instance));
-  }
-
-  public void writeShort(short value) throws SerializationException {
-    commandSink.accept(makeValue(short.class, value));
-  }
-
-  public void writeString(String value) throws SerializationException {
-    commandSink.accept(makeValue(String.class, value));
-  }
-
-  protected final CommandSink getCommandSink() {
-    return commandSink;
-  }
-
-  protected abstract ValueCommand makeValue(Class<?> type, Object value)
-      throws SerializationException;
-
-}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/rpc/client/impl/CommandToStringWriter.java b/user/src/com/google/gwt/rpc/client/impl/CommandToStringWriter.java
deleted file mode 100644
index e1f1fd8..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/CommandToStringWriter.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.client.ast.ReturnCommand;
-import com.google.gwt.rpc.client.ast.RpcCommand;
-import com.google.gwt.rpc.client.ast.ValueCommand;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-/**
- * Existing code assumes that a SerializationStreamWriter will export its
- * payload via the toString() method. This uses an internal CommandSink and
- * creates a string payload on-demand.
- */
-public class CommandToStringWriter implements SerializationStreamWriter {
-
-  private static class ToStringCommandSink extends CommandSink {
-    private final ReturnCommand retCommand = new ReturnCommand();
-
-    @Override
-    public void accept(RpcCommand command) throws SerializationException {
-      retCommand.addValue((ValueCommand) command);
-    }
-
-    @Override
-    public void finish() throws SerializationException {
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder();
-      SimplePayloadSink sink = new SimplePayloadSink(sb);
-      try {
-        sink.accept(retCommand);
-        sink.finish();
-      } catch (SerializationException e) {
-        throw new RuntimeException("Unable to create payload", e);
-      }
-      return sb.toString();
-    }
-  }
-
-  private final ToStringCommandSink commandSink = new ToStringCommandSink();
-  private final SerializationStreamWriter writer;
-
-  public CommandToStringWriter(TypeOverrides overrides) {
-    writer = ClientWriterFactory.createWriter(overrides, commandSink);
-  }
-
-  @Override
-  public String toString() {
-    return commandSink.toString();
-  }
-
-  public void writeBoolean(boolean value) throws SerializationException {
-    writer.writeBoolean(value);
-  }
-
-  public void writeByte(byte value) throws SerializationException {
-    writer.writeByte(value);
-  }
-
-  public void writeChar(char value) throws SerializationException {
-    writer.writeChar(value);
-  }
-
-  public void writeDouble(double value) throws SerializationException {
-    writer.writeDouble(value);
-  }
-
-  public void writeFloat(float value) throws SerializationException {
-    writer.writeFloat(value);
-  }
-
-  public void writeInt(int value) throws SerializationException {
-    writer.writeInt(value);
-  }
-
-  public void writeLong(long value) throws SerializationException {
-    writer.writeLong(value);
-  }
-
-  public void writeObject(Object value) throws SerializationException {
-    writer.writeObject(value);
-  }
-
-  public void writeShort(short value) throws SerializationException {
-    writer.writeShort(value);
-  }
-
-  public void writeString(String value) throws SerializationException {
-    writer.writeString(value);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/EscapeUtil.java b/user/src/com/google/gwt/rpc/client/impl/EscapeUtil.java
deleted file mode 100644
index 9db3edf..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/EscapeUtil.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.rpc.impl.ClientSerializationStreamWriter;
-import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter;
-
-/**
- * Provides the JVM implementations for payload escaping.
- */
-public class EscapeUtil {
-  public static String escape(String payload) {
-    if (GWT.isClient()) {
-      return ClientSerializationStreamWriter.quoteString(payload);
-    } else {
-      String quoted = ServerSerializationStreamWriter.escapeString(payload);
-      return quoted.substring(1, quoted.length() - 1);
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/HasValuesCommandSink.java b/user/src/com/google/gwt/rpc/client/impl/HasValuesCommandSink.java
deleted file mode 100644
index e975334..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/HasValuesCommandSink.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.client.ast.HasValues;
-import com.google.gwt.rpc.client.ast.RpcCommand;
-import com.google.gwt.rpc.client.ast.ValueCommand;
-import com.google.gwt.user.client.rpc.SerializationException;
-
-/**
- * A simple CommandSink that adds observed values to a container command.
- */
-public class HasValuesCommandSink extends CommandSink {
-  private HasValues container;
-
-  public HasValuesCommandSink(HasValues container) {
-    this.container = container;
-  }
-
-  @Override
-  public void accept(RpcCommand command) throws SerializationException {
-    if (!(command instanceof ValueCommand)) {
-      throw new SerializationException(command.getClass().getName());
-    }
-    container.addValue((ValueCommand) command);
-  }
-
-  /**
-   * Does nothing.
-   */
-  @Override
-  public void finish() throws SerializationException {
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/ListCommandSink.java b/user/src/com/google/gwt/rpc/client/impl/ListCommandSink.java
deleted file mode 100644
index 9514649..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/ListCommandSink.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.client.ast.RpcCommand;
-import com.google.gwt.user.client.rpc.SerializationException;
-
-import java.util.List;
-
-/**
- * A simple CommandSink that adds observed commands to a list.
- */
-public class ListCommandSink extends CommandSink {
-  private List<RpcCommand> commands;
-
-  public ListCommandSink(List<RpcCommand> commands) {
-    this.commands = commands;
-  }
-
-  @Override
-  public void accept(RpcCommand command) throws SerializationException {
-    commands.add(command);
-  }
-
-  /**
-   * Does nothing.
-   */
-  @Override
-  public void finish() throws SerializationException {
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/RemoteException.java b/user/src/com/google/gwt/rpc/client/impl/RemoteException.java
deleted file mode 100644
index e0205ed..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/RemoteException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-/**
- * A wrapper exception type indicating that the remote end threw an exception
- * over the wire.
- */
-public class RemoteException extends RuntimeException {
-  public RemoteException() {
-  }
-
-  public RemoteException(String msg, Throwable cause) {
-    super(msg, cause);
-  }
-
-  public RemoteException(Throwable cause) {
-    super(cause);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/RpcCallbackAdapter.java b/user/src/com/google/gwt/rpc/client/impl/RpcCallbackAdapter.java
deleted file mode 100644
index dd51a95..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/RpcCallbackAdapter.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.rpc.client.impl;
-
-import com.google.gwt.http.client.Request;
-import com.google.gwt.http.client.RequestCallback;
-import com.google.gwt.http.client.Response;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
-import com.google.gwt.user.client.rpc.InvocationException;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamFactory;
-import com.google.gwt.user.client.rpc.StatusCodeException;
-import com.google.gwt.user.client.rpc.impl.RpcStatsContext;
-
-/**
- * Adapter from a {@link RequestCallback} interface to an {@link AsyncCallback}
- * interface.
- * 
- * For internal use only.
- * 
- * @param <T> the type parameter for the {@link AsyncCallback}
- */
-public class RpcCallbackAdapter<T> implements RequestCallback {
-
-  /**
-   * {@link AsyncCallback} to notify or success or failure.
-   */
-  private final AsyncCallback<T> callback;
-
-  /**
-   * Used for stats recording.
-   */
-  private final String methodName;
-
-  /**
-   * Used for stats recording.
-   */
-  private final RpcStatsContext statsContext;
-
-  private final SerializationStreamFactory streamFactory;
-
-  public RpcCallbackAdapter(SerializationStreamFactory streamFactory,
-      String methodName, RpcStatsContext statsContext, AsyncCallback<T> callback) {
-    assert (streamFactory != null);
-    assert (callback != null);
-
-    this.streamFactory = streamFactory;
-    this.callback = callback;
-    this.methodName = methodName;
-    this.statsContext = statsContext;
-  }
-
-  public void onError(Request request, Throwable exception) {
-    callback.onFailure(exception);
-  }
-
-  @SuppressWarnings(value = {"unchecked", "unused"})
-  public void onResponseReceived(Request request, Response response) {
-    T result = null;
-    Throwable caught = null;
-    try {
-      String encodedResponse = response.getText();
-      int statusCode = response.getStatusCode();
-      boolean toss = statsContext.isStatsAvailable()
-          && statsContext.stats(
-              statsContext.bytesStat(methodName, encodedResponse.length(), "responseReceived"));
-
-      if (statusCode != Response.SC_OK) {
-        caught = new StatusCodeException(statusCode, response.getStatusText(), encodedResponse);
-      } else if (encodedResponse == null) {
-        // This can happen if the XHR is interrupted by the server dying
-        caught = new InvocationException("No response payload from " + methodName);
-      } else {
-        result = (T) streamFactory.createStreamReader(encodedResponse).readObject();
-      }
-    } catch (RemoteException e) {
-      caught = e.getCause();
-    } catch (SerializationException e) {
-      caught = new IncompatibleRemoteServiceException(
-          "The response could not be deserialized", e);
-    } catch (Throwable e) {
-      caught = e;
-    } finally {
-      boolean toss = statsContext.isStatsAvailable()
-          && statsContext.stats(statsContext.timeStat(methodName, "responseDeserialized"));
-    }
-
-    try {
-      if (caught == null) {
-        callback.onSuccess(result);
-      } else {
-        callback.onFailure(caught);
-      }
-    } finally {
-      boolean toss = statsContext.isStatsAvailable()
-          && statsContext.stats(statsContext.timeStat(methodName, "end"));
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/RpcServiceProxy.java b/user/src/com/google/gwt/rpc/client/impl/RpcServiceProxy.java
deleted file mode 100644
index ceb4df0..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/RpcServiceProxy.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.http.client.RequestCallback;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-import com.google.gwt.user.client.rpc.impl.RemoteServiceProxy;
-import com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter.ResponseReader;
-import com.google.gwt.user.client.rpc.impl.RpcStatsContext;
-
-/**
- * The base type for RPC proxies.
- */
-public class RpcServiceProxy extends RemoteServiceProxy {
-  private final TypeOverrides typeOverrides;
-
-  protected RpcServiceProxy(String moduleBaseURL,
-      String remoteServiceRelativePath, TypeOverrides typeOverrides) {
-    super(moduleBaseURL, remoteServiceRelativePath,
-        GWT.getPermutationStrongName(), null);
-    this.typeOverrides = typeOverrides;
-  }
-
-  @Override
-  public SerializationStreamReader createStreamReader(String encoded)
-      throws SerializationException, RemoteException {
-    return ClientWriterFactory.createReader(encoded);
-  }
-
-  @Override
-  public SerializationStreamWriter createStreamWriter() {
-    return new CommandToStringWriter(typeOverrides);
-  }
-
-  @Override
-  protected <T> RequestCallback doCreateRequestCallback(
-      ResponseReader responseReader, String methodName, RpcStatsContext statsContext,
-      AsyncCallback<T> callback) {
-    return new RpcCallbackAdapter<T>(this, methodName, statsContext,
-        callback);
-  }
-
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/SimplePayloadSink.java b/user/src/com/google/gwt/rpc/client/impl/SimplePayloadSink.java
deleted file mode 100644
index 1d32d93..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/SimplePayloadSink.java
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.rpc.client.ast.ArrayValueCommand;
-import com.google.gwt.rpc.client.ast.BooleanValueCommand;
-import com.google.gwt.rpc.client.ast.ByteValueCommand;
-import com.google.gwt.rpc.client.ast.CharValueCommand;
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.client.ast.DoubleValueCommand;
-import com.google.gwt.rpc.client.ast.EnumValueCommand;
-import com.google.gwt.rpc.client.ast.FloatValueCommand;
-import com.google.gwt.rpc.client.ast.InstantiateCommand;
-import com.google.gwt.rpc.client.ast.IntValueCommand;
-import com.google.gwt.rpc.client.ast.InvokeCustomFieldSerializerCommand;
-import com.google.gwt.rpc.client.ast.LongValueCommand;
-import com.google.gwt.rpc.client.ast.NullValueCommand;
-import com.google.gwt.rpc.client.ast.ReturnCommand;
-import com.google.gwt.rpc.client.ast.RpcCommand;
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor;
-import com.google.gwt.rpc.client.ast.SetCommand;
-import com.google.gwt.rpc.client.ast.ShortValueCommand;
-import com.google.gwt.rpc.client.ast.StringValueCommand;
-import com.google.gwt.rpc.client.ast.ThrowCommand;
-import com.google.gwt.rpc.client.ast.ValueCommand;
-import com.google.gwt.user.client.rpc.SerializationException;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * This implementation of CommandSink encodes RpcCommands in a simple transport
- * format that can be interpreted by both the client and the server.
- */
-public class SimplePayloadSink extends CommandSink {
-
-  private class Visitor extends RpcCommandVisitor {
-
-    @Override
-    public void endVisit(BooleanValueCommand x, Context ctx) {
-      appendTypedData(BOOLEAN_TYPE, x.getValue() ? "1" : "0");
-    }
-
-    @Override
-    public void endVisit(ByteValueCommand x, Context ctx) {
-      appendTypedData(BYTE_TYPE, x.getValue().toString());
-    }
-
-    @Override
-    public void endVisit(CharValueCommand x, Context ctx) {
-      appendTypedData(CHAR_TYPE, String.valueOf((int) x.getValue()));
-    }
-
-    @Override
-    public void endVisit(DoubleValueCommand x, Context ctx) {
-      appendTypedData(DOUBLE_TYPE, x.getValue().toString());
-    }
-
-    @Override
-    public void endVisit(EnumValueCommand x, Context ctx) {
-      // ETypeSeedName~IOrdinal~
-      if (appendIdentity(x)) {
-        appendTypedData(ENUM_TYPE, x.getValue().getDeclaringClass().getName());
-        // use ordinal (and not name), since name might have been obfuscated
-        appendTypedData(INT_TYPE, String.valueOf(x.getValue().ordinal()));
-      }
-    }
-
-    @Override
-    public void endVisit(FloatValueCommand x, Context ctx) {
-      appendTypedData(FLOAT_TYPE, x.getValue().toString());
-    }
-
-    @Override
-    public void endVisit(IntValueCommand x, Context ctx) {
-      appendTypedData(INT_TYPE, x.getValue().toString());
-    }
-
-    @Override
-    public void endVisit(LongValueCommand x, Context ctx) {
-      appendTypedData(LONG_TYPE, x.getValue().toString());
-    }
-
-    @Override
-    public void endVisit(NullValueCommand x, Context ctx) {
-      appendTypedData(VOID_TYPE, "");
-    }
-
-    @Override
-    public void endVisit(ShortValueCommand x, Context ctx) {
-      appendTypedData(SHORT_TYPE, x.getValue().toString());
-    }
-
-    @Override
-    public void endVisit(StringValueCommand x, Context ctx) {
-      // "4~abcd
-      if (appendIdentity(x)) {
-        String value = x.getValue();
-        /*
-         * Emit this a a Pascal-style string, using an explicit length. This
-         * avoids the need to escape the value.
-         */
-        appendTypedData(STRING_TYPE, String.valueOf(value.length()));
-        append(value);
-      }
-    }
-
-    @Override
-    public boolean visit(ArrayValueCommand x, Context ctx) {
-      /*
-       * Encoded as (leafType, dimensions, length, .... )
-       * 
-       * Object[] foo = new Object[3];
-       * 
-       * becomes
-       * 
-       * [ObjectSeedname~1~3~@....~@....~@...~
-       * 
-       * Object[][] foo = new Object[3][];
-       * 
-       * becomes
-       * 
-       * [ObjectSeedName~2~3~...three one-dim arrays...
-       */
-      if (appendIdentity(x)) {
-        int dims = 1;
-        Class<?> leaf = x.getComponentType();
-        while (leaf.getComponentType() != null) {
-          dims++;
-          leaf = leaf.getComponentType();
-        }
-
-        appendTypedData(ARRAY_TYPE, leaf.getName());
-        accept(new IntValueCommand(dims));
-        accept(new IntValueCommand(x.getComponentValues().size()));
-        return true;
-      } else {
-        return false;
-      }
-    }
-
-    @Override
-    public boolean visit(InstantiateCommand x, Context ctx) {
-      // @TypeSeedName~3~... N-many setters ...
-      if (appendIdentity(x)) {
-        appendTypedData(OBJECT_TYPE, x.getTargetClass().getName());
-        accept(new IntValueCommand(x.getSetters().size()));
-        return true;
-      } else {
-        return false;
-      }
-    }
-
-    @Override
-    public boolean visit(InvokeCustomFieldSerializerCommand x, Context ctx) {
-      // !TypeSeedName~Number of objects written by CFS~...CFS objects...~
-      // Number of extra fields~...N-many setters...
-      if (appendIdentity(x)) {
-        appendTypedData(INVOKE_TYPE, x.getTargetClass().getName());
-        accept(new IntValueCommand(x.getValues().size()));
-        accept(x.getValues());
-        accept(new IntValueCommand(x.getSetters().size()));
-        accept(x.getSetters());
-        return false;
-      } else {
-        return false;
-      }
-    }
-
-    @Override
-    public boolean visit(ReturnCommand x, Context ctx) {
-      // R4~...values...
-      appendTypedData(RETURN_TYPE, String.valueOf(x.getValues().size()));
-      return true;
-    }
-
-    @Override
-    public boolean visit(SetCommand x, Context ctx) {
-      /*
-       * In Development Mode, the field's declaring class is written to the
-       * stream to handle field shadowing. In Production Mode, this isn't
-       * necessary because all field names are allocated in the same "object"
-       * scope.
-       *
-       * DeclaringClassName~FieldName~...value...
-       */
-      if (!GWT.isScript()) {
-        accept(new StringValueCommand(x.getFieldDeclClass().getName()));
-      }
-      accept(new StringValueCommand(x.getField()));
-      return true;
-    }
-
-    @Override
-    public boolean visit(ThrowCommand x, Context ctx) {
-      // T...value...
-      appendTypedData(THROW_TYPE, "");
-      return true;
-    }
-
-    private void append(String x) {
-      try {
-        buffer.append(EscapeUtil.escape(x)).append(RPC_SEPARATOR_CHAR);
-      } catch (IOException e) {
-        halt(e);
-      }
-    }
-
-    private boolean appendIdentity(ValueCommand x) {
-      Integer backRef = backRefs.get(x);
-      if (backRef != null) {
-        if (PRETTY) {
-          try {
-            buffer.append(NL_CHAR);
-          } catch (IOException e) {
-            halt(e);
-          }
-        }
-        append(BACKREF_TYPE + String.valueOf(backRef));
-        return false;
-      } else {
-        backRefs.put(x, backRefs.size());
-        return true;
-      }
-    }
-
-    private void appendTypedData(char type, String value) {
-      try {
-        if (PRETTY) {
-          buffer.append(NL_CHAR);
-        }
-        buffer.append(type).append(value).append(RPC_SEPARATOR_CHAR);
-      } catch (IOException e) {
-        halt(e);
-      }
-    }
-  }
-
-  /**
-   * Used for diagnostics.
-   */
-  static final boolean PRETTY = false;
-
-  public static final char ARRAY_TYPE = '[';
-  public static final char BACKREF_TYPE = '@';
-  public static final char BOOLEAN_TYPE = 'Z';
-  public static final char BYTE_TYPE = 'B';
-  public static final char CHAR_TYPE = 'C';
-  public static final char DOUBLE_TYPE = 'D';
-  public static final char ENUM_TYPE = 'E';
-  public static final char FLOAT_TYPE = 'F';
-  public static final char INT_TYPE = 'I';
-  public static final char INVOKE_TYPE = '!';
-  public static final char LONG_TYPE = 'J';
-  public static final char NL_CHAR = '\n';
-  public static final char OBJECT_TYPE = 'L';
-  public static final char RETURN_TYPE = 'R';
-  public static final char RPC_SEPARATOR_CHAR = '~';
-  public static final char SHORT_TYPE = 'S';
-  public static final char STRING_TYPE = '"';
-  public static final char THROW_TYPE = 'T';
-  public static final char VOID_TYPE = 'V';
-
-  private final Map<ValueCommand, Integer> backRefs = new HashMap<ValueCommand, Integer>();
-
-  private final Appendable buffer;
-
-  public SimplePayloadSink(Appendable buffer) {
-    this.buffer = buffer;
-  }
-
-  @Override
-  public void accept(RpcCommand command) throws SerializationException {
-    (new Visitor()).accept(command);
-  }
-
-  @Override
-  public void finish() throws SerializationException {
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/client/impl/TypeOverrides.java b/user/src/com/google/gwt/rpc/client/impl/TypeOverrides.java
deleted file mode 100644
index 02040c0..0000000
--- a/user/src/com/google/gwt/rpc/client/impl/TypeOverrides.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-/**
- * Contains serialization dispatch information for types that don't support
- * simple serialization.
- */
-public final class TypeOverrides extends JavaScriptObject {
-  /**
-   * An individual entry, which is a wrapper around the CFS's serialize method.
-   */
-  public static final class SerializeFunction extends JavaScriptObject {
-    protected SerializeFunction() {
-    }
-
-    public native void serialize(SerializationStreamWriter writer,
-        Object instance) /*-{
-      this(writer, instance);
-    }-*/;
-  }
-
-  public static TypeOverrides create() {
-    return JavaScriptObject.createObject().cast();
-  }
-
-  protected TypeOverrides() {
-  }
-
-  public native String[] getExtraFields(String className) /*-{
-    return this['B' + className];
-  }-*/;
-
-  public native SerializeFunction getOverride(String className) /*-{
-    return this['A' + className];
-  }-*/;
-
-  public native boolean hasExtraFields(String className) /*-{
-    return !!this['B' + className];
-  }-*/;
-
-  public native void set(String className, SerializeFunction override) /*-{
-    this['A' + className] = override;
-  }-*/;
-
-  public void set(String className, SerializeFunction override,
-      String[] extraFields) {
-    set(className, override);
-    set(className, extraFields);
-  }
-
-  public native void set(String className, String[] extraFields) /*-{
-    this['B' + className] = extraFields;
-  }-*/;
-}
diff --git a/user/src/com/google/gwt/rpc/client/package-info.java b/user/src/com/google/gwt/rpc/client/package-info.java
deleted file mode 100644
index 7552a18..0000000
--- a/user/src/com/google/gwt/rpc/client/package-info.java
+++ /dev/null
@@ -1,21 +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.
- */
-
-/**
- * Contains the client-side APIs for deRPC.
- */
-@com.google.gwt.util.PreventSpuriousRebuilds
-package com.google.gwt.rpc.client;
diff --git a/user/src/com/google/gwt/rpc/linker/CastableTypeDataImpl.java b/user/src/com/google/gwt/rpc/linker/CastableTypeDataImpl.java
deleted file mode 100644
index 58207fb..0000000
--- a/user/src/com/google/gwt/rpc/linker/CastableTypeDataImpl.java
+++ /dev/null
@@ -1,36 +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.rpc.linker;
-
-import com.google.gwt.rpc.server.CastableTypeData;
-
-/**
- * Implementation of a wrapped castableTypeMap.
- */
-public class CastableTypeDataImpl implements CastableTypeData {
-  
-  private final String castableTypeMapJs;
-  
-  public CastableTypeDataImpl(String castableTypeMapJs) {
-    this.castableTypeMapJs = castableTypeMapJs;
-  }
-
-  public String toJs() {
-    return castableTypeMapJs;
-  }
-
-}
diff --git a/user/src/com/google/gwt/rpc/linker/ClientOracleLinker.java b/user/src/com/google/gwt/rpc/linker/ClientOracleLinker.java
deleted file mode 100644
index 4d1d1a2..0000000
--- a/user/src/com/google/gwt/rpc/linker/ClientOracleLinker.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2009 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.rpc.linker;
-
-import com.google.gwt.core.ext.LinkerContext;
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.linker.AbstractLinker;
-import com.google.gwt.core.ext.linker.ArtifactSet;
-import com.google.gwt.core.ext.linker.CompilationResult;
-import com.google.gwt.core.ext.linker.LinkerOrder;
-import com.google.gwt.core.ext.linker.LinkerOrder.Order;
-import com.google.gwt.core.ext.linker.Shardable;
-import com.google.gwt.core.ext.linker.SymbolData;
-import com.google.gwt.core.ext.linker.SyntheticArtifact;
-import com.google.gwt.rpc.server.WebModeClientOracle.Builder;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Exports data required by server components for directly-evalable RPC.
- */
-@LinkerOrder(Order.PRE)
-@Shardable
-public class ClientOracleLinker extends AbstractLinker {
-
-  private static final String SUFFIX = ".gwt.rpc";
-
-  @Override
-  public String getDescription() {
-    return "deRPC linker";
-  }
-
-  @Override
-  public ArtifactSet link(TreeLogger logger, LinkerContext context,
-      ArtifactSet artifacts, boolean onePermutation)
-      throws UnableToCompleteException {
-    if (onePermutation) {
-      artifacts = new ArtifactSet(artifacts);
-
-      Map<String, List<String>> allSerializableFields = new HashMap<String, List<String>>();
-
-      for (RpcDataArtifact data : artifacts.find(RpcDataArtifact.class)) {
-        allSerializableFields.putAll(data.getOperableFields());
-      }
-
-      for (CompilationResult result : artifacts.find(CompilationResult.class)) {
-        Builder builder = new Builder();
-
-        for (Map.Entry<String, List<String>> entry : allSerializableFields.entrySet()) {
-          builder.setSerializableFields(entry.getKey(), entry.getValue());
-        }
-
-        for (SymbolData symbolData : result.getSymbolMap()) {
-
-          String castableTypeMapString =
-              (symbolData.getCastableTypeMap() == null) ? null :
-                symbolData.getCastableTypeMap().toJs();
-
-          builder.add(symbolData.getSymbolName(), symbolData.getJsniIdent(),
-              symbolData.getClassName(), symbolData.getMemberName(),
-              symbolData.getRuntimeTypeId(),
-              new CastableTypeDataImpl(castableTypeMapString));
-        }
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        try {
-          builder.getOracle().store(out);
-        } catch (IOException e) {
-          // Should generally not happen
-          logger.log(TreeLogger.ERROR, "Unable to store deRPC data", e);
-          throw new UnableToCompleteException();
-        }
-
-        SyntheticArtifact a = emitBytes(logger, out.toByteArray(),
-            result.getStrongName() + SUFFIX);
-        artifacts.add(a);
-      }
-    }
-    return artifacts;
-  }
-
-}
diff --git a/user/src/com/google/gwt/rpc/linker/RpcDataArtifact.java b/user/src/com/google/gwt/rpc/linker/RpcDataArtifact.java
deleted file mode 100644
index b3087c7..0000000
--- a/user/src/com/google/gwt/rpc/linker/RpcDataArtifact.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2009 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.rpc.linker;
-
-import com.google.gwt.core.ext.linker.Artifact;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This artifact allows the RpcProxyCreator class to communicate with the
- * ClientOracleLinker.
- */
-public class RpcDataArtifact extends Artifact<RpcDataArtifact> {
-
-  private final String rpcServiceName;
-  private final Map<String, List<String>> fieldsByClassName = new HashMap<String, List<String>>();
-
-  public RpcDataArtifact(String rpcServiceName) {
-    super(ClientOracleLinker.class);
-    this.rpcServiceName = rpcServiceName;
-  }
-
-  public Map<String, List<String>> getOperableFields() {
-    return fieldsByClassName;
-  }
-
-  @Override
-  public int hashCode() {
-    return rpcServiceName.hashCode();
-  }
-
-  public void setFields(String className, List<String> fields) {
-    fieldsByClassName.put(className, fields);
-  }
-
-  @Override
-  protected int compareToComparableArtifact(RpcDataArtifact o) {
-    return rpcServiceName.compareTo(o.rpcServiceName);
-  }
-
-  @Override
-  protected Class<RpcDataArtifact> getComparableArtifactType() {
-    return RpcDataArtifact.class;
-  }
-
-}
diff --git a/user/src/com/google/gwt/rpc/linker/package-info.java b/user/src/com/google/gwt/rpc/linker/package-info.java
deleted file mode 100644
index c83eb8b..0000000
--- a/user/src/com/google/gwt/rpc/linker/package-info.java
+++ /dev/null
@@ -1,21 +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.
- */
-
-/**
- * Classes used to implement RPC.
- */
-@com.google.gwt.util.PreventSpuriousRebuilds
-package com.google.gwt.rpc.linker;
diff --git a/user/src/com/google/gwt/rpc/rebind/RpcProxyCreator.java b/user/src/com/google/gwt/rpc/rebind/RpcProxyCreator.java
deleted file mode 100644
index fe45275..0000000
--- a/user/src/com/google/gwt/rpc/rebind/RpcProxyCreator.java
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright 2009 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.rpc.rebind;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.impl.ArtificialRescue;
-import com.google.gwt.core.client.impl.ArtificialRescue.Rescue;
-import com.google.gwt.core.client.impl.Impl;
-import com.google.gwt.core.ext.GeneratorContext;
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.typeinfo.JArrayType;
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JEnumType;
-import com.google.gwt.core.ext.typeinfo.JField;
-import com.google.gwt.core.ext.typeinfo.JMethod;
-import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
-import com.google.gwt.core.ext.typeinfo.JType;
-import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.dev.util.collect.Lists;
-import com.google.gwt.rpc.client.impl.CommandToStringWriter;
-import com.google.gwt.rpc.client.impl.RpcServiceProxy;
-import com.google.gwt.rpc.client.impl.TypeOverrides;
-import com.google.gwt.rpc.linker.RpcDataArtifact;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-import com.google.gwt.user.client.rpc.impl.RemoteServiceProxy;
-import com.google.gwt.user.linker.rpc.RpcLogArtifact;
-import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
-import com.google.gwt.user.rebind.SourceWriter;
-import com.google.gwt.user.rebind.rpc.CustomFieldSerializerValidator;
-import com.google.gwt.user.rebind.rpc.ProxyCreator;
-import com.google.gwt.user.rebind.rpc.SerializableTypeOracle;
-import com.google.gwt.user.rebind.rpc.SerializableTypeOracleBuilder;
-import com.google.gwt.user.rebind.rpc.SerializationUtils;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Generates async proxy implementations using the RPC system.
- */
-public class RpcProxyCreator extends ProxyCreator {
-  private String typeOverrideName;
-
-  public RpcProxyCreator(JClassType type) {
-    super(type);
-  }
-
-  @Override
-  protected String computeTypeNameExpression(JType paramType) {
-    if (paramType.isClass() != null) {
-      return "GWT.isScript() ? Impl.getNameOf(\"@"
-          + paramType.getQualifiedSourceName() + "\") : \""
-          + SerializationUtils.getRpcTypeName(paramType) + "\"";
-    } else {
-      /*
-       * Consider the case of service methods that have interface parameters;
-       * these types don't necessarily exist in the client code, so we want to
-       * encode these type names in a way that can always be distinguished from
-       * obfuscated type names.
-       */
-      return "\" " + SerializationUtils.getRpcTypeName(paramType)
-          + "\"";
-    }
-  }
-
-  @Override
-  protected void generateProxyContructor(SourceWriter srcWriter) {
-    srcWriter.println("public " + getProxySimpleName() + "() {");
-    srcWriter.indent();
-    srcWriter.println("super(GWT.getModuleBaseURL(),");
-    srcWriter.indent();
-    srcWriter.println(getRemoteServiceRelativePath() + ",");
-    srcWriter.println("OVERRIDES);");
-    srcWriter.outdent();
-    srcWriter.outdent();
-    srcWriter.println("}");
-  }
-
-  /**
-   * Generate any fields required by the proxy.
-   */
-  @Override
-  protected void generateProxyFields(SourceWriter srcWriter,
-      SerializableTypeOracle serializableTypeOracle,
-      String serializationPolicyStrongName, String remoteServiceInterfaceName) {
-    // Initialize a field with binary name of the remote service interface
-    srcWriter.println("private static final String REMOTE_SERVICE_INTERFACE_NAME = "
-        + "\"" + remoteServiceInterfaceName + "\";");
-    srcWriter.println("private static final " + TypeOverrides.class.getName()
-        + " OVERRIDES = GWT.isScript() ? " + typeOverrideName
-        + ".create() : null;");
-    srcWriter.println();
-  }
-
-  @Override
-  protected void generateStreamWriterOverride(SourceWriter srcWriter) {
-    // Intentional no-op. Called if elideTypeNames is on, which is ignored
-  }
-
-  @Override
-  protected void generateTypeHandlers(TreeLogger logger, GeneratorContext ctx,
-      SerializableTypeOracle serializationSto,
-      SerializableTypeOracle deserializationSto)
-      throws UnableToCompleteException {
-    String simpleName = serviceIntf.getSimpleSourceName()
-        + "_TypeOverridesFactory";
-    PrintWriter out = ctx.tryCreate(logger, serviceIntf.getPackage().getName(),
-        simpleName);
-    if (out == null) {
-      return;
-    }
-
-    TypeOracle typeOracle = ctx.getTypeOracle();
-    JClassType objectType = typeOracle.getJavaLangObject();
-    Set<JType> classLiterals = new LinkedHashSet<JType>();
-    Map<JType, JMethod> serializerMethods = new LinkedHashMap<JType, JMethod>();
-    Map<JType, List<String>> fields = new LinkedHashMap<JType, List<String>>();
-
-    StringBuilder sb = writeArtificialRescues(typeOracle, serializationSto,
-        deserializationSto);
-
-    ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(
-        serviceIntf.getPackage().getName(), simpleName);
-    composerFactory.addImport(ArtificialRescue.class.getCanonicalName());
-    composerFactory.addImport(GWT.class.getCanonicalName());
-    composerFactory.addImport(Impl.class.getCanonicalName());
-    composerFactory.addImport(Rescue.class.getCanonicalName());
-    composerFactory.addImport(TypeOverrides.class.getCanonicalName());
-    composerFactory.addImport(TypeOverrides.SerializeFunction.class.getCanonicalName());
-
-    composerFactory.addAnnotationDeclaration(sb.toString());
-    SourceWriter sw = composerFactory.createSourceWriter(ctx, out);
-
-    sw.println("public static TypeOverrides create() {");
-    sw.indent();
-    sw.println("TypeOverrides toReturn = TypeOverrides.create();");
-    for (JType type : serializationSto.getSerializableTypes()) {
-      JClassType classType = type.isClass();
-      if (classType == null) {
-        continue;
-      }
-
-      /*
-       * Figure out which fields should be serialized and if there's a CFS. This
-       * is done by crawling the supertype chain until we hit Object or a type
-       * with a CFS.
-       */
-      boolean allFieldsAreSerializable = true;
-      List<String> fieldRefs = new ArrayList<String>();
-      JMethod serializerMethod = null;
-      do {
-        JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(
-            typeOracle, classType);
-        serializerMethod = customSerializer == null ? null
-            : CustomFieldSerializerValidator.getSerializationMethod(
-                customSerializer, type.isClass());
-
-        if (serializerMethod != null) {
-          // Don't include any fields in the type
-          break;
-        }
-
-        JField[] serializableFields = SerializationUtils.getSerializableFields(
-            typeOracle, classType);
-        allFieldsAreSerializable &= serializableFields.length == classType.getFields().length;
-        for (JField field : serializableFields) {
-          fieldRefs.add("@" + field.getEnclosingType().getQualifiedSourceName()
-              + "::" + field.getName());
-        }
-        classType = classType.getSuperclass();
-      } while (classType != objectType);
-
-      if (allFieldsAreSerializable && serializerMethod == null) {
-        // We can just inspect the object at runtime; best for code size
-        continue;
-      }
-
-      if (serializerMethod != null || !fieldRefs.isEmpty()) {
-        classLiterals.add(type);
-
-        /*
-         * toReturn.set(class_foo_Bar().getName(), serializer_foo_Bar(),
-         * fields_foo_Bar());
-         */
-        String mangledTypeName = type.getQualifiedSourceName().replace('.', '_');
-        sw.println("toReturn.set(class_" + mangledTypeName + "().getName()");
-        if (serializerMethod == null) {
-        } else {
-          serializerMethods.put(type, serializerMethod);
-          sw.indentln(",serializer_" + mangledTypeName + "()");
-        }
-        if (fieldRefs.isEmpty()) {
-          sw.indentln(");");
-        } else {
-          fields.put(type, fieldRefs);
-          sw.indentln(",fields_" + mangledTypeName + "());");
-        }
-      }
-    }
-
-    sw.println("return toReturn;");
-    sw.outdent();
-    sw.println("}");
-
-    for (JType classLiteral : classLiterals) {
-      sw.println("public static native Class class_"
-          + classLiteral.getQualifiedSourceName().replace('.', '_') + "() /*-{");
-      sw.indentln("return @" + classLiteral.getQualifiedSourceName()
-          + "::class;");
-      sw.println("}-*/;");
-      sw.println();
-    }
-
-    for (Map.Entry<JType, JMethod> entry : serializerMethods.entrySet()) {
-      sw.println("public static native "
-          + TypeOverrides.SerializeFunction.class.getSimpleName()
-          + " serializer_"
-          + entry.getKey().getQualifiedSourceName().replace('.', '_')
-          + "() /*-{");
-      sw.indentln("return " + entry.getValue().getJsniSignature() + ";");
-      sw.println("}-*/;");
-      sw.println();
-    }
-
-    for (Map.Entry<JType, List<String>> entry : fields.entrySet()) {
-      sw.println("public static String[] fields_"
-          + entry.getKey().getQualifiedSourceName().replace('.', '_') + "() {");
-      sw.print("return new String[] {");
-      for (String fieldRef : entry.getValue()) {
-        sw.print("Impl.getNameOf(\"" + fieldRef + "\"),");
-      }
-      sw.println("};");
-      sw.println("}");
-      sw.println();
-    }
-
-    sw.commit(logger);
-
-    typeOverrideName = composerFactory.getCreatedClassName();
-  }
-
-  @Override
-  protected Class<? extends RemoteServiceProxy> getProxySupertype() {
-    return RpcServiceProxy.class;
-  }
-
-  @Override
-  protected Class<? extends SerializationStreamWriter> getStreamWriterClass() {
-    return CommandToStringWriter.class;
-  }
-
-  @Override
-  protected String writeSerializationPolicyFile(TreeLogger logger,
-      GeneratorContext ctx, SerializableTypeOracle serializationSto,
-      SerializableTypeOracle deserializationSto)
-      throws UnableToCompleteException {
-
-    RpcDataArtifact data = new RpcDataArtifact(
-        serviceIntf.getQualifiedSourceName());
-
-    for (JType type : deserializationSto.getSerializableTypes()) {
-      if (!(type instanceof JClassType)) {
-        continue;
-      }
-
-      JField[] serializableFields = SerializationUtils.getSerializableFields(
-          ctx.getTypeOracle(), (JClassType) type);
-
-      List<String> names = Lists.create();
-      for (int i = 0, j = serializableFields.length; i < j; i++) {
-        names = Lists.add(names, serializableFields[i].getName());
-      }
-
-      data.setFields(SerializationUtils.getRpcTypeName(type), names);
-    }
-
-    ctx.commitArtifact(logger, data);
-
-    return RpcLogArtifact.UNSPECIFIED_STRONGNAME;
-  }
-
-  private StringBuilder writeArtificialRescues(TypeOracle typeOracle,
-      SerializableTypeOracle serializationSto,
-      SerializableTypeOracle deserializationSto) {
-    Set<JType> serializableTypes = new LinkedHashSet<JType>();
-    Collections.addAll(serializableTypes,
-        serializationSto.getSerializableTypes());
-    Collections.addAll(serializableTypes,
-        deserializationSto.getSerializableTypes());
-    for (JMethod m : serviceIntf.getOverridableMethods()) {
-      // Pick up any primitive return types, which get sent boxed
-      JPrimitiveType mustBox = m.getReturnType().isPrimitive();
-      if (mustBox != null) {
-        serializableTypes.add(m.getReturnType());
-      }
-    }
-
-    StringBuilder sb = new StringBuilder("@ArtificialRescue({");
-    for (JType serializableType : serializableTypes) {
-
-      JArrayType serializableArray = serializableType.isArray();
-      JClassType serializableClass = serializableType.isClass();
-      JPrimitiveType serializablePrimitive = serializableType.isPrimitive();
-      if (serializableArray != null) {
-        sb.append("\n@Rescue(className = \"");
-        sb.append(serializableArray.getQualifiedSourceName());
-        sb.append("\",\n instantiable = true),");
-      } else if (serializableClass != null) {
-        writeSingleRescue(typeOracle, deserializationSto, sb, serializableClass);
-      } else if (serializablePrimitive != null) {
-        JClassType boxedClass = typeOracle.findType(serializablePrimitive.getQualifiedBoxedSourceName());
-        assert boxedClass != null : "No boxed version of "
-            + serializablePrimitive.getQualifiedSourceName();
-        writeSingleRescue(typeOracle, deserializationSto, sb, boxedClass);
-      }
-    }
-    sb.append("})");
-    return sb;
-  }
-
-  /**
-   * Writes the rescue of a serializable type and its custom serialization
-   * logic.
-   */
-  private void writeSingleRescue(TypeOracle typeOracle,
-      SerializableTypeOracle deserializationOracle, StringBuilder sb,
-      JClassType serializableClass) {
-    boolean shouldDeserialize = deserializationOracle.isSerializable(serializableClass);
-
-    // Pull the two custom serialization methods
-    JClassType customSerializer;
-    JMethod deserialize = null;
-    JMethod instantiate = null;
-
-    // An automatically-serializable subclass of a manually serialized class
-    boolean hybridSerialization = false;
-
-    {
-      JClassType search = serializableClass;
-      do {
-        customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(
-            typeOracle, search);
-
-        if (customSerializer != null) {
-          instantiate = CustomFieldSerializerValidator.getInstantiationMethod(
-              customSerializer, search);
-
-          deserialize = CustomFieldSerializerValidator.getDeserializationMethod(
-              customSerializer, search);
-
-          hybridSerialization = search != serializableClass;
-          break;
-        }
-
-        search = search.getSuperclass();
-      } while (search != null);
-    }
-
-    // The fields that should be preserved from being pruned
-    JField[] serializableFields;
-    JEnumType enumType = serializableClass.isEnum();
-    if (enumType != null) {
-      serializableFields = enumType.getFields();
-    } else {
-      serializableFields = SerializationUtils.getSerializableFields(typeOracle,
-          serializableClass);
-    }
-
-    /*
-     * We need to rescue the constructor if there is no instantiate method and
-     * there is a custom deserialize method.
-     */
-    boolean rescueConstructor = instantiate == null && deserialize != null;
-
-    /*
-     * There may be either no custom serializer or a custom serializer that
-     * doesn't define the instantiate method.
-     */
-    if (shouldDeserialize || rescueConstructor
-        || (customSerializer == null && serializableFields.length > 0)) {
-
-      /*
-       * @Rescue(className="package.Foo$Inner", instantiable=true, fields={..},
-       * methods={..}),
-       */
-      sb.append("\n@Rescue(className = \"").append(
-          serializableClass.getQualifiedSourceName()).append("\"");
-
-      sb.append(",\n instantiable = ").append(shouldDeserialize);
-      sb.append(",\n fields = {");
-      if (customSerializer == null || hybridSerialization) {
-        for (JField field : serializableFields) {
-          sb.append("\"").append(field.getName()).append("\",");
-        }
-      }
-      sb.append("},\n methods = {");
-      if (rescueConstructor) {
-        sb.append("\"").append(serializableClass.getName().replace('.', '$')).append(
-            "()\"");
-      }
-      sb.append("}),");
-    }
-
-    // Rescue the custom serialization logic if any exists
-    if (customSerializer != null) {
-      sb.append("\n@Rescue(className = \"").append(
-          customSerializer.getQualifiedSourceName()).append("\",\n methods = {");
-      if (instantiate != null) {
-        String jsniSignature = instantiate.getJsniSignature();
-        sb.append("\"").append(
-            jsniSignature.substring(jsniSignature.lastIndexOf(':') + 1)).append(
-            "\",");
-      }
-      if (deserialize != null) {
-        String jsniSignature = deserialize.getJsniSignature();
-        sb.append("\"").append(
-            jsniSignature.substring(jsniSignature.lastIndexOf(':') + 1)).append(
-            "\",");
-      }
-      sb.append("}),");
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/rebind/RpcServiceGenerator.java b/user/src/com/google/gwt/rpc/rebind/RpcServiceGenerator.java
deleted file mode 100644
index 65ef8cd..0000000
--- a/user/src/com/google/gwt/rpc/rebind/RpcServiceGenerator.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2009 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.rpc.rebind;
-
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.user.rebind.rpc.ProxyCreator;
-import com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator;
-
-/**
- * Generator for RPC service interfaces.
- */
-public class RpcServiceGenerator extends
-    ServiceInterfaceProxyGenerator {
-
-  @Override
-  protected ProxyCreator createProxyCreator(JClassType remoteService) {
-    return new RpcProxyCreator(remoteService);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/CastableTypeData.java b/user/src/com/google/gwt/rpc/server/CastableTypeData.java
deleted file mode 100644
index c2c2e63..0000000
--- a/user/src/com/google/gwt/rpc/server/CastableTypeData.java
+++ /dev/null
@@ -1,30 +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.rpc.server;
-
-import java.io.Serializable;
-
-/**
- * An encapsulation of a JSON object containing castable type information.
- */
-public interface CastableTypeData extends Serializable {
-  
-    /**
-     * Returns an eval-able JSON object.
-     */
-    String toJs();
-}
diff --git a/user/src/com/google/gwt/rpc/server/ClientOracle.java b/user/src/com/google/gwt/rpc/server/ClientOracle.java
deleted file mode 100644
index 54bf02e..0000000
--- a/user/src/com/google/gwt/rpc/server/ClientOracle.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import com.google.gwt.rpc.client.ast.CommandSink;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.Field;
-
-/**
- * Encapsulates information about a remote client. This type is not intended to
- * be implemented by end-users although the behavior of a concrete
- * implementation may be modified via the {@link DelegatingClientOracle} type.
- */
-public abstract class ClientOracle {
-
-  /**
-   * Not a generally-extensible class.
-   */
-  ClientOracle() {
-  }
-
-  /**
-   * Create a CommandSink that can encode a payload for the client.
-   *
-   * @param out the OutputStream to which the output will be written
-   * @return a CommandSink
-   * @throws IOException if the CommandSink cannot write to the OutputStream
-   */
-  public abstract CommandSink createCommandSink(OutputStream out)
-      throws IOException;
-
-  /**
-   * Returns an identifier that does not conflict with any symbols defined in
-   * the client. This method does not accumulate any state.
-   */
-  public abstract String createUnusedIdent(String ident);
-
-  /**
-   * Returns the Json castableType data for a given type.
-   */
-  public abstract CastableTypeData getCastableTypeData(Class<?> clazz);
-
-  /**
-   * Given a base type and the unobfuscated field name, find the obfuscated name
-   * for the field in the client. This will search superclasses as well for the
-   * first matching field.
-   */
-  public abstract String getFieldId(Class<?> clazz, String fieldName);
-
-  /**
-   * Return the field name for a given enum value.
-   */
-  public abstract String getFieldId(Enum<?> value);
-
-  /**
-   * This is similar to {@link #getFieldId(Class, String)} but does not search
-   * supertypes. It is intended to be used to access "magic" GWT types.
-   */
-  public abstract String getFieldId(String className, String fieldName);
-
-  /**
-   * Return the name of a field from a client-side id. This will search
-   * superclasses for the first instance of the named field.
-   *
-   * @return The field's declaring class and the name of the field
-   */
-  public abstract Pair<Class<?>, String> getFieldName(Class<?> clazz,
-      String fieldId);
-
-  /**
-   * Returns the name of the top-level function which implements the named
-   * method that takes the exact arguments specified. This will search in the
-   * given class as well as its supertypes.
-   */
-  public abstract String getMethodId(Class<?> clazz, String methodName,
-      Class<?>... args);
-
-  /**
-   * This is similar to {@link #getMethodId(Class, String, Class...)} but does
-   * not search supertypes. It is intended to be used to access "magic" GWT
-   * types.
-   */
-  public abstract String getMethodId(String className, String methodName,
-      String... jsniArgTypes);
-
-  /**
-   * Returns the fields of a given class that should be serialized. This method
-   * does not crawl supertypes.
-   */
-  public abstract Field[] getOperableFields(Class<?> clazz);
-
-  /**
-   * Returns the assigned castability runtimeTypeId of a given type.
-   */
-  public abstract String getRuntimeTypeId(Class<?> clazz);
-
-  /**
-   * Returns the name of the top-level function that is used as the seed
-   * function for a given type.
-   */
-  public abstract String getJsSymbolName(Class<?> clazz);
-
-  /**
-   * Returns the deobfuscated name of a type based on the name of the type's
-   * seed function.
-   */
-  public abstract String getTypeName(String seedName);
-
-  /**
-   * Indicates whether or not the remote client is running as compiled script.
-   * This may be used to optimize the payload based on assumptions that can be
-   * mode about web-mode or hosted-mode clients.
-   */
-  public abstract boolean isScript();
-}
diff --git a/user/src/com/google/gwt/rpc/server/CommandSerializationUtil.java b/user/src/com/google/gwt/rpc/server/CommandSerializationUtil.java
deleted file mode 100644
index e395272..0000000
--- a/user/src/com/google/gwt/rpc/server/CommandSerializationUtil.java
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import com.google.gwt.rpc.client.ast.BooleanValueCommand;
-import com.google.gwt.rpc.client.ast.ByteValueCommand;
-import com.google.gwt.rpc.client.ast.CharValueCommand;
-import com.google.gwt.rpc.client.ast.DoubleValueCommand;
-import com.google.gwt.rpc.client.ast.FloatValueCommand;
-import com.google.gwt.rpc.client.ast.IntValueCommand;
-import com.google.gwt.rpc.client.ast.LongValueCommand;
-import com.google.gwt.rpc.client.ast.ShortValueCommand;
-import com.google.gwt.rpc.client.ast.StringValueCommand;
-import com.google.gwt.rpc.client.ast.ValueCommand;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.util.IdentityHashMap;
-import java.util.Map;
-
-import sun.misc.Unsafe;
-
-/**
- * Contains common utility code.
- */
-public class CommandSerializationUtil {
-
-  /**
-   * Defines methods for getting and setting fields.
-   */
-  public interface Accessor {
-    boolean canMakeValueCommand();
-
-    /**
-     * Indicates if set can be called with a value of the given type.
-     */
-    boolean canSet(Class<?> clazz);
-
-    Object get(Object instance, Field f);
-
-    Class<?> getTargetType();
-
-    ValueCommand makeValueCommand(Object value);
-
-    Object readNext(SerializationStreamReader reader)
-        throws SerializationException;
-
-    void set(Object instance, Field f, Object value);
-
-    void set(Object array, int index, Object value);
-  }
-
-  /**
-   * Defines type-specific methods of getting and setting fields.
-   */
-  private static enum TypeAccessor implements Accessor {
-    BOOL {
-      @Override
-      public boolean canSet(Class<?> clazz) {
-        return Boolean.class.isAssignableFrom(clazz)
-            || Number.class.isAssignableFrom(clazz)
-            || String.class.isAssignableFrom(clazz);
-      }
-
-      @Override
-      public Object get(Object instance, long offset) {
-        return theUnsafe.getBoolean(instance, offset);
-      }
-
-      @Override
-      public Object getDefaultValue() {
-        return false;
-      }
-
-      @Override
-      public Class<?> getTargetType() {
-        return boolean.class;
-      }
-
-      @Override
-      public ValueCommand makeValueCommand(Object value) {
-        return new BooleanValueCommand((Boolean) value);
-      }
-
-      @Override
-      public Object readNext(SerializationStreamReader reader)
-          throws SerializationException {
-        return reader.readBoolean();
-      }
-
-      @Override
-      public void set(Object instance, long offset, Object value) {
-        theUnsafe.putBoolean(instance, offset, toBoolean(value));
-      }
-
-      private boolean toBoolean(Object value) {
-        if (value instanceof Number) {
-          return ((Number) value).intValue() != 0;
-        } else if (value instanceof String) {
-          return Boolean.valueOf((String) value);
-        } else {
-          // returns false if the value is null.
-          return Boolean.TRUE.equals(value);
-        }
-      }
-
-    },
-    BYTE {
-      @Override
-      public Object get(Object instance, long offset) {
-        return theUnsafe.getByte(instance, offset);
-      }
-
-      @Override
-      public Class<?> getTargetType() {
-        return byte.class;
-      }
-
-      @Override
-      public ValueCommand makeValueCommand(Object value) {
-        return new ByteValueCommand((Byte) value);
-      }
-
-      @Override
-      public Object readNext(SerializationStreamReader reader)
-          throws SerializationException {
-        return reader.readByte();
-      }
-
-      @Override
-      public void set(Object instance, long offset, Object value) {
-        theUnsafe.putByte(instance, offset, ((Number) value).byteValue());
-      }
-    },
-    CHAR {
-      @Override
-      public Object get(Object instance, long offset) {
-        return theUnsafe.getChar(instance, offset);
-      }
-
-      @Override
-      public Class<?> getTargetType() {
-        return char.class;
-      }
-
-      @Override
-      public ValueCommand makeValueCommand(Object value) {
-        return new CharValueCommand((Character) value);
-      }
-
-      @Override
-      public Object readNext(SerializationStreamReader reader)
-          throws SerializationException {
-        return reader.readChar();
-      }
-
-      @Override
-      public void set(Object instance, long offset, Object value) {
-        char c = (value instanceof Number) ? (char) ((Number) value).intValue()
-            : (Character) value;
-        theUnsafe.putChar(instance, offset, c);
-      }
-    },
-    DOUBLE {
-      @Override
-      public Object get(Object instance, long offset) {
-        return theUnsafe.getDouble(instance, offset);
-      }
-
-      @Override
-      public Class<?> getTargetType() {
-        return double.class;
-      }
-
-      @Override
-      public ValueCommand makeValueCommand(Object value) {
-        return new DoubleValueCommand((Double) value);
-      }
-
-      @Override
-      public Object readNext(SerializationStreamReader reader)
-          throws SerializationException {
-        return reader.readDouble();
-      }
-
-      @Override
-      public void set(Object instance, long offset, Object value) {
-        theUnsafe.putDouble(instance, offset, ((Number) value).doubleValue());
-      }
-    },
-    FLOAT {
-      @Override
-      public Object get(Object instance, long offset) {
-        return theUnsafe.getFloat(instance, offset);
-      }
-
-      @Override
-      public Class<?> getTargetType() {
-        return float.class;
-      }
-
-      @Override
-      public ValueCommand makeValueCommand(Object value) {
-        return new FloatValueCommand((Float) value);
-      }
-
-      @Override
-      public Object readNext(SerializationStreamReader reader)
-          throws SerializationException {
-        return reader.readFloat();
-      }
-
-      @Override
-      public void set(Object instance, long offset, Object value) {
-        theUnsafe.putFloat(instance, offset, ((Number) value).floatValue());
-      }
-    },
-    INT {
-      @Override
-      public Object get(Object instance, long offset) {
-        return theUnsafe.getInt(instance, offset);
-      }
-
-      @Override
-      public Class<?> getTargetType() {
-        return int.class;
-      }
-
-      @Override
-      public ValueCommand makeValueCommand(Object value) {
-        return new IntValueCommand(((Number) value).intValue());
-      }
-
-      @Override
-      public Object readNext(SerializationStreamReader reader)
-          throws SerializationException {
-        return reader.readInt();
-      }
-
-      @Override
-      public void set(Object instance, long offset, Object value) {
-        theUnsafe.putInt(instance, offset, ((Number) value).intValue());
-      }
-    },
-    LONG {
-      @Override
-      public Object get(Object instance, long offset) {
-        return theUnsafe.getLong(instance, offset);
-      }
-
-      @Override
-      public Class<?> getTargetType() {
-        return long.class;
-      }
-
-      @Override
-      public ValueCommand makeValueCommand(Object value) {
-        return new LongValueCommand((Long) value);
-      }
-
-      @Override
-      public Object readNext(SerializationStreamReader reader)
-          throws SerializationException {
-        return reader.readLong();
-      }
-
-      @Override
-      public void set(Object instance, long offset, Object value) {
-        theUnsafe.putLong(instance, offset, ((Number) value).longValue());
-      }
-    },
-    OBJECT {
-      @Override
-      public boolean canMakeValueCommand() {
-        return false;
-      }
-
-      @Override
-      public boolean canSet(Class<?> clazz) {
-        return Object.class.isAssignableFrom(clazz);
-      }
-
-      @Override
-      public Object get(Object instance, long offset) {
-        return theUnsafe.getObject(instance, offset);
-      }
-
-      @Override
-      public Object getDefaultValue() {
-        return null;
-      }
-
-      @Override
-      public Class<?> getTargetType() {
-        return Object.class;
-      }
-
-      @Override
-      public ValueCommand makeValueCommand(Object value) {
-        throw new RuntimeException("Cannot call makeValueCommand for Objects");
-      }
-
-      @Override
-      public Object readNext(SerializationStreamReader reader)
-          throws SerializationException {
-        return reader.readObject();
-      }
-
-      @Override
-      public void set(Object instance, long offset, Object value) {
-        theUnsafe.putObject(instance, offset, value);
-      }
-    },
-    SHORT {
-      @Override
-      public Object get(Object instance, long offset) {
-        return theUnsafe.getShort(instance, offset);
-      }
-
-      @Override
-      public Class<?> getTargetType() {
-        return short.class;
-      }
-
-      @Override
-      public ValueCommand makeValueCommand(Object value) {
-        return new ShortValueCommand((Short) value);
-      }
-
-      @Override
-      public Object readNext(SerializationStreamReader reader)
-          throws SerializationException {
-        return reader.readShort();
-      }
-
-      @Override
-      public void set(Object instance, long offset, Object value) {
-        theUnsafe.putShort(instance, offset, ((Number) value).shortValue());
-      }
-    },
-    STRING {
-      @Override
-      public boolean canSet(Class<?> clazz) {
-        return true;
-      }
-
-      @Override
-      public Object get(Object instance, long offset) {
-        return theUnsafe.getObject(instance, offset);
-      }
-
-      @Override
-      public Object getDefaultValue() {
-        return null;
-      }
-
-      @Override
-      public Class<?> getTargetType() {
-        return String.class;
-      }
-
-      @Override
-      public ValueCommand makeValueCommand(Object value) {
-        return new StringValueCommand((String) value);
-      }
-
-      @Override
-      public Object readNext(SerializationStreamReader reader)
-          throws SerializationException {
-        return reader.readObject();
-      }
-
-      @Override
-      public void set(Object instance, long offset, Object value) {
-        theUnsafe.putObject(instance, offset, value == null ? null
-            : value.toString());
-      }
-    };
-
-    private final Class<?> arrayType = Array.newInstance(getTargetType(), 0).getClass();
-    private final long arrayBase = theUnsafe.arrayBaseOffset(arrayType);
-    private final long arrayIndexScale = theUnsafe.arrayIndexScale(arrayType);
-
-    public boolean canMakeValueCommand() {
-      return true;
-    }
-
-    public boolean canSet(Class<?> clazz) {
-      return Number.class.isAssignableFrom(clazz);
-    }
-
-    public Object get(Object instance, Field f) {
-      long offset = objectFieldOffset(f);
-      return get(instance, offset);
-    }
-
-    public abstract Object get(Object instance, long offset);
-
-    public Object getDefaultValue() {
-      return 0;
-    }
-
-    public abstract Class<?> getTargetType();
-
-    public abstract ValueCommand makeValueCommand(Object value);
-
-    public abstract Object readNext(SerializationStreamReader reader)
-        throws SerializationException;
-
-    public void set(Object instance, Field f, Object value) {
-      long offset = objectFieldOffset(f);
-      set(instance, offset, value == null ? getDefaultValue() : value);
-    }
-
-    public void set(Object array, int index, Object value) {
-      set(array, arrayBase + arrayIndexScale * index, value);
-    }
-
-    public abstract void set(Object instance, long offset, Object value);
-  }
-
-  private static final Map<Class<?>, Accessor> ACCESSORS = new IdentityHashMap<Class<?>, Accessor>();
-  private static final Unsafe theUnsafe;
-
-  static {
-    Exception ex = null;
-    Unsafe localUnsafe = null;
-    try {
-      Field f = Unsafe.class.getDeclaredField("theUnsafe");
-      f.setAccessible(true);
-      localUnsafe = (Unsafe) f.get(null);
-    } catch (SecurityException e) {
-      ex = e;
-    } catch (NoSuchFieldException e) {
-      ex = e;
-    } catch (IllegalArgumentException e) {
-      ex = e;
-    } catch (IllegalAccessException e) {
-      ex = e;
-    }
-    if (ex != null) {
-      throw new RuntimeException("Unable to get Unsafe instance", ex);
-    } else {
-      theUnsafe = localUnsafe;
-    }
-
-    for (TypeAccessor setter : TypeAccessor.values()) {
-      ACCESSORS.put(setter.getTargetType(), setter);
-    }
-  }
-
-  public static Accessor getAccessor(Class<?> clazz) {
-    Accessor toReturn = ACCESSORS.get(clazz);
-    if (toReturn == null) {
-      toReturn = TypeAccessor.OBJECT;
-    }
-    return toReturn;
-  }
-
-  /**
-   * TODO: In the future it may be preferable to use a custom ClassLoader to
-   * inject a constructor that will initialize all of the final fields that we
-   * care about.
-   */
-  static <T> T allocateInstance(Class<T> clazz) throws InstantiationException {
-    Object obj = theUnsafe.allocateInstance(clazz);
-    return clazz.cast(obj);
-  }
-
-  private static long objectFieldOffset(Field f) {
-    return theUnsafe.objectFieldOffset(f);
-  }
-
-  private CommandSerializationUtil() {
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/CommandServerSerializationStreamReader.java b/user/src/com/google/gwt/rpc/server/CommandServerSerializationStreamReader.java
deleted file mode 100644
index 9cbafa2..0000000
--- a/user/src/com/google/gwt/rpc/server/CommandServerSerializationStreamReader.java
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import com.google.gwt.rpc.client.ast.ArrayValueCommand;
-import com.google.gwt.rpc.client.ast.BooleanValueCommand;
-import com.google.gwt.rpc.client.ast.ByteValueCommand;
-import com.google.gwt.rpc.client.ast.CharValueCommand;
-import com.google.gwt.rpc.client.ast.DoubleValueCommand;
-import com.google.gwt.rpc.client.ast.EnumValueCommand;
-import com.google.gwt.rpc.client.ast.FloatValueCommand;
-import com.google.gwt.rpc.client.ast.IdentityValueCommand;
-import com.google.gwt.rpc.client.ast.InstantiateCommand;
-import com.google.gwt.rpc.client.ast.IntValueCommand;
-import com.google.gwt.rpc.client.ast.InvokeCustomFieldSerializerCommand;
-import com.google.gwt.rpc.client.ast.LongValueCommand;
-import com.google.gwt.rpc.client.ast.NullValueCommand;
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor;
-import com.google.gwt.rpc.client.ast.ScalarValueCommand;
-import com.google.gwt.rpc.client.ast.SetCommand;
-import com.google.gwt.rpc.client.ast.ShortValueCommand;
-import com.google.gwt.rpc.client.ast.StringValueCommand;
-import com.google.gwt.rpc.client.ast.ValueCommand;
-import com.google.gwt.rpc.server.CommandSerializationUtil.Accessor;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * This class will use ValueCommands to reconstitute objects.
- */
-public class CommandServerSerializationStreamReader implements
-    SerializationStreamReader {
-
-  class Visitor extends RpcCommandVisitor {
-
-    @SuppressWarnings("hiding")
-    private final Stack<Object> values = new Stack<Object>();
-
-    @Override
-    public void endVisit(BooleanValueCommand x, Context ctx) {
-      pushScalar(x);
-    }
-
-    @Override
-    public void endVisit(ByteValueCommand x, Context ctx) {
-      pushScalar(x);
-    }
-
-    @Override
-    public void endVisit(CharValueCommand x, Context ctx) {
-      pushScalar(x);
-    }
-
-    @Override
-    public void endVisit(DoubleValueCommand x, Context ctx) {
-      pushScalar(x);
-    }
-
-    @Override
-    public void endVisit(EnumValueCommand x, Context ctx) {
-      push(x, x.getValue());
-    }
-
-    @Override
-    public void endVisit(FloatValueCommand x, Context ctx) {
-      pushScalar(x);
-    }
-
-    @Override
-    public void endVisit(IntValueCommand x, Context ctx) {
-      pushScalar(x);
-    }
-
-    @Override
-    public void endVisit(LongValueCommand x, Context ctx) {
-      pushScalar(x);
-    }
-
-    @Override
-    public void endVisit(NullValueCommand x, Context ctx) {
-      pushScalar(x);
-    }
-
-    @Override
-    public void endVisit(SetCommand x, Context ctx) {
-      Exception ex;
-      try {
-        Field f = x.getFieldDeclClass().getDeclaredField(x.getField());
-        Object value = values.pop();
-        Object instance = values.peek();
-        assert value == null
-            || CommandSerializationUtil.getAccessor(f.getType()).canSet(
-                value.getClass()) : "Cannot assign a "
-            + value.getClass().getName() + " into " + f.getType().getName();
-
-        CommandSerializationUtil.getAccessor(f.getType()).set(instance, f,
-            value);
-        return;
-      } catch (SecurityException e) {
-        ex = e;
-      } catch (NoSuchFieldException e) {
-        ex = e;
-      }
-      halt(new SerializationException("Unable to set field value", ex));
-    }
-
-    @Override
-    public void endVisit(ShortValueCommand x, Context ctx) {
-      pushScalar(x);
-    }
-
-    @Override
-    public void endVisit(StringValueCommand x, Context ctx) {
-      pushScalar(x);
-    }
-
-    @Override
-    public boolean visit(ArrayValueCommand x, Context ctx) {
-      if (maybePushBackRef(x)) {
-        Object array = Array.newInstance(x.getComponentType(),
-            x.getComponentValues().size());
-        push(x, array);
-
-        int size = x.getComponentValues().size();
-        Accessor a = CommandSerializationUtil.getAccessor(x.getComponentType());
-        for (int i = 0; i < size; i++) {
-          accept(x.getComponentValues().get(i));
-          a.set(array, i, values.pop());
-        }
-      }
-
-      return false;
-    }
-
-    @Override
-    public boolean visit(InstantiateCommand x, Context ctx) {
-      if (maybePushBackRef(x)) {
-        Object instance;
-        try {
-          instance = CommandSerializationUtil.allocateInstance(x.getTargetClass());
-          push(x, instance);
-          return true;
-        } catch (InstantiationException e) {
-          halt(new SerializationException("Unable to create instance", e));
-        }
-      }
-
-      return false;
-    }
-
-    @Override
-    public boolean visit(InvokeCustomFieldSerializerCommand x, Context ctx) {
-      if (maybePushBackRef(x)) {
-
-        CommandServerSerializationStreamReader subReader = new CommandServerSerializationStreamReader(
-            backRefs);
-        subReader.prepareToRead(x.getValues());
-
-        Class<?> serializerClass = x.getSerializerClass();
-        assert serializerClass != null;
-
-        Method instantiate = null;
-        Method deserialize = null;
-        for (Method m : serializerClass.getMethods()) {
-          if ("instantiate".equals(m.getName())) {
-            instantiate = m;
-          } else if ("deserialize".equals(m.getName())) {
-            deserialize = m;
-          }
-
-          if (instantiate != null && deserialize != null) {
-            break;
-          }
-        }
-
-        assert deserialize != null : "No deserialize method in "
-            + serializerClass.getName();
-
-        Object instance = null;
-        if (instantiate != null) {
-          assert Modifier.isStatic(instantiate.getModifiers()) : "instantiate method in "
-              + serializerClass.getName() + " must be static";
-          try {
-            instance = instantiate.invoke(null, subReader);
-          } catch (IllegalArgumentException e) {
-            halt(new SerializationException("Unable to create instance", e));
-          } catch (IllegalAccessException e) {
-            halt(new SerializationException("Unable to create instance", e));
-          } catch (InvocationTargetException e) {
-            halt(new SerializationException("Unable to create instance", e));
-          }
-        } else {
-          try {
-            instance = x.getTargetClass().newInstance();
-          } catch (InstantiationException e) {
-            halt(new SerializationException("Unable to create instance", e));
-          } catch (IllegalAccessException e) {
-            halt(new SerializationException("Unable to create instance", e));
-          }
-        }
-
-        assert instance != null : "Did not create instance";
-        push(x, instance);
-
-        // Process any additional fields
-        accept(x.getSetters());
-
-        try {
-          deserialize.invoke(null, subReader, instance);
-        } catch (IllegalArgumentException e) {
-          halt(new SerializationException("Unable to deserialize instance", e));
-        } catch (IllegalAccessException e) {
-          halt(new SerializationException("Unable to deserialize instance", e));
-        } catch (InvocationTargetException e) {
-          halt(new SerializationException("Unable to deserialize instance", e));
-        }
-      }
-
-      return false;
-    }
-
-    /**
-     * Returns true if the command must be processed.
-     */
-    private boolean maybePushBackRef(IdentityValueCommand x) {
-      Object instance = backRefs.get(x);
-      if (instance == null) {
-        return true;
-      } else {
-        values.push(instance);
-        return false;
-      }
-    }
-
-    private void push(IdentityValueCommand x, Object value) {
-      assert !backRefs.containsKey(x) : "Trying to redefine a backref";
-      backRefs.put(x, value);
-      values.push(value);
-    }
-
-    private void pushScalar(ScalarValueCommand x) {
-      values.push(x.getValue());
-    }
-  }
-
-  final Map<IdentityValueCommand, Object> backRefs;
-  Iterator<ValueCommand> values;
-
-  public CommandServerSerializationStreamReader() {
-    this(new HashMap<IdentityValueCommand, Object>());
-  }
-
-  private CommandServerSerializationStreamReader(
-      Map<IdentityValueCommand, Object> backRefs) {
-    this.backRefs = backRefs;
-  }
-
-  public void prepareToRead(List<ValueCommand> commands) {
-    values = commands.iterator();
-  }
-
-  public boolean readBoolean() throws SerializationException {
-    return readNumberCommand(BooleanValueCommand.class).getValue();
-  }
-
-  public byte readByte() throws SerializationException {
-    return readNumberCommand(ByteValueCommand.class).getValue();
-  }
-
-  public char readChar() throws SerializationException {
-    return readNumberCommand(CharValueCommand.class).getValue();
-  }
-
-  public double readDouble() throws SerializationException {
-    return readNumberCommand(DoubleValueCommand.class).getValue();
-  }
-
-  public float readFloat() throws SerializationException {
-    return readNumberCommand(FloatValueCommand.class).getValue();
-  }
-
-  public int readInt() throws SerializationException {
-    return readNumberCommand(IntValueCommand.class).getValue();
-  }
-
-  public long readLong() throws SerializationException {
-    return readNumberCommand(LongValueCommand.class).getValue();
-  }
-
-  public Object readObject() throws SerializationException {
-    ValueCommand command = readNextCommand(ValueCommand.class);
-    Visitor v = new Visitor();
-    v.accept(command);
-    return v.values.pop();
-  }
-
-  public short readShort() throws SerializationException {
-    return readNumberCommand(ShortValueCommand.class).getValue();
-  }
-
-  public String readString() throws SerializationException {
-    return (String) readObject();
-  }
-
-  private <T extends ValueCommand> T readNextCommand(Class<T> clazz)
-      throws SerializationException {
-    if (!values.hasNext()) {
-      throw new SerializationException("Reached end of stream");
-    }
-    ValueCommand next = values.next();
-    if (!clazz.isInstance(next)) {
-      throw new SerializationException("Cannot assign "
-          + next.getClass().getName() + " to " + clazz.getName());
-    }
-    return clazz.cast(next);
-  }
-
-  /**
-   * Will perform narrowing conversions from double type to other numeric types.
-   */
-  private <T extends ValueCommand> T readNumberCommand(Class<T> clazz)
-      throws SerializationException {
-    if (!values.hasNext()) {
-      throw new SerializationException("Reached end of stream");
-    }
-    ValueCommand next = values.next();
-
-    if (clazz.isInstance(next)) {
-      return clazz.cast(next);
-    } else if (next instanceof LongValueCommand) {
-      if (!clazz.isInstance(next)) {
-        throw new SerializationException("Cannot assign "
-            + next.getClass().getName() + " to " + clazz.getName());
-      }
-      return clazz.cast(next);
-    } else if (next instanceof DoubleValueCommand) {
-      Exception ex;
-      try {
-        Constructor<T> c = clazz.getConstructor(double.class);
-        return c.newInstance(((DoubleValueCommand) next).getValue().doubleValue());
-      } catch (SecurityException e) {
-        throw new SerializationException("Cannot construct ValueCommand type",
-            e);
-      } catch (NoSuchMethodException e) {
-        throw new SerializationException("Connot initialize a "
-            + clazz.getName() + " from a DoubleValueCommand", e);
-      } catch (IllegalArgumentException e) {
-        ex = e;
-      } catch (InstantiationException e) {
-        ex = e;
-      } catch (IllegalAccessException e) {
-        ex = e;
-      } catch (InvocationTargetException e) {
-        ex = e;
-      }
-      throw new SerializationException("Cannot create ValueCommand", ex);
-    } else {
-      throw new SerializationException(
-          "Cannot create a numeric ValueCommand from a "
-              + next.getClass().getName());
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/CommandServerSerializationStreamWriter.java b/user/src/com/google/gwt/rpc/server/CommandServerSerializationStreamWriter.java
deleted file mode 100644
index bfae11e..0000000
--- a/user/src/com/google/gwt/rpc/server/CommandServerSerializationStreamWriter.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import com.google.gwt.rpc.client.ast.ArrayValueCommand;
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.client.ast.EnumValueCommand;
-import com.google.gwt.rpc.client.ast.HasSetters;
-import com.google.gwt.rpc.client.ast.IdentityValueCommand;
-import com.google.gwt.rpc.client.ast.InstantiateCommand;
-import com.google.gwt.rpc.client.ast.InvokeCustomFieldSerializerCommand;
-import com.google.gwt.rpc.client.ast.NullValueCommand;
-import com.google.gwt.rpc.client.ast.ValueCommand;
-import com.google.gwt.rpc.client.impl.CommandSerializationStreamWriterBase;
-import com.google.gwt.rpc.client.impl.HasValuesCommandSink;
-import com.google.gwt.rpc.server.CommandSerializationUtil.Accessor;
-import com.google.gwt.user.client.rpc.IsSerializable;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.server.rpc.impl.SerializabilityUtil;
-
-import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.IdentityHashMap;
-import java.util.Map;
-
-/**
- * A server-side implementation of SerializationStreamWriter that creates a
- * command stream.
- */
-public class CommandServerSerializationStreamWriter extends
-    CommandSerializationStreamWriterBase {
-
-  private final ClientOracle clientOracle;
-  private final Map<Object, IdentityValueCommand> identityMap;
-
-  public CommandServerSerializationStreamWriter(CommandSink sink) {
-    this(new HostedModeClientOracle(), sink);
-  }
-
-  public CommandServerSerializationStreamWriter(ClientOracle oracle,
-      CommandSink sink) {
-    this(oracle, sink, new IdentityHashMap<Object, IdentityValueCommand>());
-  }
-
-  private CommandServerSerializationStreamWriter(ClientOracle oracle,
-      CommandSink sink, Map<Object, IdentityValueCommand> identityMap) {
-    super(sink);
-    this.clientOracle = oracle;
-    this.identityMap = identityMap;
-  }
-
-  /**
-   * Type is passed in to handle primitive types.
-   */
-  @Override
-  protected ValueCommand makeValue(Class<?> type, Object value)
-      throws SerializationException {
-    if (value == null) {
-      return NullValueCommand.INSTANCE;
-    }
-
-    /*
-     * Check accessor map before the identity map because we don't want to
-     * recurse on wrapped primitive values.
-     */
-    Accessor accessor;
-    if ((accessor = CommandSerializationUtil.getAccessor(type)).canMakeValueCommand()) {
-      return accessor.makeValueCommand(value);
-
-    } else if (identityMap.containsKey(value)) {
-      return identityMap.get(value);
-
-    } else if (type.isArray()) {
-      return makeArray(type, value);
-
-    } else if (Enum.class.isAssignableFrom(type)) {
-      return makeEnum(value);
-
-    } else {
-      return makeObject(type, value);
-    }
-  }
-
-  private ArrayValueCommand makeArray(Class<?> type, Object value)
-      throws SerializationException {
-    ArrayValueCommand toReturn = new ArrayValueCommand(type.getComponentType());
-    identityMap.put(value, toReturn);
-    for (int i = 0, j = Array.getLength(value); i < j; i++) {
-      Object arrayValue = Array.get(value, i);
-      if (arrayValue == null) {
-        toReturn.add(NullValueCommand.INSTANCE);
-      } else {
-        Class<? extends Object> valueType = type.getComponentType().isPrimitive()
-            ? type.getComponentType() : arrayValue.getClass();
-        toReturn.add(makeValue(valueType, arrayValue));
-      }
-    }
-    return toReturn;
-  }
-
-  private ValueCommand makeEnum(Object value) {
-    EnumValueCommand toReturn = new EnumValueCommand();
-    toReturn.setValue((Enum<?>) value);
-    return toReturn;
-  }
-
-  /*
-   * TODO: Profiling shows that the reflection and conditional logic in this
-   * method is a hotspot. This could be remedied by generating synthetic
-   * InstantiateCommand types that initialize themselves.
-   */
-  private IdentityValueCommand makeObject(Class<?> type, Object value)
-      throws SerializationException {
-
-    if (type.isAnonymousClass() || type.isLocalClass()) {
-      throw new SerializationException(
-          "Cannot serialize anonymous or local classes");
-    }
-
-    Class<?> manualType = type;
-    Class<?> customSerializer;
-    do {
-      customSerializer = SerializabilityUtil.hasCustomFieldSerializer(manualType);
-      if (customSerializer != null) {
-        break;
-      }
-      manualType = manualType.getSuperclass();
-    } while (manualType != null);
-
-    IdentityValueCommand ins;
-    if (customSerializer != null) {
-      ins = serializeWithCustomSerializer(customSerializer, value, type,
-          manualType);
-    } else {
-      ins = new InstantiateCommand(type);
-      identityMap.put(value, ins);
-    }
-
-    /*
-     * If we're looking at a subclass of a manually-serialized type, the
-     * subclass must be tagged as serializable in order to qualify for
-     * serialization.
-     */
-    if (type != manualType) {
-      if (!Serializable.class.isAssignableFrom(type)
-          && !IsSerializable.class.isAssignableFrom(type)) {
-        throw new SerializationException(type.getName()
-            + " is not a serializable type");
-      }
-    }
-
-    while (type != manualType) {
-      Field[] serializableFields = clientOracle.getOperableFields(type);
-      for (Field declField : serializableFields) {
-        assert (declField != null);
-
-        Accessor accessor = CommandSerializationUtil.getAccessor(declField.getType());
-        ValueCommand valueCommand;
-        Object fieldValue = accessor.get(value, declField);
-        if (fieldValue == null) {
-          valueCommand = NullValueCommand.INSTANCE;
-        } else {
-          Class<? extends Object> fieldType = declField.getType().isPrimitive()
-              ? declField.getType() : fieldValue.getClass();
-          valueCommand = makeValue(fieldType, fieldValue);
-        }
-
-        ((HasSetters) ins).set(declField.getDeclaringClass(),
-            declField.getName(), valueCommand);
-      }
-      type = type.getSuperclass();
-    }
-    return ins;
-  }
-
-  private InvokeCustomFieldSerializerCommand serializeWithCustomSerializer(
-      Class<?> customSerializer, Object instance, Class<?> instanceClass,
-      Class<?> manuallySerializedType) throws SerializationException {
-    assert !instanceClass.isArray();
-
-    Exception ex;
-    try {
-      /*
-       * NB: Class.getMethod() wants exact formal types. It may be the case that
-       * the custom serializer uses looser type bounds in its method
-       * declarations.
-       */
-      for (Method method : customSerializer.getMethods()) {
-        if ("serialize".equals(method.getName())) {
-          assert Modifier.isStatic(method.getModifiers()) : "serialize method "
-              + "in type " + customSerializer.getName() + " must be static";
-
-          final InvokeCustomFieldSerializerCommand toReturn = new InvokeCustomFieldSerializerCommand(
-              instanceClass, customSerializer, manuallySerializedType);
-          identityMap.put(instance, toReturn);
-
-          /*
-           * Pass the current identityMap into the new writer to allow circular
-           * references through the graph emitted by the CFS.
-           */
-          CommandServerSerializationStreamWriter subWriter = new CommandServerSerializationStreamWriter(
-              clientOracle, new HasValuesCommandSink(toReturn), identityMap);
-          method.invoke(null, subWriter, instance);
-
-          return toReturn;
-        }
-      }
-
-      throw new NoSuchMethodException(
-          "Could not find serialize method in custom serializer "
-              + customSerializer.getName());
-
-    } catch (SecurityException e) {
-      ex = e;
-    } catch (NoSuchMethodException e) {
-      ex = e;
-    } catch (IllegalArgumentException e) {
-      ex = e;
-    } catch (IllegalAccessException e) {
-      ex = e;
-    } catch (InvocationTargetException e) {
-      ex = e;
-    }
-
-    throw new SerializationException(ex);
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/DelegatingClientOracle.java b/user/src/com/google/gwt/rpc/server/DelegatingClientOracle.java
deleted file mode 100644
index 707048c..0000000
--- a/user/src/com/google/gwt/rpc/server/DelegatingClientOracle.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import com.google.gwt.rpc.client.ast.CommandSink;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.Field;
-
-/**
- * A delegate-pattern ClientOracle that can be used to introduce custom
- * behavior.
- */
-public class DelegatingClientOracle extends ClientOracle {
-
-  private final ClientOracle delegate;
-
-  public DelegatingClientOracle(ClientOracle delegate) {
-    this.delegate = delegate;
-  }
-
-  @Override
-  public CommandSink createCommandSink(OutputStream out) throws IOException {
-    return delegate.createCommandSink(out);
-  }
-
-  @Override
-  public String createUnusedIdent(String ident) {
-    return delegate.createUnusedIdent(ident);
-  }
-
-  @Override
-  public CastableTypeData getCastableTypeData(Class<?> clazz) {
-    return delegate.getCastableTypeData(clazz);
-  }
-
-  @Override
-  public String getFieldId(Class<?> clazz, String fieldName) {
-    return delegate.getFieldId(clazz, fieldName);
-  }
-
-  @Override
-  public String getFieldId(Enum<?> value) {
-    return delegate.getFieldId(value);
-  }
-
-  @Override
-  public String getFieldId(String className, String fieldName) {
-    return delegate.getFieldId(className, fieldName);
-  }
-
-  @Override
-  public Pair<Class<?>, String> getFieldName(Class<?> clazz, String fieldId) {
-    return delegate.getFieldName(clazz, fieldId);
-  }
-
-  @Override
-  public String getMethodId(Class<?> clazz, String methodName, Class<?>... args) {
-    return delegate.getMethodId(clazz, methodName, args);
-  }
-
-  @Override
-  public String getMethodId(String className, String methodName,
-      String... jsniArgTypes) {
-    return delegate.getMethodId(className, methodName, jsniArgTypes);
-  }
-
-  @Override
-  public Field[] getOperableFields(Class<?> clazz) {
-    return delegate.getOperableFields(clazz);
-  }
-
-  @Override
-  public String getRuntimeTypeId(Class<?> clazz) {
-    return delegate.getRuntimeTypeId(clazz);
-  }
-
-  @Override
-  public String getJsSymbolName(Class<?> clazz) {
-    return delegate.getJsSymbolName(clazz);
-  }
-
-  @Override
-  public String getTypeName(String seedName) {
-    return delegate.getTypeName(seedName);
-  }
-
-  @Override
-  public boolean isScript() {
-    return delegate.isScript();
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/HostedModeClientOracle.java b/user/src/com/google/gwt/rpc/server/HostedModeClientOracle.java
deleted file mode 100644
index 10c90e2..0000000
--- a/user/src/com/google/gwt/rpc/server/HostedModeClientOracle.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.client.impl.SimplePayloadSink;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.server.rpc.impl.SerializabilityUtil;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.lang.reflect.Field;
-
-/**
- * A ClientOracle that is used for hosted-mode clients. This type only
- * implements a limited subset of the ClientOracle functionality.
- */
-public final class HostedModeClientOracle extends ClientOracle {
-
-  @Override
-  public CommandSink createCommandSink(OutputStream out) throws IOException {
-    final BufferedWriter buffer = new BufferedWriter(new OutputStreamWriter(
-        out, "UTF-8"));
-
-    return new SimplePayloadSink(buffer) {
-      @Override
-      public void finish() throws SerializationException {
-        super.finish();
-        try {
-          buffer.flush();
-        } catch (IOException e) {
-          throw new SerializationException("Could not flush buffer", e);
-        }
-      }
-    };
-  }
-
-  /**
-   * Unimplemented.
-   */
-  @Override
-  public String createUnusedIdent(String ident) {
-    return unimplemented();
-  }
-
-  @Override
-  public CastableTypeData getCastableTypeData(Class<?> clazz) {
-    return unimplemented();
-  }
-
-  /**
-   * Unimplemented.
-   */
-  @Override
-  public String getFieldId(Class<?> clazz, String fieldName) {
-    return unimplemented();
-  }
-
-  /**
-   * Unimplemented.
-   */
-  @Override
-  public String getFieldId(Enum<?> value) {
-    return unimplemented();
-  }
-
-  /**
-   * Unimplemented.
-   */
-  @Override
-  public String getFieldId(String className, String fieldName) {
-    return unimplemented();
-  }
-
-  @Override
-  public Pair<Class<?>, String> getFieldName(Class<?> clazz, String fieldId) {
-    while (clazz != null) {
-      try {
-        clazz.getDeclaredField(fieldId);
-        return new Pair<Class<?>, String>(clazz, fieldId);
-      } catch (SecurityException e) {
-        // Fall through
-      } catch (NoSuchFieldException e) {
-        // Fall through
-      }
-      clazz = clazz.getSuperclass();
-    }
-    return null;
-  }
-
-  /**
-   * Unimplemented.
-   */
-  @Override
-  public String getMethodId(Class<?> clazz, String methodName, Class<?>... args) {
-    return unimplemented();
-  }
-
-  /**
-   * Unimplemented.
-   */
-  @Override
-  public String getMethodId(String className, String methodName,
-      String... jsniArgTypes) {
-    return unimplemented();
-  }
-
-  /**
-   * Falls back to reflectively analyzing the provided class.
-   */
-  @Override
-  public Field[] getOperableFields(Class<?> clazz) {
-    return SerializabilityUtil.applyFieldSerializationPolicy(clazz);
-  }
-
-  /**
-   * Unimplemented.
-   */
-  @Override
-  public String getRuntimeTypeId(Class<?> clazz) {
-    return unimplemented();
-  }
-
-  /**
-   * Unimplemented.
-   */
-  @Override
-  public String getJsSymbolName(Class<?> clazz) {
-    return unimplemented();
-  }
-
-  /**
-   * Unimplemented.
-   */
-  @Override
-  public String getTypeName(String seedName) {
-    return seedName;
-  }
-
-  /**
-   * Unimplemented.
-   */
-  @Override
-  public boolean isScript() {
-    return false;
-  }
-
-  private <T> T unimplemented() {
-    throw new RuntimeException("Not supported in Development Mode");
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/RPC.java b/user/src/com/google/gwt/rpc/server/RPC.java
deleted file mode 100644
index dc1abc4..0000000
--- a/user/src/com/google/gwt/rpc/server/RPC.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.client.ast.HasValues;
-import com.google.gwt.rpc.client.ast.ReturnCommand;
-import com.google.gwt.rpc.client.ast.RpcCommand;
-import com.google.gwt.rpc.client.ast.ThrowCommand;
-import com.google.gwt.rpc.client.impl.HasValuesCommandSink;
-import com.google.gwt.rpc.client.impl.RemoteException;
-import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
-import com.google.gwt.user.client.rpc.RemoteService;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.server.rpc.RPCRequest;
-import com.google.gwt.user.server.rpc.RPCServletUtils;
-import com.google.gwt.user.server.rpc.UnexpectedException;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * EXPERIMENTAL and subject to change. Do not use this in production code.
- * <p>
- * Utility class for integrating with the RPC system.
- */
-public class RPC {
-
-  private static final HashMap<String, Class<?>> TYPE_NAMES = new HashMap<String, Class<?>>();
-
-  /**
-   * Static map of classes to sets of interfaces (e.g. classes). Optimizes
-   * lookup of interfaces for security.
-   */
-  private static final Map<Class<?>, Set<String>> serviceToImplementedInterfacesMap = new HashMap<Class<?>, Set<String>>();
-
-  static {
-    // The space is needed to prevent name collisions
-    TYPE_NAMES.put(" Z", boolean.class);
-    TYPE_NAMES.put(" B", byte.class);
-    TYPE_NAMES.put(" C", char.class);
-    TYPE_NAMES.put(" D", double.class);
-    TYPE_NAMES.put(" F", float.class);
-    TYPE_NAMES.put(" I", int.class);
-    TYPE_NAMES.put(" J", long.class);
-    TYPE_NAMES.put(" S", short.class);
-  }
-
-  public static RPCRequest decodeRequest(String encodedRequest, Class<?> type,
-      ClientOracle clientOracle) throws RemoteException {
-    if (encodedRequest == null) {
-      throw new NullPointerException("encodedRequest cannot be null");
-    }
-
-    if (encodedRequest.length() == 0) {
-      throw new IllegalArgumentException("encodedRequest cannot be empty");
-    }
-
-    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-
-    try {
-      SimplePayloadDecoder decoder;
-      try {
-        decoder = new SimplePayloadDecoder(clientOracle, encodedRequest);
-      } catch (ClassNotFoundException e) {
-        throw new IncompatibleRemoteServiceException(
-            "Client does not have a type sent by the server", e);
-      }
-      CommandServerSerializationStreamReader streamReader = new CommandServerSerializationStreamReader();
-      if (decoder.getThrownValue() != null) {
-        streamReader.prepareToRead(Collections.singletonList(decoder.getThrownValue()));
-        try {
-          throw new RemoteException((Throwable) streamReader.readObject());
-        } catch (ClassCastException e) {
-          throw new SerializationException(
-              "The remote end threw something other than a Throwable", e);
-        } catch (SerializationException e) {
-          throw new IncompatibleRemoteServiceException(
-              "The remote end threw an exception which could not be deserialized",
-              e);
-        }
-      } else {
-        streamReader.prepareToRead(decoder.getValues());
-      }
-
-      // Read the name of the RemoteService interface
-      String serviceIntfName = streamReader.readString();
-
-      if (type != null) {
-        if (!implementsInterface(type, serviceIntfName)) {
-          // The service does not implement the requested interface
-          throw new IncompatibleRemoteServiceException(
-              "Blocked attempt to access interface '" + serviceIntfName
-                  + "', which is not implemented by '" + printTypeName(type)
-                  + "'; this is either misconfiguration or a hack attempt");
-        }
-      }
-
-      Class<?> serviceIntf;
-      try {
-        serviceIntf = getClassFromSerializedName(null, serviceIntfName,
-            classLoader);
-        if (!RemoteService.class.isAssignableFrom(serviceIntf)) {
-          // The requested interface is not a RpcService interface
-          throw new IncompatibleRemoteServiceException(
-              "Blocked attempt to access interface '"
-                  + printTypeName(serviceIntf)
-                  + "', which doesn't extend RpcService; "
-                  + "this is either misconfiguration or a hack attempt");
-        }
-      } catch (ClassNotFoundException e) {
-        throw new IncompatibleRemoteServiceException(
-            "Could not locate requested interface '" + serviceIntfName
-                + "' in default classloader", e);
-      }
-
-      String serviceMethodName = streamReader.readString();
-
-      int paramCount = streamReader.readInt();
-      Class<?>[] parameterTypes = new Class[paramCount];
-
-      for (int i = 0; i < parameterTypes.length; i++) {
-        String paramClassName = streamReader.readString();
-
-        try {
-          parameterTypes[i] = getClassFromSerializedName(clientOracle,
-              paramClassName, classLoader);
-        } catch (ClassNotFoundException e) {
-          throw new IncompatibleRemoteServiceException("Parameter " + i
-              + " of is of an unknown type '" + paramClassName + "'", e);
-        }
-      }
-
-      try {
-        Method method = serviceIntf.getMethod(serviceMethodName, parameterTypes);
-
-        Object[] parameterValues = new Object[parameterTypes.length];
-        for (int i = 0; i < parameterValues.length; i++) {
-          Object o = CommandSerializationUtil.getAccessor(parameterTypes[i]).readNext(
-              streamReader);
-          parameterValues[i] = o;
-        }
-
-        return new RPCRequest(method, parameterValues, null, null, 0);
-
-      } catch (NoSuchMethodException e) {
-        throw new IncompatibleRemoteServiceException(
-            formatMethodNotFoundErrorMessage(serviceIntf, serviceMethodName,
-                parameterTypes));
-      }
-    } catch (SerializationException ex) {
-      throw new IncompatibleRemoteServiceException(ex.getMessage(), ex);
-    }
-  }
-
-  public static void invokeAndStreamResponse(Object target,
-      Method serviceMethod, Object[] args, ClientOracle clientOracle,
-      OutputStream stream) throws SerializationException {
-    if (serviceMethod == null) {
-      throw new NullPointerException("serviceMethod");
-    }
-
-    if (clientOracle == null) {
-      throw new NullPointerException("clientOracle");
-    }
-
-    CommandSink sink;
-    try {
-      sink = clientOracle.createCommandSink(stream);
-    } catch (IOException e) {
-      throw new SerializationException("Unable to initialize output", e);
-    }
-
-    try {
-      Object result = serviceMethod.invoke(target, args);
-      try {
-        streamResponse(clientOracle, result, sink, false);
-      } catch (SerializationException e) {
-        streamResponse(clientOracle, e, sink, true);
-      }
-
-    } catch (IllegalAccessException e) {
-      SecurityException securityException = new SecurityException(
-          formatIllegalAccessErrorMessage(target, serviceMethod));
-      securityException.initCause(e);
-      throw securityException;
-    } catch (IllegalArgumentException e) {
-      SecurityException securityException = new SecurityException(
-          formatIllegalArgumentErrorMessage(target, serviceMethod, args));
-      securityException.initCause(e);
-      throw securityException;
-    } catch (InvocationTargetException e) {
-      // Try to encode the caught exception
-      Throwable cause = e.getCause();
-
-      // Don't allow random RuntimeExceptions to be thrown back to the client
-      if (!RPCServletUtils.isExpectedException(serviceMethod, cause)) {
-        throw new UnexpectedException("Service method '"
-            + getSourceRepresentation(serviceMethod)
-            + "' threw an unexpected exception: " + cause.toString(), cause);
-      }
-
-      streamResponse(clientOracle, cause, sink, true);
-    }
-    sink.finish();
-  }
-
-  public static void streamResponseForFailure(ClientOracle clientOracle,
-      OutputStream out, Throwable payload) throws SerializationException {
-    CommandSink sink;
-    try {
-      sink = clientOracle.createCommandSink(out);
-    } catch (IOException e) {
-      throw new SerializationException("Unable to initialize output", e);
-    }
-    streamResponse(clientOracle, payload, sink, true);
-    sink.finish();
-  }
-
-  public static void streamResponseForSuccess(ClientOracle clientOracle,
-      OutputStream out, Object payload) throws SerializationException {
-    CommandSink sink;
-    try {
-      sink = clientOracle.createCommandSink(out);
-    } catch (IOException e) {
-      throw new SerializationException("Unable to initialize output", e);
-    }
-    streamResponse(clientOracle, payload, sink, false);
-    sink.finish();
-  }
-
-  private static String formatIllegalAccessErrorMessage(Object target,
-      Method serviceMethod) {
-    StringBuffer sb = new StringBuffer();
-    sb.append("Blocked attempt to access inaccessible method '");
-    sb.append(getSourceRepresentation(serviceMethod));
-    sb.append("'");
-
-    if (target != null) {
-      sb.append(" on target '");
-      sb.append(printTypeName(target.getClass()));
-      sb.append("'");
-    }
-
-    sb.append("; this is either misconfiguration or a hack attempt");
-
-    return sb.toString();
-  }
-
-  private static String formatIllegalArgumentErrorMessage(Object target,
-      Method serviceMethod, Object[] args) {
-    StringBuffer sb = new StringBuffer();
-    sb.append("Blocked attempt to invoke method '");
-    sb.append(getSourceRepresentation(serviceMethod));
-    sb.append("'");
-
-    if (target != null) {
-      sb.append(" on target '");
-      sb.append(printTypeName(target.getClass()));
-      sb.append("'");
-    }
-
-    sb.append(" with invalid arguments");
-
-    if (args != null && args.length > 0) {
-      sb.append(Arrays.asList(args));
-    }
-
-    return sb.toString();
-  }
-
-  private static String formatMethodNotFoundErrorMessage(Class<?> serviceIntf,
-      String serviceMethodName, Class<?>[] parameterTypes) {
-    StringBuffer sb = new StringBuffer();
-
-    sb.append("Could not locate requested method '");
-    sb.append(serviceMethodName);
-    sb.append("(");
-    for (int i = 0; i < parameterTypes.length; ++i) {
-      if (i > 0) {
-        sb.append(", ");
-      }
-      sb.append(printTypeName(parameterTypes[i]));
-    }
-    sb.append(")'");
-
-    sb.append(" in interface '");
-    sb.append(printTypeName(serviceIntf));
-    sb.append("'");
-
-    return sb.toString();
-  }
-
-  /**
-   * Returns the {@link Class} instance for the named class or primitive type.
-   * 
-   * @param serializedName the serialized name of a class or primitive type
-   * @param classLoader the classLoader used to load {@link Class}es
-   * @return Class instance for the given type name
-   * @throws ClassNotFoundException if the named type was not found
-   */
-  private static Class<?> getClassFromSerializedName(ClientOracle clientOracle,
-      String serializedName, ClassLoader classLoader)
-      throws ClassNotFoundException {
-    Class<?> value = TYPE_NAMES.get(serializedName);
-    if (value != null) {
-      return value;
-    }
-
-    // Interfaces don't exist in the client, so we use unobfuscated names
-    if (serializedName.charAt(0) == ' ') {
-      serializedName = serializedName.substring(1);
-    } else if (clientOracle != null) {
-      serializedName = clientOracle.getTypeName(serializedName);
-    }
-    assert serializedName != null;
-
-    return Class.forName(serializedName, false, classLoader);
-  }
-
-  /**
-   * Returns the source representation for a method signature.
-   * 
-   * @param method method to get the source signature for
-   * @return source representation for a method signature
-   */
-  private static String getSourceRepresentation(Method method) {
-    return method.toString().replace('$', '.');
-  }
-
-  /**
-   * Used to determine whether the specified interface name is implemented by
-   * the service class. This is done without loading the class (for security).
-   */
-  private static boolean implementsInterface(Class<?> service, String intfName) {
-    synchronized (serviceToImplementedInterfacesMap) {
-      // See if it's cached.
-      //
-      Set<String> interfaceSet = serviceToImplementedInterfacesMap.get(service);
-      if (interfaceSet != null) {
-        if (interfaceSet.contains(intfName)) {
-          return true;
-        }
-      } else {
-        interfaceSet = new HashSet<String>();
-        serviceToImplementedInterfacesMap.put(service, interfaceSet);
-      }
-
-      if (!service.isInterface()) {
-        while ((service != null) && !RpcServlet.class.equals(service)) {
-          Class<?>[] intfs = service.getInterfaces();
-          for (Class<?> intf : intfs) {
-            if (implementsInterfaceRecursive(intf, intfName)) {
-              interfaceSet.add(intfName);
-              return true;
-            }
-          }
-
-          // did not find the interface in this class so we look in the
-          // superclass
-          //
-          service = service.getSuperclass();
-        }
-      } else {
-        if (implementsInterfaceRecursive(service, intfName)) {
-          interfaceSet.add(intfName);
-          return true;
-        }
-      }
-
-      return false;
-    }
-  }
-
-  /**
-   * Recursive helper for implementsInterface().
-   */
-  private static boolean implementsInterfaceRecursive(Class<?> clazz,
-      String intfName) {
-    assert (clazz.isInterface());
-
-    if (clazz.getName().equals(intfName)) {
-      return true;
-    }
-
-    // search implemented interfaces
-    Class<?>[] intfs = clazz.getInterfaces();
-    for (Class<?> intf : intfs) {
-      if (implementsInterfaceRecursive(intf, intfName)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  /**
-   * Straight copy from
-   * {@link com.google.gwt.dev.util.TypeInfo#getSourceRepresentation(Class)} to
-   * avoid runtime dependency on gwt-dev.
-   */
-  private static String printTypeName(Class<?> type) {
-    // Primitives
-    //
-    if (type.equals(Integer.TYPE)) {
-      return "int";
-    } else if (type.equals(Long.TYPE)) {
-      return "long";
-    } else if (type.equals(Short.TYPE)) {
-      return "short";
-    } else if (type.equals(Byte.TYPE)) {
-      return "byte";
-    } else if (type.equals(Character.TYPE)) {
-      return "char";
-    } else if (type.equals(Boolean.TYPE)) {
-      return "boolean";
-    } else if (type.equals(Float.TYPE)) {
-      return "float";
-    } else if (type.equals(Double.TYPE)) {
-      return "double";
-    }
-
-    // Arrays
-    //
-    if (type.isArray()) {
-      Class<?> componentType = type.getComponentType();
-      return printTypeName(componentType) + "[]";
-    }
-
-    // Everything else
-    //
-    return type.getName().replace('$', '.');
-  }
-
-  private static void streamResponse(ClientOracle clientOracle, Object payload,
-      CommandSink sink, boolean asThrow) throws SerializationException {
-    HasValues command;
-    if (asThrow) {
-      command = new ThrowCommand();
-      assert payload instanceof Throwable : "Trying to throw something other than a Throwable";
-      // payload = new RemoteException((Throwable) payload);
-    } else {
-      command = new ReturnCommand();
-    }
-
-    CommandServerSerializationStreamWriter out = new CommandServerSerializationStreamWriter(
-        clientOracle, new HasValuesCommandSink(command));
-
-    out.writeObject(payload);
-
-    sink.accept((RpcCommand) command);
-  }
-
-  private RPC() {
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/RpcServlet.java b/user/src/com/google/gwt/rpc/server/RpcServlet.java
deleted file mode 100644
index f7c5c0d..0000000
--- a/user/src/com/google/gwt/rpc/server/RpcServlet.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import static com.google.gwt.user.client.rpc.RpcRequestBuilder.MODULE_BASE_HEADER;
-
-import com.google.gwt.rpc.client.impl.RemoteException;
-import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet;
-import com.google.gwt.user.server.rpc.RPCRequest;
-import com.google.gwt.user.server.rpc.RPCServletUtils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.ref.SoftReference;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.zip.GZIPOutputStream;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * EXPERIMENTAL and subject to change. Do not use this in production code.
- * <p>
- * The servlet base class for your RPC service implementations that
- * automatically deserializes incoming requests from the client and serializes
- * outgoing responses for client/server RPCs.
- */
-public class RpcServlet extends AbstractRemoteServiceServlet {
-
-  protected static final String CLIENT_ORACLE_EXTENSION = ".gwt.rpc";
-  private static final boolean DUMP_PAYLOAD = Boolean.getBoolean("gwt.rpc.dumpPayload");
-
-  private final Map<String, SoftReference<ClientOracle>> clientOracleCache = new ConcurrentHashMap<String, SoftReference<ClientOracle>>();
-
-  /**
-   * The implementation of the service.
-   */
-  private final Object delegate;
-
-  /**
-   * The default constructor used by service implementations that
-   * extend this class.  The servlet will delegate AJAX requests to
-   * the appropriate method in the subclass.
-   */
-  public RpcServlet() {
-    this.delegate = this;
-  }
-
-  /**
-   * The wrapping constructor used by service implementations that are
-   * separate from this class.  The servlet will delegate AJAX
-   * requests to the appropriate method in the given object.
-   */
-  public RpcServlet(Object delegate) {
-    this.delegate = delegate;
-  }
-
-  /**
-   * This method creates the ClientOracle that will provide data about the
-   * remote client. It delegates to
-   * {@link #findClientOracleData(String, String)} to obtain access to
-   * ClientOracle data emitted by the GWT compiler.
-   */
-  public ClientOracle getClientOracle() throws SerializationException {
-    String permutationStrongName = getPermutationStrongName();
-    if (permutationStrongName == null) {
-      throw new SecurityException(
-          "Blocked request without GWT permutation header (XSRF attack?)");
-    }
-    String basePath = getRequestModuleBasePath();
-    if (basePath == null) {
-      throw new SecurityException(
-          "Blocked request without GWT base path header (XSRF attack?)");
-    }
-
-    ClientOracle toReturn;
-
-    // Fast path if the ClientOracle is already cached.
-    if (clientOracleCache.containsKey(permutationStrongName)) {
-      toReturn = clientOracleCache.get(permutationStrongName).get();
-      if (toReturn != null) {
-        return toReturn;
-      }
-    }
-
-    /* Synchronize to make sure expensive calls are executed only once.
-       Double checked locking idiom works here because of volatiles in
-       ConcurrentHashMap.*/
-    synchronized (clientOracleCache) {
-      if (clientOracleCache.containsKey(permutationStrongName)) {
-        toReturn = clientOracleCache.get(permutationStrongName).get();
-        if (toReturn != null) {
-          return toReturn;
-        }
-      }
-
-      if ("HostedMode".equals(permutationStrongName)) {
-        if (!allowHostedModeConnections()) {
-          throw new SecurityException("Blocked Development Mode request");
-        }
-        toReturn = new HostedModeClientOracle();
-      } else {
-        InputStream in = findClientOracleData(basePath, permutationStrongName);
-
-        try {
-          toReturn = WebModeClientOracle.load(in);
-        } catch (IOException e) {
-          throw new SerializationException(
-              "Could not load serialization policy for permutation "
-                  + permutationStrongName, e);
-        }
-      }
-      clientOracleCache.put(permutationStrongName,
-          new SoftReference<ClientOracle>(toReturn));
-    }
-
-    return toReturn;
-  }
-
-  /**
-   * Process a call originating from the given request. Uses the
-   * {@link RPC#invokeAndStreamResponse(Object, java.lang.reflect.Method, Object[], ClientOracle, OutputStream)}
-   * method to do the actual work.
-   * <p>
-   * Subclasses may optionally override this method to handle the payload in any
-   * way they desire (by routing the request to a framework component, for
-   * instance). The {@link HttpServletRequest} and {@link HttpServletResponse}
-   * can be accessed via the {@link #getThreadLocalRequest()} and
-   * {@link #getThreadLocalResponse()} methods.
-   * </p>
-   * This is public so that it can be unit tested easily without HTTP.
-   * 
-   * @param clientOracle the ClientOracle that will be used to interpret the
-   *          request
-   * @param payload the UTF-8 request payload
-   * @param stream the OutputStream that will receive the encoded response
-   * @throws SerializationException if we cannot serialize the response
-   */
-  public void processCall(ClientOracle clientOracle, String payload,
-      OutputStream stream) throws SerializationException {
-    assert clientOracle != null : "clientOracle";
-    assert payload != null : "payload";
-    assert stream != null : "stream";
-
-    try {
-      RPCRequest rpcRequest = RPC.decodeRequest(payload, delegate.getClass(),
-          clientOracle);
-      onAfterRequestDeserialized(rpcRequest);
-      RPC.invokeAndStreamResponse(delegate, rpcRequest.getMethod(),
-          rpcRequest.getParameters(), clientOracle, stream);
-    } catch (RemoteException ex) {
-      throw new SerializationException("An exception was sent from the client",
-          ex.getCause());
-    } catch (IncompatibleRemoteServiceException ex) {
-      log(
-          "An IncompatibleRemoteServiceException was thrown while processing this call.",
-          ex);
-      RPC.streamResponseForFailure(clientOracle, stream, ex);
-    }
-  }
-
-  /**
-   * Standard HttpServlet method: handle the POST.
-   * 
-   * This doPost method swallows ALL exceptions, logs them in the
-   * ServletContext, and returns a GENERIC_FAILURE_MSG response with status code
-   * 500.
-   * 
-   * @throws IOException
-   * @throws ServletException
-   * @throws SerializationException
-   */
-  @Override
-  public final void processPost(HttpServletRequest request,
-      HttpServletResponse response) throws ServletException, IOException,
-      SerializationException {
-
-    /*
-     * Get the ClientOracle before doing anything else, so that if ClientOracle
-     * cannot be loaded, we haven't opened the response's OutputStream.
-     */
-    ClientOracle clientOracle = getClientOracle();
-
-    // Read the request fully.
-    String requestPayload = readContent(request);
-    if (DUMP_PAYLOAD) {
-      System.out.println(requestPayload);
-    }
-
-    response.setContentType("application/json");
-    response.setCharacterEncoding("UTF-8");
-
-    // Configure the OutputStream based on configuration and capabilities
-    boolean canCompress = RPCServletUtils.acceptsGzipEncoding(request)
-        && shouldCompressResponse(request, response);
-
-    OutputStream out;
-    if (DUMP_PAYLOAD) {
-      out = new ByteArrayOutputStream();
-
-    } else if (canCompress) {
-      RPCServletUtils.setGzipEncodingHeader(response);
-      out = new GZIPOutputStream(response.getOutputStream());
-
-    } else {
-      out = response.getOutputStream();
-    }
-
-    // Invoke the core dispatching logic, which returns the serialized result.
-    processCall(clientOracle, requestPayload, out);
-
-    if (DUMP_PAYLOAD) {
-      byte[] bytes = ((ByteArrayOutputStream) out).toByteArray();
-      System.out.println(new String(bytes, "UTF-8"));
-      response.getOutputStream().write(bytes);
-    } else if (canCompress) {
-      /*
-       * We want to write the end of the gzip data, but not close the underlying
-       * OutputStream in case there are servlet filters that want to write
-       * headers after processPost().
-       */
-      ((GZIPOutputStream) out).finish();
-    }
-  }
-
-  /**
-   * Indicates whether or not an RPC request from a Development Mode client
-   * should be serviced. Requests from Development Mode clients will expose
-   * unobfuscated identifiers in the payload. It is intended that developers
-   * override this method to restrict access based on installation-specific
-   * logic (such as a range of IP addresses, checking for certain cookies, etc.)
-   * <p>
-   * The default implementation allows hosted-mode connections from the local
-   * host, loopback addresses (127.*), site local (RFC 1918), link local
-   * (169.254/16) addresses, and their IPv6 equivalents.
-   *
-   * @return <code>true</code> if a Development Mode connection should be
-   *         allowed
-   * @see #getThreadLocalRequest()
-   * @see InetAddress
-   */
-  protected boolean allowHostedModeConnections() {
-    return isRequestFromLocalAddress();
-  }
-
-  /**
-   * Override this method to control access to permutation-specific data. For
-   * instance, the permutation-specific data may be stored in a database in
-   * order to support older clients.
-   * <p>
-   * The default implementation attempts to load the file from the
-   * ServletContext as
-   * 
-   * <code>requestModuleBasePath + permutationStrongName + CLIENT_ORACLE_EXTENSION</code>
-   * 
-   * @param requestModuleBasePath the module's base path, modulo protocol and
-   *          host, as reported by {@link #getRequestModuleBasePath()}
-   * @param permutationStrongName the module's strong name as reported by
-   *          {@link #getPermutationStrongName()}
-   */
-  protected InputStream findClientOracleData(String requestModuleBasePath,
-      String permutationStrongName) throws SerializationException {
-    String resourcePath = requestModuleBasePath + permutationStrongName
-        + CLIENT_ORACLE_EXTENSION;
-    InputStream in = getServletContext().getResourceAsStream(resourcePath);
-    if (in == null) {
-      throw new SerializationException(
-          "Could not find ClientOracle data for permutation "
-              + permutationStrongName);
-    }
-    return in;
-  }
-
-  /**
-   * Extract the module's base path from the current request.
-   * 
-   * @return the module's base path, modulo protocol and host, as reported by
-   *         {@link com.google.gwt.core.client.GWT#getModuleBaseURL()} or
-   *         <code>null</code> if the request did not contain the
-   *         {@value com.google.gwt.user.client.rpc.RpcRequestBuilder#MODULE_BASE_HEADER} header
-   */
-  protected final String getRequestModuleBasePath() {
-    try {
-      String header = getThreadLocalRequest().getHeader(MODULE_BASE_HEADER);
-      if (header == null) {
-        return null;
-      }
-      String path = new URL(header).getPath();
-      String contextPath = getThreadLocalRequest().getContextPath();
-      if (!path.startsWith(contextPath)) {
-        return null;
-      }
-      return path.substring(contextPath.length());
-    } catch (MalformedURLException e) {
-      return null;
-    }
-  }
-
-  /**
-   * Determines whether the response to a given servlet request should or should
-   * not be GZIP compressed. This method is only called in cases where the
-   * requester accepts GZIP encoding.
-   * <p>
-   * This implementation currently returns <code>true</code> if the request
-   * originates from a non-local address. Subclasses can override this logic.
-   * </p>
-   * 
-   * @param request the request being served
-   * @param response the response that will be written into
-   * @return <code>true</code> if responsePayload should be GZIP compressed,
-   *         otherwise <code>false</code>.
-   */
-  protected boolean shouldCompressResponse(HttpServletRequest request,
-      HttpServletResponse response) {
-    return !isRequestFromLocalAddress();
-  }
-
-  /**
-   * Utility function to determine if the thread-local request originates from a
-   * local address.
-   */
-  private boolean isRequestFromLocalAddress() {
-    try {
-      InetAddress addr = InetAddress.getByName(getThreadLocalRequest().getRemoteAddr());
-
-      return InetAddress.getLocalHost().equals(addr)
-          || addr.isLoopbackAddress() || addr.isSiteLocalAddress()
-          || addr.isLinkLocalAddress();
-    } catch (UnknownHostException e) {
-      return false;
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/SimplePayloadDecoder.java b/user/src/com/google/gwt/rpc/server/SimplePayloadDecoder.java
deleted file mode 100644
index a9fd42d..0000000
--- a/user/src/com/google/gwt/rpc/server/SimplePayloadDecoder.java
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.ARRAY_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.BACKREF_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.BOOLEAN_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.BYTE_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.CHAR_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.DOUBLE_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.ENUM_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.FLOAT_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.INT_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.INVOKE_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.LONG_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.NL_CHAR;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.OBJECT_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.RETURN_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.RPC_SEPARATOR_CHAR;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.SHORT_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.STRING_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.THROW_TYPE;
-import static com.google.gwt.rpc.client.impl.SimplePayloadSink.VOID_TYPE;
-
-import com.google.gwt.rpc.client.ast.ArrayValueCommand;
-import com.google.gwt.rpc.client.ast.BooleanValueCommand;
-import com.google.gwt.rpc.client.ast.ByteValueCommand;
-import com.google.gwt.rpc.client.ast.CharValueCommand;
-import com.google.gwt.rpc.client.ast.DoubleValueCommand;
-import com.google.gwt.rpc.client.ast.EnumValueCommand;
-import com.google.gwt.rpc.client.ast.FloatValueCommand;
-import com.google.gwt.rpc.client.ast.HasSetters;
-import com.google.gwt.rpc.client.ast.IdentityValueCommand;
-import com.google.gwt.rpc.client.ast.InstantiateCommand;
-import com.google.gwt.rpc.client.ast.IntValueCommand;
-import com.google.gwt.rpc.client.ast.InvokeCustomFieldSerializerCommand;
-import com.google.gwt.rpc.client.ast.LongValueCommand;
-import com.google.gwt.rpc.client.ast.NullValueCommand;
-import com.google.gwt.rpc.client.ast.ReturnCommand;
-import com.google.gwt.rpc.client.ast.RpcCommand;
-import com.google.gwt.rpc.client.ast.ScalarValueCommand;
-import com.google.gwt.rpc.client.ast.ShortValueCommand;
-import com.google.gwt.rpc.client.ast.StringValueCommand;
-import com.google.gwt.rpc.client.ast.ValueCommand;
-import com.google.gwt.user.server.rpc.impl.SerializabilityUtil;
-
-import java.lang.reflect.Array;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * Decodes the simple payload.
- */
-public class SimplePayloadDecoder {
-  private static final String OBFUSCATED_CLASS_PREFIX = "Class$ ";
-  private static final Map<String, Class<?>> PRIMITIVE_TYPES = new HashMap<String, Class<?>>();
-
-  static {
-    // Obfuscated when class metadata is disabled
-    PRIMITIVE_TYPES.put(OBFUSCATED_CLASS_PREFIX + BOOLEAN_TYPE, boolean.class);
-    PRIMITIVE_TYPES.put(OBFUSCATED_CLASS_PREFIX + BYTE_TYPE, byte.class);
-    PRIMITIVE_TYPES.put(OBFUSCATED_CLASS_PREFIX + CHAR_TYPE, char.class);
-    PRIMITIVE_TYPES.put(OBFUSCATED_CLASS_PREFIX + DOUBLE_TYPE, double.class);
-    PRIMITIVE_TYPES.put(OBFUSCATED_CLASS_PREFIX + FLOAT_TYPE, float.class);
-    PRIMITIVE_TYPES.put(OBFUSCATED_CLASS_PREFIX + INT_TYPE, int.class);
-    PRIMITIVE_TYPES.put(OBFUSCATED_CLASS_PREFIX + LONG_TYPE, long.class);
-    PRIMITIVE_TYPES.put(OBFUSCATED_CLASS_PREFIX + SHORT_TYPE, short.class);
-    PRIMITIVE_TYPES.put(OBFUSCATED_CLASS_PREFIX + VOID_TYPE, void.class);
-
-    // Regular
-    PRIMITIVE_TYPES.put(boolean.class.getName(), boolean.class);
-    PRIMITIVE_TYPES.put(byte.class.getName(), byte.class);
-    PRIMITIVE_TYPES.put(char.class.getName(), char.class);
-    PRIMITIVE_TYPES.put(double.class.getName(), double.class);
-    PRIMITIVE_TYPES.put(float.class.getName(), float.class);
-    PRIMITIVE_TYPES.put(int.class.getName(), int.class);
-    PRIMITIVE_TYPES.put(long.class.getName(), long.class);
-    PRIMITIVE_TYPES.put(short.class.getName(), short.class);
-    PRIMITIVE_TYPES.put(void.class.getName(), void.class);
-  }
-
-  private final Map<Integer, ValueCommand> backRefs = new HashMap<Integer, ValueCommand>();
-  private final Map<String, Class<?>> classCache = new HashMap<String, Class<?>>(
-      PRIMITIVE_TYPES);
-  private final ClientOracle clientOracle;
-  private final Stack<RpcCommand> commands = new Stack<RpcCommand>();
-  private int idx;
-  private final CharSequence payload;
-  private ReturnCommand toReturn;
-  private ValueCommand toThrow;
-
-  /**
-   * Construct a new SimplePayloadDecoder. This will consume the entire payload
-   * which will be made available through {@link #getValues}. If the payload
-   * stream contains an embedded exception, processing will end early and the
-   * Throwable will be available via {@link #getThrownValue()}.
-   * 
-   * @throws ClassNotFoundException
-   */
-  public SimplePayloadDecoder(ClientOracle clientOracle, CharSequence payload)
-      throws ClassNotFoundException {
-    this.clientOracle = clientOracle;
-    this.payload = payload;
-    while (toReturn == null && idx < payload.length()) {
-      decodeCommand();
-
-      // We hit an error in the stream; stop now
-      if (toThrow != null) {
-        return;
-      }
-    }
-  }
-
-  /**
-   * Returns the thrown value, if any.
-   */
-  public ValueCommand getThrownValue() {
-    return toThrow;
-  }
-
-  /**
-   * Returns the values encoded in the payload.
-   */
-  public List<ValueCommand> getValues() {
-    return toReturn == null ? Collections.<ValueCommand> emptyList()
-        : toReturn.getValues();
-  }
-
-  private void decodeCommand() throws ClassNotFoundException {
-    char command = next();
-    if (command == NL_CHAR) {
-      // Pretty mode payload
-      command = next();
-    }
-    String token = token();
-    switch (command) {
-      case BOOLEAN_TYPE: {
-        push(new BooleanValueCommand(token.equals("1")));
-        break;
-      }
-      case BYTE_TYPE: {
-        push(new ByteValueCommand(Byte.valueOf(token)));
-        break;
-      }
-      case CHAR_TYPE: {
-        push(new CharValueCommand(Character.valueOf((char) Integer.valueOf(
-            token).intValue())));
-        break;
-      }
-      case DOUBLE_TYPE: {
-        push(new DoubleValueCommand(Double.valueOf(token)));
-        break;
-      }
-      case FLOAT_TYPE: {
-        push(new FloatValueCommand(Float.valueOf(token)));
-        break;
-      }
-      case INT_TYPE: {
-        push(new IntValueCommand(Integer.valueOf(token)));
-        break;
-      }
-      case LONG_TYPE: {
-        push(new LongValueCommand(Long.valueOf(token)));
-        break;
-      }
-      case VOID_TYPE: {
-        push(NullValueCommand.INSTANCE);
-        break;
-      }
-      case SHORT_TYPE: {
-        push(new ShortValueCommand(Short.valueOf(token)));
-        break;
-      }
-      case STRING_TYPE: {
-        // "4~abcd
-        int length = Integer.valueOf(token);
-        String value = next(length);
-        if (next() != RPC_SEPARATOR_CHAR) {
-          throw new RuntimeException("Overran string");
-        }
-        push(new StringValueCommand(value));
-        break;
-      }
-      case ENUM_TYPE: {
-        // ETypeSeedName~IOrdinal~
-        EnumValueCommand x = new EnumValueCommand();
-        push(x);
-        
-        // use ordinal (and not name), since name might have been obfuscated
-        int ordinal = readCommand(IntValueCommand.class).getValue();
-
-        @SuppressWarnings("rawtypes")
-        Class<? extends Enum> clazz = findClass(token).asSubclass(Enum.class);
-        
-        /*
-         * TODO: Note this approach could be prone to subtle corruption or
-         * an ArrayOutOfBoundsException if the client and server have drifted.
-         */
-        Enum<?> enumConstants[] = clazz.getEnumConstants();
-        x.setValue(enumConstants[ordinal]);
-        break;
-      }
-      case ARRAY_TYPE: {
-        // Encoded as (leafType, dimensions, length, .... )
-        Class<?> leaf = findClass(token);
-
-        Integer numDims = readCommand(IntValueCommand.class).getValue();
-        Class<?> clazz;
-        if (numDims > 1) {
-          int[] dims = new int[numDims - 1];
-          clazz = Array.newInstance(leaf, dims).getClass();
-        } else {
-          clazz = leaf;
-        }
-
-        ArrayValueCommand x = new ArrayValueCommand(clazz);
-        push(x);
-        int length = readCommand(IntValueCommand.class).getValue();
-        for (int i = 0; i < length; i++) {
-          x.add(readCommand(ValueCommand.class));
-        }
-        break;
-      }
-      case OBJECT_TYPE: {
-        // @TypeSeedName~3~... N-many setters ...
-        Class<?> clazz = findClass(token);
-        InstantiateCommand x = new InstantiateCommand(clazz);
-        push(x);
-        readSetters(clazz, x);
-        break;
-      }
-      case INVOKE_TYPE: {
-        // !TypeSeedName~Number of objects written by CFS~...CFS objects...~
-        // Number of extra fields~...N-many setters...
-        Class<?> clazz = findClass(token);
-        Class<?> serializerClass = null;
-
-        // The custom serializer type might be for a supertype
-        Class<?> manualType = clazz;
-        while (manualType != null) {
-          serializerClass = SerializabilityUtil.hasCustomFieldSerializer(manualType);
-          if (serializerClass != null) {
-            break;
-          }
-          manualType = manualType.getSuperclass();
-        }
-
-        InvokeCustomFieldSerializerCommand x = new InvokeCustomFieldSerializerCommand(
-            clazz, serializerClass, manualType);
-        push(x);
-
-        readFields(x);
-        readSetters(clazz, x);
-        break;
-      }
-      case RETURN_TYPE: {
-        // R4~...values...
-        toReturn = new ReturnCommand();
-        int toRead = Integer.valueOf(token);
-        for (int i = 0; i < toRead; i++) {
-          toReturn.addValue(readCommand(ValueCommand.class));
-        }
-        break;
-      }
-      case THROW_TYPE: {
-        // T...value...
-        toThrow = readCommand(ValueCommand.class);
-        break;
-      }
-      case BACKREF_TYPE: {
-        // @backrefNumber~
-        ValueCommand x = backRefs.get(Integer.valueOf(token));
-        assert x != null : "Could not find backref";
-        commands.push(x);
-        break;
-      }
-      case RPC_SEPARATOR_CHAR: {
-        /*
-         * Not strictly necessary, but it makes an off-by-one easier to
-         * distinguish.
-         */
-        throw new RuntimeException("Segmentation overrun at " + idx);
-      }
-      default:
-        throw new RuntimeException("Unknown command " + command);
-    }
-  }
-
-  /**
-   * Uses the ClientOracle to decode a type name.
-   */
-  private Class<?> findClass(String token) throws ClassNotFoundException {
-    /*
-     * NB: This is the only method in SimplePayloadDecoder which would require
-     * any real adaptation to be made to run in Production Mode.
-     */
-
-    Class<?> clazz = classCache.get(token);
-    if (clazz != null) {
-      return clazz;
-    }
-
-    String className = clientOracle.getTypeName(token);
-    if (className == null) {
-      // Probably a regular class name
-      className = token;
-    }
-
-    if (className.contains("[]")) {
-      // Array types are annoying to construct
-      int firstIndex = -1;
-      int j = -1;
-      int dims = 0;
-      while ((j = className.indexOf("[", j + 1)) != -1) {
-        if (dims++ == 0) {
-          firstIndex = j;
-        }
-      }
-      Class<?> componentType = findClass(className.substring(0, firstIndex));
-      assert componentType != null : "Could not determine component type with "
-          + className.substring(0, firstIndex);
-      clazz = Array.newInstance(componentType, new int[dims]).getClass();
-    } else {
-      // Ensure that we use the bridge classloader in CCL
-      ClassLoader myCCL = getClass().getClassLoader();
-      clazz = Class.forName(className, false, myCCL);
-    }
-    classCache.put(token, clazz);
-    return clazz;
-  }
-
-  /**
-   * Reads the next character in the input, possibly evaluating escape
-   * sequences.
-   */
-  private char next() {
-    char c = payload.charAt(idx++);
-
-    if (c == '\\') {
-      switch (payload.charAt(idx++)) {
-        case '0':
-          c = '\0';
-          break;
-        case '!':
-          // Compatibility since we're using the legacy escaping code
-          c = '|';
-          break;
-        case 'b':
-          c = '\b';
-          break;
-        case 't':
-          c = '\t';
-          break;
-        case 'n':
-          c = '\n';
-          break;
-        case 'f':
-          c = '\f';
-          break;
-        case 'r':
-          c = '\r';
-          break;
-        case '\\':
-          c = '\\';
-          break;
-        case '"':
-          c = '"';
-          break;
-        case 'u':
-          c = (char) Integer.parseInt(
-              payload.subSequence(idx, idx += 4).toString(), 16);
-          break;
-        case 'x':
-          c = (char) Integer.parseInt(
-              payload.subSequence(idx, idx += 2).toString(), 16);
-          break;
-        default:
-          throw new RuntimeException("Unhandled escape " + payload.charAt(idx));
-      }
-    }
-    return c;
-  }
-
-  /**
-   * Reads <code>count</code> many characters and returns them as a string.
-   */
-  private String next(int count) {
-    StringBuilder sb = new StringBuilder();
-    while (count-- > 0) {
-      sb.append(next());
-    }
-    return sb.toString();
-  }
-
-  /**
-   * Retains the object value and establishes a backreference.
-   */
-  private void push(IdentityValueCommand x) {
-    commands.push(x);
-    backRefs.put(backRefs.size(), x);
-  }
-
-  /**
-   * Retains the scalar value, but does not establish a backreference.
-   */
-  private void push(ScalarValueCommand x) {
-    commands.push(x);
-  }
-
-  /**
-   * Retains the string value and establishes a backreference.
-   */
-  private void push(StringValueCommand x) {
-    commands.push(x);
-    backRefs.put(backRefs.size(), x);
-  }
-
-  /**
-   * Read one command from the stream.
-   * 
-   * @param <T> the expected type of RpcCommand to read
-   * @param clazz the expected type of RpcCommand to read
-   * @throws ClassCastException if a command was successfully read, but could
-   *           not be assigned to <code>clazz</code>
-   */
-  private <T extends RpcCommand> T readCommand(Class<T> clazz)
-      throws ClassNotFoundException {
-    decodeCommand();
-    RpcCommand value = commands.pop();
-    assert clazz.isInstance(value) : "Cannot assign a "
-        + value.getClass().getName() + " to " + clazz.getName();
-    return clazz.cast(value);
-  }
-
-  /**
-   * Format is (int, value...).
-   */
-  private void readFields(InvokeCustomFieldSerializerCommand x)
-      throws ClassNotFoundException {
-    int length = readCommand(IntValueCommand.class).getValue();
-    for (int i = 0; i < length; i++) {
-      x.addValue(readCommand(ValueCommand.class));
-    }
-  }
-
-  /**
-   * Format is (fieldDeclClassName, fieldId, value). fieldDeclClassName may be
-   * null.
-   */
-  private void readSetter(Class<?> clazz, HasSetters x)
-      throws ClassNotFoundException {
-    // Only used by Development Mode to handle shadowing
-    if (!clientOracle.isScript()) {
-      String fieldDeclClassName = readCommand(StringValueCommand.class).getValue();
-      if (fieldDeclClassName != null) {
-        clazz = findClass(fieldDeclClassName);
-      }
-    }
-    String fieldId = readCommand(StringValueCommand.class).getValue();
-
-    Pair<Class<?>, String> data = clientOracle.getFieldName(clazz, fieldId);
-    Class<?> fieldDeclClass = data.getA();
-    String fieldName = data.getB();
-    ValueCommand value = readCommand(ValueCommand.class);
-    x.set(fieldDeclClass, fieldName, value);
-  }
-
-  /**
-   * Format is (int, setter...).
-   */
-  private void readSetters(Class<?> clazz, HasSetters x)
-      throws ClassNotFoundException {
-    int length = readCommand(IntValueCommand.class).getValue();
-    for (int i = 0; i < length; i++) {
-      readSetter(clazz, x);
-    }
-  }
-
-  /**
-   * Read through the next separator character.
-   */
-  private String token() {
-    StringBuilder sb = new StringBuilder();
-    char n = next();
-    while (n != RPC_SEPARATOR_CHAR) {
-      sb.append(n);
-      n = next();
-    }
-    return sb.toString();
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/WebModeClientOracle.java b/user/src/com/google/gwt/rpc/server/WebModeClientOracle.java
deleted file mode 100644
index 4e30fd7..0000000
--- a/user/src/com/google/gwt/rpc/server/WebModeClientOracle.java
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.GZIPOutputStream;
-
-/**
- * Encapsulates data about the structure of the client code.
- */
-public final class WebModeClientOracle extends ClientOracle implements
-    Serializable {
-  /*
-   * TODO: Don't use Java serialization.
-   */
-
-  /**
-   * A Builder object to create ClientOracles.
-   */
-  public static class Builder {
-    private WebModeClientOracle oracle = new WebModeClientOracle();
-
-    public void add(String jsIdent, String jsniIdent, String className,
-        String memberName, String runtimeTypeId, CastableTypeData castableTypeData) {
-
-      oracle.idents.add(jsIdent);
-      ClassData data = oracle.getClassData(className);
-
-      /*
-       * Don't overwrite castableTypeData and runtimeTypeId if already set.
-       * There are many versions of symbols for a given className,
-       * corresponding to the type of member fields, etc.,
-       * which don't have the runtimeTypeId or castableTypeData initialized.  Only
-       * the symbol data for the class itself has this info.
-       */
-      if (data.castableTypeData == null) {
-        data.runtimeTypeId = runtimeTypeId;
-        data.castableTypeData = castableTypeData;
-      }
-
-      if (jsniIdent == null || jsniIdent.length() == 0) {
-        data.typeName = className;
-        data.jsSymbolName = jsIdent;
-        oracle.seedNamesToClassData.put(jsIdent, data);
-        // Class.getName() with metadata disabled is "Class$S<seedId>"
-        oracle.seedIdsToClassData.put("S" + runtimeTypeId, data);
-        data.runtimeTypeId = runtimeTypeId;
-      } else {
-        if (jsniIdent.contains("(")) {
-          jsniIdent = jsniIdent.substring(jsniIdent.indexOf("::") + 2,
-              jsniIdent.indexOf(')') + 1);
-          data.methodJsniNamesToIdents.put(jsniIdent, jsIdent);
-        } else {
-          data.fieldIdentsToNames.put(jsIdent, memberName);
-          data.fieldNamesToIdents.put(memberName, jsIdent);
-        }
-      }
-    }
-
-    public WebModeClientOracle getOracle() {
-      WebModeClientOracle toReturn = oracle;
-      oracle = null;
-      return toReturn;
-    }
-
-    public void setSerializableFields(String className, List<String> fieldNames) {
-      ClassData data = oracle.getClassData(className);
-      assert data.serializableFields == null
-          || fieldNames.containsAll(data.serializableFields);
-      if (fieldNames.size() == 1) {
-        data.serializableFields = Collections.singletonList(fieldNames.get(0));
-      } else {
-        data.serializableFields = new ArrayList<String>(fieldNames);
-        Collections.sort(data.serializableFields);
-      }
-    }
-  }
-
-  /**
-   * A pair with extra data.
-   */
-  public static class Triple<A, B, C> extends Pair<A, B> {
-    private final C[] c;
-
-    public Triple(A a, B b, C... c) {
-      super(a, b);
-      this.c = c;
-    }
-
-    public C[] getC() {
-      return c;
-    }
-  }
-
-  private static class ClassData implements Serializable {
-    private static final long serialVersionUID = 6L;
-
-    public CastableTypeData castableTypeData;
-    public final Map<String, String> fieldIdentsToNames = new HashMap<String, String>();
-    public final Map<String, String> fieldNamesToIdents = new HashMap<String, String>();
-    public final Map<String, String> methodJsniNamesToIdents = new HashMap<String, String>();
-    public String runtimeTypeId;
-    public String jsSymbolName;
-    public List<String> serializableFields = Collections.emptyList();
-    public String typeName;
-  }
-
-  /**
-   * Defined to prevent simple changes from invalidating stored data.
-   *
-   * TODO: Use something other than Java serialization to store this type's
-   * data.
-   */
-  private static final long serialVersionUID = 3L;
-
-  /**
-   * Recreate a WebModeClientOracle based on the contents previously emitted by
-   * {@link #store}. The underlying format should be considered opaque.
-   */
-  public static WebModeClientOracle load(InputStream stream) throws IOException {
-    try {
-      stream = new GZIPInputStream(stream);
-      return readStreamAsObject(stream, WebModeClientOracle.class);
-    } catch (ClassNotFoundException e) {
-      throw new RuntimeException("Should never reach this", e);
-    }
-  }
-
-  static String jsniName(Class<?> clazz) {
-    if (clazz.isPrimitive()) {
-      if (clazz.equals(boolean.class)) {
-        return "Z";
-      } else if (clazz.equals(byte.class)) {
-        return "B";
-      } else if (clazz.equals(char.class)) {
-        return "C";
-      } else if (clazz.equals(short.class)) {
-        return "S";
-      } else if (clazz.equals(int.class)) {
-        return "I";
-      } else if (clazz.equals(long.class)) {
-        return "J";
-      } else if (clazz.equals(float.class)) {
-        return "F";
-      } else if (clazz.equals(double.class)) {
-        return "D";
-      }
-      throw new RuntimeException("Unhandled primitive type " + clazz.getName());
-    } else if (clazz.isArray()) {
-      return "[" + jsniName(clazz.getComponentType());
-    } else {
-      return "L" + clazz.getName().replace('.', '/') + ";";
-    }
-  }
-
-  /**
-   * Copied from dev.Utility class which is not part of servlet.jar.
-   */
-  private static <T> T readStreamAsObject(InputStream inputStream, Class<T> type)
-      throws ClassNotFoundException {
-    ObjectInputStream objectInputStream = null;
-    try {
-      objectInputStream = new ObjectInputStream(inputStream);
-      return type.cast(objectInputStream.readObject());
-    } catch (IOException e) {
-      return null;
-    } finally {
-      try {
-        objectInputStream.close();
-      } catch (IOException e) {
-        // Ignore
-      }
-    }
-  }
-
-  /**
-   * Serializes an object and writes it to a stream. Copied from Util to avoid
-   * dependecy on gwt-dev.
-   */
-  private static void writeObjectToStream(OutputStream stream,
-      Object... objects) throws IOException {
-    ObjectOutputStream objectStream = new ObjectOutputStream(stream);
-    for (Object object : objects) {
-      objectStream.writeObject(object);
-    }
-    objectStream.flush();
-  }
-
-  /**
-   * A map of class names to ClassData elements.
-   */
-  private final Map<String, ClassData> classData = new HashMap<String, ClassData>();
-
-  private final Set<String> idents = new HashSet<String>();
-
-  private final Map<String, ClassData> seedNamesToClassData = new HashMap<String, ClassData>();
-  private final Map<String, ClassData> seedIdsToClassData = new HashMap<String, ClassData>();
-
-  private transient Map<Class<?>, Field[]> operableFieldMap = new IdentityHashMap<Class<?>, Field[]>();
-
-  /**
-   * Instances of WebModeClientOracle are created either through the
-   * {@link Builder} class or via the {@link #load} method.
-   */
-  protected WebModeClientOracle() {
-  }
-
-  @Override
-  public CommandSink createCommandSink(OutputStream out) throws IOException {
-    return new WebModePayloadSink(this, out);
-  }
-
-  @Override
-  public String createUnusedIdent(String ident) {
-    while (idents.contains(ident)) {
-      ident += "$";
-    }
-    return ident;
-  }
-
-  @Override
-  public CastableTypeData getCastableTypeData(Class<?> clazz) {
-    while (clazz != null) {
-      CastableTypeData toReturn = getCastableTypeData(canonicalName(clazz));
-      if (toReturn != null) {
-        return toReturn;
-      }
-      clazz = clazz.getSuperclass();
-    }
-    return null;
-  }
-
-  @Override
-  public String getFieldId(Class<?> clazz, String fieldName) {
-    while (clazz != null) {
-      String className = clazz.getName();
-      ClassData data = getClassData(className);
-      if (data.fieldNamesToIdents.containsKey(fieldName)) {
-        return data.fieldNamesToIdents.get(fieldName);
-      }
-      clazz = clazz.getSuperclass();
-    }
-    return null;
-  }
-
-  @Override
-  public String getFieldId(Enum<?> value) {
-    return getFieldId(value.getDeclaringClass(), value.name());
-  }
-
-  @Override
-  public String getFieldId(String className, String fieldName) {
-    ClassData data = getClassData(className);
-    return data.fieldNamesToIdents.get(fieldName);
-  }
-
-  @Override
-  public Pair<Class<?>, String> getFieldName(Class<?> clazz, String fieldId) {
-    while (clazz != null) {
-      ClassData data = getClassData(clazz.getName());
-      String fieldName = data.fieldIdentsToNames.get(fieldId);
-      if (fieldName == null) {
-        clazz = clazz.getSuperclass();
-      } else {
-        return new Pair<Class<?>, String>(clazz, fieldName);
-      }
-    }
-    return null;
-  }
-
-  /**
-   * This will search superclasses.
-   */
-  @Override
-  public String getMethodId(Class<?> clazz, String methodName, Class<?>... args) {
-    while (clazz != null) {
-      String toReturn = getMethodId(clazz.getName(), methodName, args);
-      if (toReturn != null) {
-        return toReturn;
-      }
-      clazz = clazz.getSuperclass();
-    }
-    return null;
-  }
-
-  @Override
-  public String getMethodId(String className, String methodName,
-      String... jsniArgTypes) {
-    StringBuilder sb = new StringBuilder();
-    sb.append(methodName);
-    sb.append("(");
-    for (String jsniArg : jsniArgTypes) {
-      sb.append(jsniArg);
-    }
-    sb.append(")");
-
-    ClassData data = getClassData(className);
-    String jsIdent = data.methodJsniNamesToIdents.get(sb.toString());
-    return jsIdent;
-  }
-
-  @Override
-  public Field[] getOperableFields(Class<?> clazz) {
-    Field[] toReturn;
-    synchronized (operableFieldMap) {
-      toReturn = operableFieldMap.get(clazz);
-    }
-    if (toReturn != null) {
-      return toReturn;
-    }
-
-    ClassData data = getClassData(clazz.getName());
-    toReturn = new Field[data.serializableFields.size()];
-    for (int i = 0; i < toReturn.length; i++) {
-      String fieldName = data.serializableFields.get(i);
-      try {
-        toReturn[i] = clazz.getDeclaredField(fieldName);
-      } catch (SecurityException e) {
-        throw new IncompatibleRemoteServiceException("Cannot access field "
-            + fieldName, e);
-      } catch (NoSuchFieldException e) {
-        throw new IncompatibleRemoteServiceException("No field " + fieldName, e);
-      }
-    }
-
-    synchronized (operableFieldMap) {
-      operableFieldMap.put(clazz, toReturn);
-    }
-    return toReturn;
-  }
-
-  @Override
-  public String getRuntimeTypeId(Class<?> clazz) {
-    while (clazz != null) {
-      String toReturn = getRuntimeTypeId(canonicalName(clazz));
-      if (toReturn != null) {
-        return toReturn;
-      }
-      clazz = clazz.getSuperclass();
-    }
-    return null;
-  }
-
-  @Override
-  public String getJsSymbolName(Class<?> clazz) {
-    ClassData data = getClassData(clazz.getName());
-    return data.jsSymbolName;
-  }
-
-  @Override
-  public String getTypeName(String seedName) {
-    // TODO: Decide how to handle the no-metadata case
-    ClassData data = null;
-    if (seedName.startsWith("Class$")) {
-      seedName = seedName.substring(6);
-      data = seedIdsToClassData.get(seedName);
-    }
-
-    if (data == null) {
-      data = seedNamesToClassData.get(seedName);
-    }
-    return data == null ? null : data.typeName;
-  }
-
-  @Override
-  public boolean isScript() {
-    return true;
-  }
-
-  /**
-   * Write the state of the WebModeClientOracle into an OutputStream. The
-   * underlying format should be considered opaque.
-   */
-  public void store(OutputStream stream) throws IOException {
-    stream = new GZIPOutputStream(stream);
-    writeObjectToStream(stream, this);
-    stream.close();
-  }
-
-  private String canonicalName(Class<?> clazz) {
-    if (clazz.isArray()) {
-      Class<?> leafType = clazz;
-      do {
-        leafType = leafType.getComponentType();
-      } while (leafType.isArray());
-
-      Class<?> enclosing = leafType.getEnclosingClass();
-      if (enclosing != null) {
-        // com.foo.Enclosing$Name[]
-        return canonicalName(enclosing) + "$" + clazz.getSimpleName();
-      } else if (leafType.getPackage() == null) {
-        // Name0[
-        return clazz.getSimpleName();
-      } else {
-        // com.foo.Name[]
-        return leafType.getPackage().getName() + "." + clazz.getSimpleName();
-      }
-    } else {
-      return clazz.getName();
-    }
-  }
-
-  private CastableTypeData getCastableTypeData(String className) {
-    ClassData data = getClassData(className);
-    return data.castableTypeData;
-  }
-
-  private ClassData getClassData(String className) {
-    ClassData toReturn = classData.get(className);
-    if (toReturn == null) {
-      toReturn = new ClassData();
-      classData.put(className, toReturn);
-    }
-    return toReturn;
-  }
-
-  /**
-   * This will not search superclasses and is used to access magic GWT types
-   * like Array.
-   */
-  private String getMethodId(String className, String methodName,
-      Class<?>... args) {
-    String[] jsniArgTypes = new String[args.length];
-    for (int i = 0, j = args.length; i < j; i++) {
-      jsniArgTypes[i] = jsniName(args[i]);
-    }
-    return getMethodId(className, methodName, jsniArgTypes);
-  }
-
-  private String getRuntimeTypeId(String className) {
-    ClassData data = getClassData(className);
-    return data.runtimeTypeId;
-  }
-
-  /**
-   * Reinitialize the <code>operableFieldMap</code> field when the
-   * WebModeClientOracle is reloaded.
-   */
-  private Object readResolve() {
-    operableFieldMap = new HashMap<Class<?>, Field[]>();
-    return this;
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/WebModePayloadSink.java b/user/src/com/google/gwt/rpc/server/WebModePayloadSink.java
deleted file mode 100644
index 2080855..0000000
--- a/user/src/com/google/gwt/rpc/server/WebModePayloadSink.java
+++ /dev/null
@@ -1,956 +0,0 @@
-/*
- * Copyright 2009 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.rpc.server;
-
-import static com.google.gwt.rpc.client.impl.CommandClientSerializationStreamReader.BACKREF_IDENT;
-
-import com.google.gwt.rpc.client.ast.ArrayValueCommand;
-import com.google.gwt.rpc.client.ast.BooleanValueCommand;
-import com.google.gwt.rpc.client.ast.ByteValueCommand;
-import com.google.gwt.rpc.client.ast.CharValueCommand;
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.rpc.client.ast.DoubleValueCommand;
-import com.google.gwt.rpc.client.ast.EnumValueCommand;
-import com.google.gwt.rpc.client.ast.FloatValueCommand;
-import com.google.gwt.rpc.client.ast.InstantiateCommand;
-import com.google.gwt.rpc.client.ast.IntValueCommand;
-import com.google.gwt.rpc.client.ast.InvokeCustomFieldSerializerCommand;
-import com.google.gwt.rpc.client.ast.LongValueCommand;
-import com.google.gwt.rpc.client.ast.NullValueCommand;
-import com.google.gwt.rpc.client.ast.ReturnCommand;
-import com.google.gwt.rpc.client.ast.RpcCommand;
-import com.google.gwt.rpc.client.ast.RpcCommandVisitor;
-import com.google.gwt.rpc.client.ast.SetCommand;
-import com.google.gwt.rpc.client.ast.ShortValueCommand;
-import com.google.gwt.rpc.client.ast.StringValueCommand;
-import com.google.gwt.rpc.client.ast.ThrowCommand;
-import com.google.gwt.rpc.client.ast.ValueCommand;
-import com.google.gwt.rpc.client.impl.CommandClientSerializationStreamReader;
-import com.google.gwt.rpc.client.impl.EscapeUtil;
-import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Array;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.logging.Logger;
-
-/**
- * A CommandSink that will generate a web-mode payload.
- *
- * ONE-SHOT EVAL (no incremental evaluation, must call finish())
- */
-public class WebModePayloadSink extends CommandSink {
-
-  private class BackRefAssigner extends RpcCommandVisitor {
-    private final Set<ValueCommand> seenOnce = new HashSet<ValueCommand>();
-
-    @Override
-    public void endVisit(InvokeCustomFieldSerializerCommand x, Context ctx) {
-      // We always need a backref for custom serializers
-      makeBackRef(x);
-    }
-
-    @Override
-    public void endVisit(LongValueCommand x, Context ctx) {
-      process(x);
-    }
-
-    @Override
-    public void endVisit(StringValueCommand x, Context ctx) {
-      process(x);
-    }
-
-    @Override
-    public boolean visit(ArrayValueCommand x, Context ctx) {
-      return process(x);
-    }
-
-    @Override
-    public boolean visit(InstantiateCommand x, Context ctx) {
-      return process(x);
-    }
-
-    private boolean process(ValueCommand x) {
-      if (!seenOnce.add(x)) {
-        makeBackRef(x);
-        return false;
-      }
-      return true;
-    }
-  }
-  private class PayloadVisitor extends RpcCommandVisitor {
-    private final Map<Class<?>, byte[]> constructorFunctions = new IdentityHashMap<Class<?>, byte[]>();
-    private final Map<RpcCommand, ByteBuffer> commandBuffers = new IdentityHashMap<RpcCommand, ByteBuffer>();
-    private ByteBuffer currentBuffer;
-    private final Stack<RpcCommand> stack = new Stack<RpcCommand>();
-    private final Set<RpcCommand> started = new HashSet<RpcCommand>();
-
-    @Override
-    public void endVisit(BooleanValueCommand x, Context ctx) {
-      if (x.getValue()) {
-        one();
-      } else {
-        zero();
-      }
-    }
-
-    @Override
-    public void endVisit(ByteValueCommand x, Context ctx) {
-      push(String.valueOf(x.getValue()));
-    }
-
-    @Override
-    public void endVisit(CharValueCommand x, Context ctx) {
-      push(String.valueOf((int) x.getValue()));
-    }
-
-    @Override
-    public void endVisit(DoubleValueCommand x, Context ctx) {
-      push(String.valueOf(x.getValue()));
-    }
-
-    @Override
-    public void endVisit(EnumValueCommand x, Context ctx) {
-      String fieldName = clientOracle.getFieldId(x.getValue());
-      if (fieldName == null) {
-        throw new IncompatibleRemoteServiceException(
-            "The client cannot accept " + x.getValue().name());
-      }
-      String clinitName = clientOracle.getMethodId(
-          x.getValue().getDeclaringClass(), "$clinit");
-      assert clinitName != null;
-
-      // (clinit(), A)
-      lparen();
-      push(clinitName);
-      lparen();
-      rparen();
-      comma();
-      push(fieldName);
-      rparen();
-    }
-
-    @Override
-    public void endVisit(FloatValueCommand x, Context ctx) {
-      push(String.valueOf((double) x.getValue()));
-    }
-
-    @Override
-    public void endVisit(IntValueCommand x, Context ctx) {
-      push(String.valueOf(x.getValue()));
-    }
-
-    @Override
-    public void endVisit(LongValueCommand x, Context ctx) {
-      // TODO (rice): use backwards-compatible wire format?
-      long fieldValue = x.getValue();
-
-      /*
-       * Client code represents longs internally as an Object with numeric
-       * properties l, m, and h. In order to make serialization of longs faster,
-       * we'll send the component parts so that the value can be directly
-       * reconstituted on the client.
-       */
-      int l = (int) (fieldValue & 0x3fffff);
-      int m = (int) ((fieldValue >> 22) & 0x3fffff);
-      int h = (int) ((fieldValue >> 44) & 0xfffff);
-      // CHECKSTYLE_OFF
-      push("{l:" + l + ",m:" + m + ",h:" + h + "}");
-      // CHECKSTYLE_ON
-    }
-
-    @Override
-    public void endVisit(NullValueCommand x, Context ctx) {
-      _null();
-    }
-
-    @Override
-    public void endVisit(ShortValueCommand x, Context ctx) {
-      push(String.valueOf(x.getValue()));
-    }
-
-    @Override
-    public void endVisit(StringValueCommand x, Context ctx) {
-      if (hasBackRef(x)) {
-        if (!isStarted(x)) {
-          String escaped = EscapeUtil.escape(x.getValue());
-          push(begin(x));
-          eq();
-          quote();
-          push(escaped);
-          quote();
-          commit(x, false);
-        } else {
-          push(makeBackRef(x));
-        }
-      } else {
-        String escaped = EscapeUtil.escape(x.getValue());
-        quote();
-        push(escaped);
-        quote();
-      }
-    }
-
-    @Override
-    public boolean visit(ArrayValueCommand x, Context ctx) {
-      boolean hasBackRef = hasBackRef(x);
-      if (hasBackRef && isStarted(x)) {
-        push(makeBackRef(x));
-        return false;
-      }
-
-      // constructorFunction(x = [value,value,value])
-      byte[] currentBackRef = begin(x);
-      push(constructorFunction(x));
-      lparen();
-      if (hasBackRef) {
-        push(currentBackRef);
-        eq();
-      }
-      lbracket();
-      for (Iterator<ValueCommand> it = x.getComponentValues().iterator(); it.hasNext();) {
-        accept(it.next());
-        if (it.hasNext()) {
-          comma();
-        }
-      }
-      rbracket();
-      rparen();
-      commit(x, false);
-      if (!hasBackRef) {
-        forget(x);
-      }
-      return false;
-    }
-
-    @Override
-    public boolean visit(InstantiateCommand x, Context ctx) {
-      boolean hasBackRef = hasBackRef(x);
-      if (hasBackRef && isStarted(x)) {
-        push(makeBackRef(x));
-        return false;
-      }
-
-      byte[] currentBackRef = begin(x);
-      byte[] constructorFunction = constructorFunction(x);
-
-      String getSeedFunc = clientOracle.getMethodId("java.lang.Class",
-          "getSeedFunction", "Ljava/lang/Class;");
-      String classLitId = clientOracle.getFieldId(
-               "com.google.gwt.lang.ClassLiteralHolder",
-               getJavahSignatureName(x.getTargetClass()) + "_classLit");
-           assert classLitId != null : "No class literal for "
-               + x.getTargetClass().getName();
-
-      /*
-       * If we need to maintain a backreference to the object, it's established
-       * in the first argument instead of using the return value of the
-       * constructorFunction. This is done in case one of the fields should
-       * require a reference to the object that is currently being constructed.
-       */
-      // constructorFunctionFoo(x = new (classLit.getSeedFunction()), field1, field2)
-      push(constructorFunction);
-      lparen();
-      if (hasBackRef) {
-        push(currentBackRef);
-        eq();
-      }
-      _new();
-      lparen();
-      push(getSeedFunc);
-      lparen();
-      push(classLitId);
-      rparen();
-      rparen();
-      for (SetCommand setter : x.getSetters()) {
-        comma();
-        accept(setter.getValue());
-      }
-      rparen();
-
-      commit(x, false);
-      if (!hasBackRef) {
-        forget(x);
-      }
-      return false;
-    }
-
-    @Override
-    public boolean visit(InvokeCustomFieldSerializerCommand x, Context ctx) {
-      if (isStarted(x)) {
-        push(makeBackRef(x));
-        return false;
-      }
-
-      // ( backref = instantiate(), deserialize(), setter, ..., backref )
-      byte[] currentBackRef = begin(x);
-
-      lparen();
-
-      InstantiateCommand makeReader = new InstantiateCommand(
-          CommandClientSerializationStreamReader.class);
-      /*
-       * Ensure that the reader will stick around for both instantiate and
-       * deserialize calls.
-       */
-      makeBackRef(makeReader);
-
-      ArrayValueCommand payload = new ArrayValueCommand(Object.class);
-      for (ValueCommand value : x.getValues()) {
-        payload.add(value);
-      }
-      makeReader.set(CommandClientSerializationStreamReader.class, "payload",
-          payload);
-
-      String instantiateIdent = clientOracle.getMethodId(
-          x.getSerializerClass(), "instantiate",
-          SerializationStreamReader.class);
-
-      // x = new Foo,
-      // x = instantiate(reader),
-      push(currentBackRef);
-      eq();
-      if (instantiateIdent == null) {
-        // No instantiate method, we'll have to invoke the constructor
-
-        // new Foo()
-        String constructorMethodName;
-        if (x.getTargetClass().getEnclosingClass() == null) {
-          constructorMethodName = x.getTargetClass().getSimpleName();
-        } else {
-          String name = x.getTargetClass().getName();
-          constructorMethodName = name.substring(name.lastIndexOf('.') + 1);
-        }
-
-        String constructorIdent = clientOracle.getMethodId(x.getTargetClass(),
-            constructorMethodName);
-        assert constructorIdent != null : "constructorIdent "
-            + constructorMethodName;
-
-        // new constructor,
-        _new();
-        push(constructorIdent);
-        comma();
-      } else {
-        // instantiate(reader),
-        push(instantiateIdent);
-        lparen();
-        accept(makeReader);
-        rparen();
-        comma();
-      }
-
-      // Call the deserialize method if it exists
-      String deserializeIdent = clientOracle.getMethodId(
-          x.getSerializerClass(), "deserialize",
-          SerializationStreamReader.class, x.getManuallySerializedType());
-      if (deserializeIdent != null) {
-        // deserialize(reader, obj),
-        push(deserializeIdent);
-        lparen();
-        accept(makeReader);
-        comma();
-        push(currentBackRef);
-        rparen();
-        comma();
-      }
-
-      // If there are extra fields, set them
-      for (SetCommand setter : x.getSetters()) {
-        accept(setter);
-        comma();
-      }
-
-      push(currentBackRef);
-      rparen();
-      commit(x, false);
-      forget(makeReader);
-
-      return false;
-    }
-
-    @Override
-    public boolean visit(ReturnCommand x, Context ctx) {
-      int size = x.getValues().size();
-
-      begin(x);
-      _return();
-
-      // return [a,b,c];
-      lbracket();
-      for (int i = 0; i < size; i++) {
-        accept(x.getValues().get(i));
-        if (i < size - 1) {
-          comma();
-        }
-      }
-      rbracket();
-
-      semi();
-      commit(x);
-
-      return false;
-    }
-
-    @Override
-    public boolean visit(SetCommand x, Context ctx) {
-      String fieldName = clientOracle.getFieldId(x.getFieldDeclClass(),
-          x.getField());
-
-      if (fieldName == null) {
-        // TODO: What does it mean if the client doesn't have a field?
-        throw new IncompatibleRemoteServiceException(
-            "The client does not have field " + x.getField() + " in type "
-                + x.getFieldDeclClass().getName());
-      }
-
-      // i[3].foo = bar
-      push(makeBackRef((ValueCommand) stack.peek()));
-      dot();
-      push(fieldName);
-      eq();
-      accept(x.getValue());
-
-      return false;
-    }
-
-    /**
-     * In order to improve robustness of the payload, we perform the throw from
-     * within a function.
-     */
-    @Override
-    public boolean visit(ThrowCommand x, Context ctx) {
-      // throw foo;
-      begin(x);
-      _throw();
-
-      assert x.getValues().size() == 1;
-      accept(x.getValues());
-
-      semi();
-      commit(x);
-
-      return false;
-    }
-
-    // CHECKSTYLE_OFF
-
-    private void _new() {
-      push(NEW_BYTES);
-    }
-
-    private void _null() {
-      push(NULL_BYTES);
-    }
-
-    private void _return() {
-      push(RETURN_BYTES);
-    }
-
-    private void _throw() {
-      push(THROW_BYTES);
-    }
-
-    // CHECKSTYLE_ON
-
-    private void begin(RpcCommand x) {
-      assert !commandBuffers.containsKey(x) : "ValueCommand already active";
-
-      started.add(x);
-      stack.push(x);
-      currentBuffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
-      commandBuffers.put(x, currentBuffer);
-    }
-
-    private byte[] begin(ValueCommand x) {
-      begin((RpcCommand) x);
-      return makeBackRef(x);
-    }
-
-    private void comma() {
-      push(COMMA_BYTES);
-      spaceOpt();
-    }
-
-    private void commit(RpcCommand x) {
-      commit(x, true);
-    }
-
-    private void commit(RpcCommand x, boolean send) {
-      if (stack.pop() != x) {
-        throw new IllegalStateException("Did not pop expected command");
-      }
-
-      // Don't need to retain any internal data
-      x.clear();
-
-      ByteBuffer sb = commandBuffers.remove(x);
-      assert sb != null : "No ByteBuffer for " + x;
-
-      if (!stack.isEmpty()) {
-        currentBuffer = commandBuffers.get(stack.peek());
-        assert currentBuffer != null : "Could not restore currentBuilder";
-      } else {
-        currentBuffer = null;
-      }
-
-      sb.limit(sb.position()).rewind();
-
-      if (send) {
-        try {
-          send(sb);
-        } catch (SerializationException e) {
-          halt(e);
-        }
-      } else {
-        push(sb);
-      }
-    }
-
-    private byte[] constructorFunction(ArrayValueCommand x) {
-      Class<?> targetClass = Array.newInstance(x.getComponentType(), 0).getClass();
-      byte[] functionName = constructorFunctions.get(targetClass);
-      if (functionName != null) {
-        return functionName;
-      }
-
-      String initValuesId = clientOracle.getMethodId(
-          "com.google.gwt.lang.Array", "initValues", "Ljava/lang/Class;",
-          "Lcom/google/gwt/core/client/JavaScriptObject;", "I",
-          "Lcom/google/gwt/lang/Array;");
-      assert initValuesId != null : "Could not find initValues";
-
-      String classLitId = clientOracle.getFieldId(
-          "com.google.gwt.lang.ClassLiteralHolder",
-          getJavahSignatureName(x.getComponentType()) + "_classLit");
-      assert classLitId != null : "No class literal for "
-          + x.getComponentType().getName();
-
-      functionName = getBytes(clientOracle.createUnusedIdent(classLitId));
-      constructorFunctions.put(targetClass, functionName);
-
-      /*
-       * Set the castableTypeData and queryIds to exact values,
-       * or fall back to acting like a plain Object[] array.
-       */
-      CastableTypeData castableTypeData = clientOracle.getCastableTypeData(targetClass);
-      if (castableTypeData == null) {
-        castableTypeData = clientOracle.getCastableTypeData(Object[].class);
-      }
-
-      String runtimeTypeId = clientOracle.getRuntimeTypeId(x.getComponentType());
-      if (runtimeTypeId == null) {
-        runtimeTypeId = clientOracle.getRuntimeTypeId(Object.class);
-      }
-
-      byte[] ident = getBytes("_0");
-
-      // function foo(_0) {return initValues(classLit, castableTypeData, runtimeTypeId, _0)}
-      function();
-      push(functionName);
-      lparen();
-      push(ident);
-      rparen();
-      lbrace();
-      _return();
-      push(initValuesId);
-      lparen();
-      push(classLitId);
-      comma();
-      push(castableTypeData.toJs());
-      comma();
-      push(String.valueOf(runtimeTypeId));
-      comma();
-      push(ident);
-      rparen();
-      rbrace();
-
-      flush(x);
-
-      return functionName;
-    }
-
-    private byte[] constructorFunction(InstantiateCommand x) {
-      Class<?> targetClass = x.getTargetClass();
-      byte[] functionName = constructorFunctions.get(targetClass);
-      if (functionName != null) {
-        return functionName;
-      }
-
-      String seedName = clientOracle.getJsSymbolName(targetClass);
-      assert seedName != null : "TypeOverride failed to rescue "
-          + targetClass.getName();
-      functionName = getBytes(clientOracle.createUnusedIdent(seedName));
-      constructorFunctions.put(targetClass, functionName);
-      byte[][] idents = new byte[x.getSetters().size() + 1][];
-      for (int i = 0, j = idents.length; i < j; i++) {
-        idents[i] = getBytes("_" + i);
-      }
-
-      // function foo(_0, _1, _2) {_0.a = _1; _0.b=_2; return _0}
-      function();
-      push(functionName);
-      lparen();
-      for (int i = 0, j = idents.length; i < j; i++) {
-        push(idents[i]);
-        if (i < j - 1) {
-          comma();
-        }
-      }
-      rparen();
-      lbrace();
-      newlineOpt();
-      for (int i = 1, j = idents.length; i < j; i++) {
-        SetCommand setter = x.getSetters().get(i - 1);
-        String fieldIdent = clientOracle.getFieldId(setter.getFieldDeclClass(),
-            setter.getField());
-
-        if (fieldIdent != null) {
-          // _0.foo = bar;
-          spaceOpt();
-          push(idents[0]);
-          dot();
-          push(fieldIdent);
-          eq();
-          push(idents[i]);
-          semi();
-        } else {
-          String fieldName = setter.getFieldDeclClass().getName()
-              + "." + setter.getField();
-          if (!skippedFields.contains(fieldName)) {
-            skippedFields.add(fieldName);
-            log.warning("Skipped sending the field " + fieldName + " because "
-                + "it's unused in the client. It should either be changed to "
-                + "transient or removed.");
-          }
-        }
-      }
-      spaceOpt();
-      _return();
-      push(idents[0]);
-      rbrace();
-      newlineOpt();
-
-      flush(x);
-
-      return functionName;
-    }
-
-    private void dot() {
-      push(DOT_BYTES);
-    }
-
-    private void eq() {
-      spaceOpt();
-      push(EQ_BYTES);
-      spaceOpt();
-    }
-
-    /**
-     * Cause an immediate write of accumulated output for a command. This is
-     * used primarily for writing object allocations
-     */
-    private void flush(RpcCommand x) {
-      ByteBuffer sb = commandBuffers.get(x);
-      if (sb == null || sb.position() == 0) {
-        return;
-      }
-
-      sb.limit(sb.position()).rewind();
-      try {
-        send(sb);
-      } catch (SerializationException e) {
-        halt(e);
-      }
-      sb.clear();
-    }
-
-    private void function() {
-      newlineOpt();
-      push(FUNCTION_BYTES);
-    }
-
-    /**
-     * Keep in sync with JReferenceType implementations.
-     */
-    private String getJavahSignatureName(Class<?> clazz) {
-      if (clazz.isArray()) {
-        Class<?> leafType = clazz;
-        int dims = 0;
-        do {
-          dims++;
-          leafType = leafType.getComponentType();
-        } while (leafType.getComponentType() != null);
-        assert dims > 0;
-        // leafType cannot be null here
-
-        String s = getJavahSignatureName(leafType);
-        for (int i = 0; i < dims; ++i) {
-          s = "_3" + s;
-        }
-        return s;
-      } else if (clazz.isPrimitive()) {
-        return WebModeClientOracle.jsniName(clazz);
-      } else {
-        String name = clazz.getName();
-        return "L" + name.replaceAll("_", "_1").replace('.', '_') + "_2";
-      }
-    }
-
-    private boolean isStarted(RpcCommand x) {
-      return started.contains(x);
-    }
-
-    private void lbrace() {
-      push(LBRACE_BYTES);
-    }
-
-    private void lbracket() {
-      push(LBRACKET_BYTES);
-    }
-
-    private void lparen() {
-      push(LPAREN_BYTES);
-    }
-
-    private void newlineOpt() {
-      pushOpt(NEWLINE_BYTES);
-    }
-
-    private void one() {
-      push(ONE_BYTES);
-    }
-
-    /**
-     * Add data to the current command's serialization output.
-     */
-    private void push(byte[] bytes) {
-      assert currentBuffer != null : "Must call begin(RpcCommand) first";
-      try {
-        currentBuffer.put(bytes);
-      } catch (BufferOverflowException e) {
-        reallocateCurrentBuffer(bytes.length);
-        currentBuffer.put(bytes);
-      }
-    }
-
-    /**
-     * Add data to the current command's serialization output.
-     */
-    private void push(ByteBuffer buffer) {
-      assert currentBuffer != null : "Must call begin(RpcCommand) first";
-      try {
-        currentBuffer.put(buffer);
-      } catch (BufferOverflowException e) {
-        reallocateCurrentBuffer(buffer.remaining());
-        currentBuffer.put(buffer);
-      }
-    }
-
-    /**
-     * Add data to the current command's serialization output.
-     */
-    private void push(String s) {
-      push(getBytes(s));
-    }
-
-    /**
-     * Optionally add data to the current command's serialization output.
-     */
-    private void pushOpt(byte[] x) {
-      if (PRETTY) {
-        push(x);
-      }
-    }
-
-    private void quote() {
-      push(QUOTE_BYTES);
-    }
-
-    private void rbrace() {
-      push(RBRACE_BYTES);
-    }
-
-    private void rbracket() {
-      push(RBRACKET_BYTES);
-    }
-
-    private void reallocateCurrentBuffer(int bytesNeeded) {
-      // Allocate a new buffer of sufficient size
-      int newSize = currentBuffer.capacity()
-          + Math.max(2 * bytesNeeded, currentBuffer.capacity());
-      ByteBuffer newBuffer = ByteBuffer.allocate(newSize);
-
-      // Copy the old buffer over
-      currentBuffer.limit(currentBuffer.position()).rewind();
-      newBuffer.put(currentBuffer);
-
-      // Reassign the current buffer
-      assert commandBuffers.get(stack.peek()) == currentBuffer;
-      commandBuffers.put(stack.peek(), newBuffer);
-      currentBuffer = newBuffer;
-    }
-
-    private void rparen() {
-      push(RPAREN_BYTES);
-    }
-
-    private void semi() {
-      push(SEMI_BYTES);
-      newlineOpt();
-    }
-
-    private void spaceOpt() {
-      pushOpt(SPACE_BYTES);
-    }
-
-    private void zero() {
-      push(ZERO_BYTES);
-    }
-  }
-
-  private static final Logger log = Logger.getLogger(WebModePayloadSink.class.getName());
-  private static final Set<String> skippedFields = new HashSet<String>();
-
-  /*
-   * Instead of converting these commonly-used strings to bytes every time we
-   * want to write them to the output, we'll simply create a fixed pool.
-   */
-  static final byte[] COMMA_BYTES = getBytes(",");
-  static final byte[] DOT_BYTES = getBytes(".");
-  static final byte[] EQ_BYTES = getBytes("=");
-  static final byte[] FUNCTION_BYTES = getBytes("function ");
-  static final byte[] LBRACE_BYTES = getBytes("{");
-  static final byte[] LBRACKET_BYTES = getBytes("[");
-  static final byte[] LPAREN_BYTES = getBytes("(");
-  static final byte[] NEW_BYTES = getBytes("new ");
-  static final byte[] NEWLINE_BYTES = getBytes("\n");
-  static final byte[] NULL_BYTES = getBytes("null");
-  static final byte[] ONE_BYTES = getBytes("1");
-  static final byte[] QUOTE_BYTES = getBytes("\"");
-  static final byte[] RBRACE_BYTES = getBytes("}");
-  static final byte[] RBRACKET_BYTES = getBytes("]");
-  static final byte[] RETURN_BYTES = getBytes("return ");
-  static final byte[] RPAREN_BYTES = getBytes(")");
-  static final byte[] SPACE_BYTES = getBytes(" ");
-  static final byte[] SEMI_BYTES = getBytes(";");
-  static final byte[] THROW_BYTES = getBytes("throw ");
-  static final byte[] ZERO_BYTES = getBytes("0");
-
-  /**
-   * A runtime flag to indicate that the generated output should be made to be
-   * human-readable.
-   */
-  static final boolean PRETTY = Boolean.getBoolean("gwt.rpc.pretty");
-
-  private static final int DEFAULT_BUFFER_SIZE = 256;
-
-  static byte[] getBytes(String x) {
-    try {
-      return x.getBytes("UTF-8");
-    } catch (UnsupportedEncodingException e) {
-      throw new RuntimeException("UTF-8 is unsupported", e);
-    }
-  }
-
-  private final ClientOracle clientOracle;
-  private boolean finished = false;
-  private final OutputStream out;
-  private final Map<ValueCommand, byte[]> valueBackRefs = new HashMap<ValueCommand, byte[]>();
-  private final PayloadVisitor visitor = new PayloadVisitor();
-
-  private Stack<byte[]> freeBackRefs = new Stack<byte[]>();
-
-  public WebModePayloadSink(ClientOracle clientOracle, OutputStream out) {
-    this.clientOracle = clientOracle;
-    this.out = out;
-  }
-
-  @Override
-  public void accept(RpcCommand command) throws SerializationException {
-    if (finished) {
-      throw new IllegalStateException("finish() has already been called");
-    }
-
-    new BackRefAssigner().accept(command);
-
-    if (command instanceof ValueCommand) {
-      makeBackRef((ValueCommand) command);
-    }
-    visitor.accept(command);
-  }
-
-  /**
-   * The caller must close the stream.
-   */
-  @Override
-  public void finish() throws SerializationException {
-    finished = true;
-  }
-
-  void forget(ValueCommand x) {
-    assert valueBackRefs.containsKey(x);
-    freeBackRefs.push(valueBackRefs.remove(x));
-  }
-
-  boolean hasBackRef(ValueCommand x) {
-    return valueBackRefs.containsKey(x);
-  }
-
-  byte[] makeBackRef(ValueCommand x) {
-    byte[] toReturn = valueBackRefs.get(x);
-    if (toReturn == null) {
-      if (freeBackRefs.isEmpty()) {
-        int idx = valueBackRefs.size();
-        toReturn = getBytes(BACKREF_IDENT + "._"
-            + Integer.toString(idx, Character.MAX_RADIX));
-      } else {
-        toReturn = freeBackRefs.pop();
-      }
-      valueBackRefs.put(x, toReturn);
-    }
-    return toReturn;
-  }
-
-  void send(ByteBuffer x) throws SerializationException {
-    try {
-      assert x.hasArray();
-      out.write(x.array(), x.position(), x.limit());
-    } catch (IOException e) {
-      throw new SerializationException("Could not send data", e);
-    }
-  }
-
-  void send(String x) throws SerializationException {
-    try {
-      out.write(getBytes(x));
-    } catch (IOException e) {
-      throw new SerializationException("Could not send data", e);
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/rpc/server/package-info.java b/user/src/com/google/gwt/rpc/server/package-info.java
deleted file mode 100644
index fee6f54..0000000
--- a/user/src/com/google/gwt/rpc/server/package-info.java
+++ /dev/null
@@ -1,21 +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.
- */
-
-/**
- * Contains the server-side APIs for deRPC.
- */
-@com.google.gwt.util.PreventSpuriousRebuilds
-package com.google.gwt.rpc.server;
diff --git a/user/src/com/google/gwt/user/server/rpc/HybridServiceServlet.java b/user/src/com/google/gwt/user/server/rpc/HybridServiceServlet.java
deleted file mode 100644
index 16fbe7a..0000000
--- a/user/src/com/google/gwt/user/server/rpc/HybridServiceServlet.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright 2009 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.user.server.rpc;
-
-import com.google.gwt.rpc.server.ClientOracle;
-import com.google.gwt.rpc.server.RpcServlet;
-import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
-import com.google.gwt.user.client.rpc.RpcTokenException;
-import com.google.gwt.user.client.rpc.SerializationException;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * EXPERIMENTAL and subject to change. Do not use this in production code.
- * <p>
- * This RemoteServiceServlet provides support for both legacy and deRPC clients
- * at the cost of additional runtime overhead and API complexity.
- */
-public class HybridServiceServlet extends RpcServlet implements
-    SerializationPolicyProvider {
-
-  /**
-   * Records permutations for which {@link #getClientOracle()} should return
-   * <code>null</code>.
-   */
-  private final Set<String> legacyPermutations = new HashSet<String>();
-
-  /**
-   * A cache of moduleBaseURL and serialization policy strong name to
-   * {@link SerializationPolicy}.
-   */
-  private final Map<String, SerializationPolicy> serializationPolicyCache = new HashMap<String, SerializationPolicy>();
-
-  /**
-   * This method will return <code>null</code> instead of throwing an exception.
-   */
-  @Override
-  public ClientOracle getClientOracle() {
-    String strongName = getPermutationStrongName();
-    if (legacyPermutations.contains(strongName)) {
-      return null;
-    }
-    try {
-      return super.getClientOracle();
-    } catch (SerializationException e) {
-      legacyPermutations.add(strongName);
-      return null;
-    }
-  }
-
-  public final SerializationPolicy getSerializationPolicy(String moduleBaseURL,
-      String strongName) {
-
-    SerializationPolicy serializationPolicy = getCachedSerializationPolicy(
-        moduleBaseURL, strongName);
-    if (serializationPolicy != null) {
-      return serializationPolicy;
-    }
-
-    serializationPolicy = doGetSerializationPolicy(getThreadLocalRequest(),
-        moduleBaseURL, strongName);
-
-    if (serializationPolicy == null) {
-      // Failed to get the requested serialization policy; use the default
-      log(
-          "WARNING: Failed to get the SerializationPolicy '"
-              + strongName
-              + "' for module '"
-              + moduleBaseURL
-              + "'; a legacy, 1.3.3 compatible, serialization policy will be used.  You may experience SerializationExceptions as a result.");
-      serializationPolicy = RPC.getDefaultSerializationPolicy();
-    }
-
-    // This could cache null or an actual instance. Either way we will not
-    // attempt to lookup the policy again.
-    putCachedSerializationPolicy(moduleBaseURL, strongName, serializationPolicy);
-
-    return serializationPolicy;
-  }
-
-  @Override
-  public void processCall(ClientOracle clientOracle, String payload,
-      OutputStream stream) throws SerializationException {
-
-    if (!Character.isDigit(payload.charAt(0))) {
-      // Picking up null returned from getClientOracle()
-      if (clientOracle == null) {
-        throw new SerializationException("No ClientOracle for permutation "
-            + getPermutationStrongName());
-      }
-      super.processCall(clientOracle, payload, stream);
-    } else {
-      String toReturn = processCall(payload);
-      onAfterResponseSerialized(toReturn);
-
-      try {
-        stream.write(toReturn.getBytes(RPCServletUtils.CHARSET_UTF8));
-      } catch (IOException e) {
-        throw new SerializationException("Unable to commit bytes", e);
-      }
-    }
-  }
-
-  public String processCall(String payload) throws SerializationException {
-    try {
-      RPCRequest rpcRequest = RPC.decodeRequest(payload, this.getClass(), this);
-      onAfterRequestDeserialized(rpcRequest);
-      return RPC.invokeAndEncodeResponse(this, rpcRequest.getMethod(),
-          rpcRequest.getParameters(), rpcRequest.getSerializationPolicy(),
-          rpcRequest.getFlags());
-    } catch (IncompatibleRemoteServiceException ex) {
-      log(
-          "An IncompatibleRemoteServiceException was thrown while processing this call.",
-          ex);
-      return RPC.encodeResponseForFailure(null, ex);
-    } catch (RpcTokenException tokenException) {
-      log("An RpcTokenException was thrown while processing this call.",
-          tokenException);
-      return RPC.encodeResponseForFailure(null, tokenException);
-    }
-  }
-
-  /**
-   * Gets the {@link SerializationPolicy} for given module base URL and strong
-   * name if there is one.
-   * 
-   * Override this method to provide a {@link SerializationPolicy} using an
-   * alternative approach.
-   * 
-   * @param request the HTTP request being serviced
-   * @param moduleBaseURL as specified in the incoming payload
-   * @param strongName a strong name that uniquely identifies a serialization
-   *          policy file
-   * @return a {@link SerializationPolicy} for the given module base URL and
-   *         strong name, or <code>null</code> if there is none
-   */
-  protected SerializationPolicy doGetSerializationPolicy(
-      HttpServletRequest request, String moduleBaseURL, String strongName) {
-    return RemoteServiceServlet.loadSerializationPolicy(this, request,
-        moduleBaseURL, strongName);
-  }
-
-  /**
-   * @param serializedResponse
-   */
-  protected void onAfterResponseSerialized(String serializedResponse) {
-  }
-
-  private SerializationPolicy getCachedSerializationPolicy(
-      String moduleBaseURL, String strongName) {
-    synchronized (serializationPolicyCache) {
-      return serializationPolicyCache.get(moduleBaseURL + strongName);
-    }
-  }
-
-  private void putCachedSerializationPolicy(String moduleBaseURL,
-      String strongName, SerializationPolicy serializationPolicy) {
-    synchronized (serializationPolicyCache) {
-      serializationPolicyCache.put(moduleBaseURL + strongName,
-          serializationPolicy);
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java b/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
index cfcea1f..141d342 100644
--- a/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
+++ b/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
@@ -15,6 +15,8 @@
  */
 package com.google.gwt.user.server.rpc;
 
+import static com.google.gwt.user.client.rpc.RpcRequestBuilder.MODULE_BASE_HEADER;
+
 import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
 import com.google.gwt.user.client.rpc.RpcTokenException;
 import com.google.gwt.user.client.rpc.SerializationException;
@@ -194,6 +196,31 @@
         + " expected an integer in the range [1-65535] but got: " + value);
   }
 
+  /**
+   * Extract the module's base path from the current request.
+   *
+   * @return the module's base path, modulo protocol and host, as reported by
+   *         {@link com.google.gwt.core.client.GWT#getModuleBaseURL()} or
+   *         <code>null</code> if the request did not contain the
+   *         {@value com.google.gwt.user.client.rpc.RpcRequestBuilder#MODULE_BASE_HEADER} header
+   */
+  protected String getRequestModuleBasePath() {
+    try {
+      String header = getThreadLocalRequest().getHeader(MODULE_BASE_HEADER);
+      if (header == null) {
+        return null;
+      }
+      String path = new URL(header).getPath();
+      String contextPath = getThreadLocalRequest().getContextPath();
+      if (!path.startsWith(contextPath)) {
+        return null;
+      }
+      return path.substring(contextPath.length());
+    } catch (MalformedURLException e) {
+      return null;
+    }
+  }
+
   @Override
   public final SerializationPolicy getSerializationPolicy(String moduleBaseURL,
       String strongName) {
diff --git a/user/src/com/google/gwt/rpc/server/Pair.java b/user/src/com/google/web/bindery/requestfactory/server/Pair.java
similarity index 95%
rename from user/src/com/google/gwt/rpc/server/Pair.java
rename to user/src/com/google/web/bindery/requestfactory/server/Pair.java
index 0b64b48..edc3ae2 100644
--- a/user/src/com/google/gwt/rpc/server/Pair.java
+++ b/user/src/com/google/web/bindery/requestfactory/server/Pair.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.rpc.server;
+package com.google.web.bindery.requestfactory.server;
 
 /**
  * Simple pair class.
diff --git a/user/src/com/google/web/bindery/requestfactory/server/ServiceLayerCache.java b/user/src/com/google/web/bindery/requestfactory/server/ServiceLayerCache.java
index 277f9ab..b34507b 100644
--- a/user/src/com/google/web/bindery/requestfactory/server/ServiceLayerCache.java
+++ b/user/src/com/google/web/bindery/requestfactory/server/ServiceLayerCache.java
@@ -15,7 +15,6 @@
  */
 package com.google.web.bindery.requestfactory.server;
 
-import com.google.gwt.rpc.server.Pair;
 import com.google.web.bindery.requestfactory.shared.BaseProxy;
 import com.google.web.bindery.requestfactory.shared.Locator;
 import com.google.web.bindery.requestfactory.shared.RequestContext;
diff --git a/user/super/com/google/gwt/rpc/super/com/google/gwt/rpc/client/impl/ClientWriterFactory.java b/user/super/com/google/gwt/rpc/super/com/google/gwt/rpc/client/impl/ClientWriterFactory.java
deleted file mode 100644
index 4503eed..0000000
--- a/user/super/com/google/gwt/rpc/super/com/google/gwt/rpc/client/impl/ClientWriterFactory.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.core.client.GwtScriptOnly;
-import com.google.gwt.rpc.client.ast.CommandSink;
-import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-/**
- * Isolates client code from swapping out the command factory in hosted versus
- * web mode.
- */
-@GwtScriptOnly
-public class ClientWriterFactory {
-
-  public static SerializationStreamReader createReader(String payload)
-      throws IncompatibleRemoteServiceException, RemoteException {
-    CommandClientSerializationStreamReader toReturn = new CommandClientSerializationStreamReader();
-    toReturn.prepareToRead(payload);
-    return toReturn;
-  }
-
-  public static SerializationStreamWriter createWriter(
-      TypeOverrides typeOverrides, CommandSink commandSink) {
-    return new CommandClientSerializationStreamWriter(typeOverrides,
-        commandSink);
-  }
-}
diff --git a/user/super/com/google/gwt/rpc/super/com/google/gwt/rpc/client/impl/EscapeUtil.java b/user/super/com/google/gwt/rpc/super/com/google/gwt/rpc/client/impl/EscapeUtil.java
deleted file mode 100644
index f748e98..0000000
--- a/user/super/com/google/gwt/rpc/super/com/google/gwt/rpc/client/impl/EscapeUtil.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client.impl;
-
-import com.google.gwt.core.client.GwtScriptOnly;
-import com.google.gwt.user.client.rpc.impl.ClientSerializationStreamWriter;
-
-/**
- * Provides the web-mode implementation for payload escaping.
- */
-@GwtScriptOnly
-public class EscapeUtil {
-  public static String escape(String payload) {
-    return ClientSerializationStreamWriter.quoteString(payload);
-  }
-}
diff --git a/user/test/com/google/gwt/rpc/RPCSuite.gwt.xml b/user/test/com/google/gwt/rpc/RPCSuite.gwt.xml
deleted file mode 100644
index 64ef04a..0000000
--- a/user/test/com/google/gwt/rpc/RPCSuite.gwt.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--                                                                        -->
-<!-- Copyright 2009 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   -->
-<!-- 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. License for the specific language governing permissions and   -->
-<!-- limitations under the License.                                         -->
-
-<module type="fileset">
-  <inherits name="com.google.gwt.user.RPCSuite" />
-  <inherits name="com.google.gwt.rpc.RPC" />
-  
-  <!-- This allows us to reuse the existing tests -->
-  <set-property name="gwt.rpc.hijackLegacyInterface" value="true" />
-</module>
diff --git a/user/test/com/google/gwt/rpc/client/RpcCollectionsTest.java b/user/test/com/google/gwt/rpc/client/RpcCollectionsTest.java
deleted file mode 100644
index 58d2406..0000000
--- a/user/test/com/google/gwt/rpc/client/RpcCollectionsTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client;
-
-import com.google.gwt.user.client.rpc.CollectionsTest;
-
-/**
- * Tests RPC system using existing tests by overriding module name.
- */
-public class RpcCollectionsTest extends CollectionsTest {
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.rpc.RPCSuite";
-  }
-
-}
diff --git a/user/test/com/google/gwt/rpc/client/RpcCustomFieldSerializerTest.java b/user/test/com/google/gwt/rpc/client/RpcCustomFieldSerializerTest.java
deleted file mode 100644
index 2fd1d31..0000000
--- a/user/test/com/google/gwt/rpc/client/RpcCustomFieldSerializerTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client;
-
-import com.google.gwt.user.client.rpc.CustomFieldSerializerTest;
-
-/**
- * Tests RPC system using existing tests by overriding module name.
- */
-public class RpcCustomFieldSerializerTest extends CustomFieldSerializerTest {
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.rpc.RPCSuite";
-  }
-
-}
diff --git a/user/test/com/google/gwt/rpc/client/RpcEnumsTest.java b/user/test/com/google/gwt/rpc/client/RpcEnumsTest.java
deleted file mode 100644
index d89b83e..0000000
--- a/user/test/com/google/gwt/rpc/client/RpcEnumsTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client;
-
-import com.google.gwt.user.client.rpc.EnumsTest;
-
-/**
- * Tests RPC system using existing tests by overriding module name.
- */
-public class RpcEnumsTest extends EnumsTest {
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.rpc.RPCSuite";
-  }
-
-}
diff --git a/user/test/com/google/gwt/rpc/client/RpcInheritanceTest.java b/user/test/com/google/gwt/rpc/client/RpcInheritanceTest.java
deleted file mode 100644
index 6a7720b..0000000
--- a/user/test/com/google/gwt/rpc/client/RpcInheritanceTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client;
-
-import com.google.gwt.user.client.rpc.InheritanceTest;
-
-/**
- * Tests RPC system using existing tests by overriding module name.
- */
-public class RpcInheritanceTest extends InheritanceTest {
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.rpc.RPCSuite";
-  }
-
-}
diff --git a/user/test/com/google/gwt/rpc/client/RpcObjectGraphTest.java b/user/test/com/google/gwt/rpc/client/RpcObjectGraphTest.java
deleted file mode 100644
index cd77405..0000000
--- a/user/test/com/google/gwt/rpc/client/RpcObjectGraphTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client;
-
-import com.google.gwt.user.client.rpc.ObjectGraphTest;
-import com.google.gwt.user.client.rpc.SerializationException;
-
-/**
- * Tests RPC system using existing tests by overriding module name.
- */
-public class RpcObjectGraphTest extends ObjectGraphTest {
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.rpc.RPCSuite";
-  }
-
-  /**
-   * This test assumes particular concrete types and is not relevant in the
-   * deRPC code base as all type names are implicitly obfuscated.
-   */
-  @Override
-  public void testElision() throws SerializationException {
-  }
-}
diff --git a/user/test/com/google/gwt/rpc/client/RpcRecursiveClassTest.java b/user/test/com/google/gwt/rpc/client/RpcRecursiveClassTest.java
deleted file mode 100644
index de09087..0000000
--- a/user/test/com/google/gwt/rpc/client/RpcRecursiveClassTest.java
+++ /dev/null
@@ -1,30 +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.rpc.client;
-
-import com.google.gwt.user.client.rpc.RecursiveClassTest;
-
-/**
- * Tests RPC system using existing tests by overriding module name.
- */
-public class RpcRecursiveClassTest extends RecursiveClassTest {
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.rpc.RPCSuite";
-  }
-
-}
\ No newline at end of file
diff --git a/user/test/com/google/gwt/rpc/client/RpcRemoteServiceServletTest.java b/user/test/com/google/gwt/rpc/client/RpcRemoteServiceServletTest.java
deleted file mode 100644
index f216799..0000000
--- a/user/test/com/google/gwt/rpc/client/RpcRemoteServiceServletTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client;
-
-import com.google.gwt.user.client.rpc.RemoteServiceServletTest;
-
-/**
- * Tests RPC system using existing tests by overriding module name.
- */
-public class RpcRemoteServiceServletTest extends RemoteServiceServletTest {
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.rpc.RPCSuite";
-  }
-
-}
diff --git a/user/test/com/google/gwt/rpc/client/RpcRunTimeSerializationErrorsTest.java b/user/test/com/google/gwt/rpc/client/RpcRunTimeSerializationErrorsTest.java
deleted file mode 100644
index dd543db..0000000
--- a/user/test/com/google/gwt/rpc/client/RpcRunTimeSerializationErrorsTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client;
-
-import com.google.gwt.user.client.rpc.RunTimeSerializationErrorsTest;
-
-/**
- * Tests RPC system using existing tests by overriding module name.
- */
-public class RpcRunTimeSerializationErrorsTest extends
-    RunTimeSerializationErrorsTest {
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.rpc.RPCSuite";
-  }
-
-}
diff --git a/user/test/com/google/gwt/rpc/client/RpcUnicodeEscapingTest.java b/user/test/com/google/gwt/rpc/client/RpcUnicodeEscapingTest.java
deleted file mode 100644
index 331c596..0000000
--- a/user/test/com/google/gwt/rpc/client/RpcUnicodeEscapingTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client;
-
-import com.google.gwt.user.client.rpc.UnicodeEscapingTest;
-
-/**
- * Tests RPC system using existing tests by overriding module name.
- */
-public class RpcUnicodeEscapingTest extends UnicodeEscapingTest {
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.rpc.RPCSuite";
-  }
-
-}
diff --git a/user/test/com/google/gwt/rpc/client/RpcValueTypesTest.java b/user/test/com/google/gwt/rpc/client/RpcValueTypesTest.java
deleted file mode 100644
index 5e8a47b..0000000
--- a/user/test/com/google/gwt/rpc/client/RpcValueTypesTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2009 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.rpc.client;
-
-import com.google.gwt.user.client.rpc.ValueTypesTest;
-
-/**
- * Tests RPC system using existing tests by overriding module name.
- */
-public class RpcValueTypesTest extends ValueTypesTest {
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.rpc.RPCSuite";
-  }
-
-}
diff --git a/user/test/com/google/gwt/user/RPCSuite.java b/user/test/com/google/gwt/user/RPCSuite.java
index d0e54a2..6e005b6 100644
--- a/user/test/com/google/gwt/user/RPCSuite.java
+++ b/user/test/com/google/gwt/user/RPCSuite.java
@@ -17,15 +17,6 @@
 
 import com.google.gwt.dev.BootStrapPlatform;
 import com.google.gwt.junit.tools.GWTTestSuite;
-import com.google.gwt.rpc.client.RpcCollectionsTest;
-import com.google.gwt.rpc.client.RpcCustomFieldSerializerTest;
-import com.google.gwt.rpc.client.RpcEnumsTest;
-import com.google.gwt.rpc.client.RpcInheritanceTest;
-import com.google.gwt.rpc.client.RpcObjectGraphTest;
-import com.google.gwt.rpc.client.RpcRemoteServiceServletTest;
-import com.google.gwt.rpc.client.RpcRunTimeSerializationErrorsTest;
-import com.google.gwt.rpc.client.RpcUnicodeEscapingTest;
-import com.google.gwt.rpc.client.RpcValueTypesTest;
 import com.google.gwt.user.client.rpc.CollectionsTest;
 import com.google.gwt.user.client.rpc.CollectionsTestWithTypeObfuscation;
 import com.google.gwt.user.client.rpc.CoreJavaTest;
@@ -103,21 +94,6 @@
         com.google.gwt.user.client.rpc.RemoteServiceServletTestWithTypeObfuscation.class);
     suite.addTestSuite(UnicodeEscapingTestWithTypeObfuscation.class);
     suite.addTestSuite(RpcTokenTestWithTypeObfuscation.class);
-
-    // Client-side test cases for deRPC system
-    if (false) {
-      // Disabled due to https://code.google.com/p/google-web-toolkit/issues/detail?id=8136
-      suite.addTestSuite(RpcValueTypesTest.class);
-      suite.addTestSuite(RpcEnumsTest.class);
-      suite.addTestSuite(RpcInheritanceTest.class);
-      suite.addTestSuite(RpcCollectionsTest.class);
-      suite.addTestSuite(RpcCustomFieldSerializerTest.class);
-      suite.addTestSuite(RpcObjectGraphTest.class);
-      suite.addTestSuite(RpcRemoteServiceServletTest.class);
-      suite.addTestSuite(RpcUnicodeEscapingTest.class);
-      suite.addTestSuite(RpcRunTimeSerializationErrorsTest.class);
-    }
-
     return suite;
   }
 }
diff --git a/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java
index 916c98a..0750b80 100644
--- a/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java
@@ -62,7 +62,7 @@
 /**
  * TODO: document me.
  */
-public class CollectionsTestServiceImpl extends HybridServiceServlet implements
+public class CollectionsTestServiceImpl extends RemoteServiceServlet implements
     CollectionsTestService {
 
   private static String toString(Object[] values) {
diff --git a/user/test/com/google/gwt/user/server/rpc/CoreJavaTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/CoreJavaTestServiceImpl.java
index aab75d8..4d97344 100644
--- a/user/test/com/google/gwt/user/server/rpc/CoreJavaTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/CoreJavaTestServiceImpl.java
@@ -24,7 +24,7 @@
 /**
  * Remote service implementation  for serialization of GWT core.java emulations.
  */
-public class CoreJavaTestServiceImpl extends HybridServiceServlet implements CoreJavaTestService {
+public class CoreJavaTestServiceImpl extends RemoteServiceServlet implements CoreJavaTestService {
 
   @Override
   public MathContext echoMathContext(MathContext value) throws CoreJavaTestServiceException {
diff --git a/user/test/com/google/gwt/user/server/rpc/CustomFieldSerializerTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/CustomFieldSerializerTestServiceImpl.java
index 4ddc56d..e492440 100644
--- a/user/test/com/google/gwt/user/server/rpc/CustomFieldSerializerTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/CustomFieldSerializerTestServiceImpl.java
@@ -29,7 +29,7 @@
  * {@link com.google.gwt.user.client.rpc.CustomFieldSerializerTest
  * CustomFieldSerializerTest} unit test.
  */
-public class CustomFieldSerializerTestServiceImpl extends HybridServiceServlet
+public class CustomFieldSerializerTestServiceImpl extends RemoteServiceServlet
     implements CustomFieldSerializerTestService {
 
   /**
diff --git a/user/test/com/google/gwt/user/server/rpc/EnumsTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/EnumsTestServiceImpl.java
index 78053f3..56f4983 100644
--- a/user/test/com/google/gwt/user/server/rpc/EnumsTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/EnumsTestServiceImpl.java
@@ -20,7 +20,7 @@
 /**
  * Simple remote service used to echo enumerated types.
  */
-public class EnumsTestServiceImpl extends HybridServiceServlet implements
+public class EnumsTestServiceImpl extends RemoteServiceServlet implements
     EnumsTestService {
 
   @Override
diff --git a/user/test/com/google/gwt/user/server/rpc/ExceptionsTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/ExceptionsTestServiceImpl.java
index 3006c79..2f96948 100644
--- a/user/test/com/google/gwt/user/server/rpc/ExceptionsTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/ExceptionsTestServiceImpl.java
@@ -20,7 +20,7 @@
 /**
  * Remote Service Implementation for Exception serialization tests.
  */
-public class ExceptionsTestServiceImpl extends HybridServiceServlet implements
+public class ExceptionsTestServiceImpl extends RemoteServiceServlet implements
     ExceptionsTestService {
 
   @Override
diff --git a/user/test/com/google/gwt/user/server/rpc/InheritanceTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/InheritanceTestServiceImpl.java
index 41579cf..b849ef7 100644
--- a/user/test/com/google/gwt/user/server/rpc/InheritanceTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/InheritanceTestServiceImpl.java
@@ -34,7 +34,7 @@
  * Servlet used by the {@link com.google.gwt.user.client.rpc.InheritanceTest
  * InheritanceTest} unit test.
  */
-public class InheritanceTestServiceImpl extends HybridServiceServlet implements
+public class InheritanceTestServiceImpl extends RemoteServiceServlet implements
     InheritanceTestServiceSubtype {
 
   /**
diff --git a/user/test/com/google/gwt/user/server/rpc/LoggingRPCTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/LoggingRPCTestServiceImpl.java
index f9703ed..2856def 100644
--- a/user/test/com/google/gwt/user/server/rpc/LoggingRPCTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/LoggingRPCTestServiceImpl.java
@@ -34,7 +34,7 @@
 /**
  * Remote service implementation for serialization of GWT core.java.util.logging emulations.
  */
-public class LoggingRPCTestServiceImpl extends HybridServiceServlet implements
+public class LoggingRPCTestServiceImpl extends RemoteServiceServlet implements
     LoggingRPCTestService {
 
   @Override
diff --git a/user/test/com/google/gwt/user/server/rpc/MixedSerializableEchoServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/MixedSerializableEchoServiceImpl.java
index 8bf277b..e679e91 100644
--- a/user/test/com/google/gwt/user/server/rpc/MixedSerializableEchoServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/MixedSerializableEchoServiceImpl.java
@@ -22,7 +22,7 @@
  * Servlet used by the
  * {@link com.google.gwt.user.client.rpc.RunTimeSerializationErrorsTest}.
  */
-public class MixedSerializableEchoServiceImpl extends HybridServiceServlet
+public class MixedSerializableEchoServiceImpl extends RemoteServiceServlet
     implements MixedSerializableEchoService {
   @Override
   public MixedSerializable echoVoid(MixedSerializable mixed) {
diff --git a/user/test/com/google/gwt/user/server/rpc/ObjectGraphTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/ObjectGraphTestServiceImpl.java
index f0875de..7011112 100644
--- a/user/test/com/google/gwt/user/server/rpc/ObjectGraphTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/ObjectGraphTestServiceImpl.java
@@ -25,7 +25,7 @@
 /**
  * TODO: document me.
  */
-public class ObjectGraphTestServiceImpl extends HybridServiceServlet implements
+public class ObjectGraphTestServiceImpl extends RemoteServiceServlet implements
     ObjectGraphTestService {
 
   @Override
diff --git a/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTestServiceImplBase.java b/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTestServiceImplBase.java
index c96a6d4..45575ce 100644
--- a/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTestServiceImplBase.java
+++ b/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTestServiceImplBase.java
@@ -24,7 +24,7 @@
  * RPC-over-HTTP.
  */
 public class RemoteServiceServletTestServiceImplBase extends
-    HybridServiceServlet implements RemoteServiceServletTestService {
+    RemoteServiceServlet implements RemoteServiceServletTestService {
 
   /**
    * A RuntimeException the client code shouldn't know anything about.
diff --git a/user/test/com/google/gwt/user/server/rpc/TypeCheckedObjectsTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/TypeCheckedObjectsTestServiceImpl.java
index 5b9ceb0..1615e50 100644
--- a/user/test/com/google/gwt/user/server/rpc/TypeCheckedObjectsTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/TypeCheckedObjectsTestServiceImpl.java
@@ -27,7 +27,7 @@
  * Servlet used by the
  * {@link com.google.gwt.user.client.rpc.TypeCheckedObjectsTest} unit tests.
  */
-public class TypeCheckedObjectsTestServiceImpl extends HybridServiceServlet implements
+public class TypeCheckedObjectsTestServiceImpl extends RemoteServiceServlet implements
     TypeCheckedObjectsTestService {
 
   /*
diff --git a/user/test/com/google/gwt/user/server/rpc/UnicodeEscapingServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/UnicodeEscapingServiceImpl.java
index bcc5e11..87cc1b3 100644
--- a/user/test/com/google/gwt/user/server/rpc/UnicodeEscapingServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/UnicodeEscapingServiceImpl.java
@@ -21,7 +21,7 @@
 /**
  * Implementation of the {@link UnicodeEscapingService} interface.
  */
-public class UnicodeEscapingServiceImpl extends HybridServiceServlet implements
+public class UnicodeEscapingServiceImpl extends RemoteServiceServlet implements
     UnicodeEscapingService {
 
   /**
diff --git a/user/test/com/google/gwt/user/server/rpc/ValueTypesTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/ValueTypesTestServiceImpl.java
index 76bdbb3..259199c 100644
--- a/user/test/com/google/gwt/user/server/rpc/ValueTypesTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/ValueTypesTestServiceImpl.java
@@ -27,7 +27,7 @@
  * sure it isn't mangled on the way to the server and then unmangled on the way
  * back to the client.
  */
-public class ValueTypesTestServiceImpl extends HybridServiceServlet implements
+public class ValueTypesTestServiceImpl extends RemoteServiceServlet implements
     ValueTypesTestService {
 
   @Override
diff --git a/user/test/test/ServletMappingTestServiceImpl1.java b/user/test/test/ServletMappingTestServiceImpl1.java
index 4a7b9b7..84ca42f 100644
--- a/user/test/test/ServletMappingTestServiceImpl1.java
+++ b/user/test/test/ServletMappingTestServiceImpl1.java
@@ -15,12 +15,12 @@
  */
 package test;
 
-import com.google.gwt.user.server.rpc.HybridServiceServlet;
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
 
 /**
  * TODO: document me.
  */
-public class ServletMappingTestServiceImpl1 extends HybridServiceServlet
+public class ServletMappingTestServiceImpl1 extends RemoteServiceServlet
     implements ServletMappingTestService {
 
   @Override
diff --git a/user/test/test/ServletMappingTestServiceImpl2.java b/user/test/test/ServletMappingTestServiceImpl2.java
index aa4e227..c9ffde8 100644
--- a/user/test/test/ServletMappingTestServiceImpl2.java
+++ b/user/test/test/ServletMappingTestServiceImpl2.java
@@ -15,12 +15,12 @@
  */
 package test;
 
-import com.google.gwt.user.server.rpc.HybridServiceServlet;
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
 
 /**
  * TODO: document me.
  */
-public class ServletMappingTestServiceImpl2 extends HybridServiceServlet
+public class ServletMappingTestServiceImpl2 extends RemoteServiceServlet
     implements ServletMappingTestService {
 
   @Override
diff --git a/user/test/test/ServletMappingTestServiceImpl3.java b/user/test/test/ServletMappingTestServiceImpl3.java
index 2daef5e..221fadd 100644
--- a/user/test/test/ServletMappingTestServiceImpl3.java
+++ b/user/test/test/ServletMappingTestServiceImpl3.java
@@ -15,12 +15,12 @@
  */
 package test;
 
-import com.google.gwt.user.server.rpc.HybridServiceServlet;
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
 
 /**
  * TODO: document me.
  */
-public class ServletMappingTestServiceImpl3 extends HybridServiceServlet
+public class ServletMappingTestServiceImpl3 extends RemoteServiceServlet
     implements ServletMappingTestService {
 
   @Override
