diff --git a/doc/build.xml b/doc/build.xml
index a9dab35..c0306e4 100644
--- a/doc/build.xml
+++ b/doc/build.xml
@@ -243,7 +243,7 @@
 					<arg value="-sourcepath" />
 					<arg pathref="USER_SOURCE_PATH" />
 					<arg value="-examplepackages" />
-					<arg value="com.google.gwt.examples;com.google.gwt.examples.i18n;com.google.gwt.examples.http.client" />
+					<arg value="com.google.gwt.examples;com.google.gwt.examples.i18n;com.google.gwt.examples.http.client;com.google.gwt.examples.rpc.server" />
 					<arg value="-packages" />
 					<arg value="${USER_PKGS}" />
 				</java>
diff --git a/user/javadoc/com/google/gwt/examples/rpc/server/AdvancedExample.java b/user/javadoc/com/google/gwt/examples/rpc/server/AdvancedExample.java
new file mode 100644
index 0000000..b454200
--- /dev/null
+++ b/user/javadoc/com/google/gwt/examples/rpc/server/AdvancedExample.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2007 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.examples.rpc.server;
+
+import com.google.gwt.user.server.rpc.RPC;
+import com.google.gwt.user.server.rpc.RPCRequest;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Example demonstrating a more complex RPC integration scenario.
+ */
+public class AdvancedExample extends HttpServlet {
+  /**
+   * An example of how you could integrate GWTs RPC functionality without using
+   * the {@link com.google.gwt.user.server.rpc.RemoteServiceServlet}. Note that
+   * it also shows how mapping between and RPC interface and some other POJO
+   * could be performed.
+   */
+  public void doPost(HttpServletRequest httpRequest,
+      HttpServletResponse httpResponse) throws ServletException, IOException {
+    String payload = readPayloadAsUtf8(httpRequest);
+
+    try {
+      RPCRequest rpcRequest = RPC.decodeRequest(payload);
+
+      Object targetInstance = getInstanceToHandleRequest(httpRequest,
+          rpcRequest);
+
+      Method targetMethod = maybeMapRequestedMethod(targetInstance,
+          rpcRequest.getMethod());
+
+      Object[] targetParameters = maybeMapParameters(rpcRequest.getParameters());
+
+      try {
+        Object result = targetMethod.invoke(targetInstance, targetParameters);
+
+        result = maybeMapResult(rpcRequest.getMethod(), result);
+
+        /*
+         * Encode the object that will be given to the client code's
+         * AsyncCallback::onSuccess(Object) method.
+         */
+        String encodedResult = RPC.encodeResponseForSuccess(
+            rpcRequest.getMethod(), result);
+
+        sendResponseForSuccess(httpResponse, encodedResult);
+      } catch (IllegalArgumentException e) {
+        throw new SecurityException("Blocked attempt to invoke method "
+            + targetMethod, e);
+      } catch (IllegalAccessException e) {
+        throw new SecurityException("Blocked attempt to access inaccessible method " 
+            + targetMethod
+            + (targetInstance != null ? " on target " + targetInstance : ""), e);
+      } catch (InvocationTargetException e) {
+        Throwable cause = e.getCause();
+
+        Throwable mappedThrowable = maybeMapThrowable(cause,
+            rpcRequest.getMethod());
+
+        /*
+         * Encode the exception that will be passed back to the client's client
+         * code's AsyncCallback::onFailure(Throwable) method.
+         */
+        String failurePayload = RPC.encodeResponseForFailure(
+            rpcRequest.getMethod(), mappedThrowable);
+
+        sendResponseForFailure(httpResponse, failurePayload);
+      }
+    } catch (Throwable e) {
+      /*
+       * Return a generic error which will be passed to the client code's
+       * AsyncCallback::onFailure(Throwable) method.
+       */
+      sendResponseForGenericFailure(httpResponse);
+    }
+  }
+
+  private Object getInstanceToHandleRequest(HttpServletRequest httpRequest,
+      RPCRequest rpcRequest) {
+    return null;
+  }
+
+  private Method maybeMapRequestedMethod(Object targetInstance, Method method) {
+    return null;
+  }
+
+  private Object[] maybeMapParameters(Object[] parameters) {
+    return null;
+  }
+
+  private Object maybeMapResult(Method method, Object targetResult) {
+    return null;
+  }
+
+  private Throwable maybeMapThrowable(Throwable cause, Method method) {
+    return null;
+  }
+
+  private String readPayloadAsUtf8(HttpServletRequest httpRequest) {
+    return null;
+  }
+
+  private void sendResponseForFailure(HttpServletResponse httpResponse,
+      String failurePayload) {
+  }
+
+  private void sendResponseForGenericFailure(HttpServletResponse httpResponse) {
+  }
+
+  private void sendResponseForSuccess(HttpServletResponse httpResponse,
+      String encodedResult) {
+  }
+}
diff --git a/user/javadoc/com/google/gwt/examples/rpc/server/CanonicalExample.java b/user/javadoc/com/google/gwt/examples/rpc/server/CanonicalExample.java
new file mode 100644
index 0000000..1c8c38c
--- /dev/null
+++ b/user/javadoc/com/google/gwt/examples/rpc/server/CanonicalExample.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2007 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.examples.rpc.server;
+
+import com.google.gwt.user.client.rpc.SerializationException;
+import com.google.gwt.user.server.rpc.RPC;
+import com.google.gwt.user.server.rpc.RPCRequest;
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+/**
+ * Canonical RPC integration example.
+ */
+public class CanonicalExample extends RemoteServiceServlet {
+  /**
+   * Process the RPC request encoded into the payload string and return a string
+   * that encodes either the method return or an exception thrown by it.
+   */
+  public String processCall(String payload) throws SerializationException {
+    RPCRequest rpcRequest = RPC.decodeRequest(payload, this.getClass());
+
+    return RPC.invokeAndEncodeResponse(this, rpcRequest.getMethod(),
+        rpcRequest.getParameters());
+  }
+}
diff --git a/user/src/com/google/gwt/user/server/rpc/RPC.java b/user/src/com/google/gwt/user/server/rpc/RPC.java
new file mode 100644
index 0000000..741ad53
--- /dev/null
+++ b/user/src/com/google/gwt/user/server/rpc/RPC.java
@@ -0,0 +1,637 @@
+/*
+ * Copyright 2007 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.dev.util.TypeInfo;
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.SerializationException;
+import com.google.gwt.user.server.rpc.impl.ServerSerializableTypeOracle;
+import com.google.gwt.user.server.rpc.impl.ServerSerializableTypeOracleImpl;
+import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader;
+import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Utility class for integrating with the RPC system. This class exposes methods
+ * for decoding of RPC requests, encoding of RPC responses, and invocation of
+ * RPC calls on service objects. The operations exposed by this class can be
+ * reused by framework implementors such as Spring and G4jsf to support a wide
+ * range of service invocation policies.
+ * 
+ * <h3>Canonical Example</h3>
+ * The following example demonstrates the canonical way to use this class.
+ * 
+ * {@example com.google.gwt.examples.rpc.server.CanonicalExample#processCall(String)}
+ * 
+ * <h3>Advanced Example</h3>
+ * The following example shows a more advanced way of using this class to create
+ * an adapter between GWT RPC entities and POJOs.
+ * 
+ * {@example com.google.gwt.examples.rpc.server.AdvancedExample#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
+ */
+public final class RPC {
+
+  /**
+   * Maps primitive wrapper classes to their corresponding primitive class.
+   */
+  private static final Map PRIMITIVE_WRAPPER_CLASS_TO_PRIMITIVE_CLASS = new HashMap();
+
+  /**
+   * Oracle used in stream construction. Encapsulates a set of static,
+   * synchronized caches.
+   */
+  private static ServerSerializableTypeOracle serializableTypeOracle;
+
+  /**
+   * Static map of classes to sets of interfaces (e.g. classes). Optimizes
+   * lookup of interfaces for security.
+   */
+  private static Map/* <Class, Set<String> > */serviceToImplementedInterfacesMap;
+
+  private static final HashMap TYPE_NAMES;
+  static {
+    PRIMITIVE_WRAPPER_CLASS_TO_PRIMITIVE_CLASS.put(Boolean.class, Boolean.TYPE);
+    PRIMITIVE_WRAPPER_CLASS_TO_PRIMITIVE_CLASS.put(Byte.class, Byte.TYPE);
+    PRIMITIVE_WRAPPER_CLASS_TO_PRIMITIVE_CLASS.put(Character.class,
+        Character.TYPE);
+    PRIMITIVE_WRAPPER_CLASS_TO_PRIMITIVE_CLASS.put(Double.class, Double.TYPE);
+    PRIMITIVE_WRAPPER_CLASS_TO_PRIMITIVE_CLASS.put(Float.class, Float.TYPE);
+    PRIMITIVE_WRAPPER_CLASS_TO_PRIMITIVE_CLASS.put(Integer.class, Integer.TYPE);
+    PRIMITIVE_WRAPPER_CLASS_TO_PRIMITIVE_CLASS.put(Long.class, Long.TYPE);
+    PRIMITIVE_WRAPPER_CLASS_TO_PRIMITIVE_CLASS.put(Short.class, Short.TYPE);
+
+    TYPE_NAMES = new HashMap();
+    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);
+
+    serializableTypeOracle = new ServerSerializableTypeOracleImpl(
+        getPackagePaths());
+
+    serviceToImplementedInterfacesMap = new HashMap();
+  }
+
+  /**
+   * Returns an {@link RPCRequest} that is built by decoding the contents of an
+   * encoded RPC request.
+   * 
+   * <p>
+   * This method is equivalent to calling {@link #decodeRequest(String, Class)}
+   * with <code>null</code> for the type parameter.
+   * </p>
+   * 
+   * @param encodedRequest a string that encodes the {@link RemoteService}
+   *          interface, the service method to call, and the arguments to for
+   *          the service method
+   * @return an {@link RPCRequest} instance
+   * 
+   * @throws SerializationException if the encodedRequest contents cannot be
+   *           deserialized
+   * @throws SecurityException if any of the following conditions apply:
+   *           <ul>
+   *           <li><code>RPC.class.getClassLoader()</code> cannot load the
+   *           service interface requested in the encoded request</li>
+   *           <li>the requested interface is not assignable to
+   *           {@link RemoteService}</li>
+   *           <li>the service method requested in the encoded request is not a
+   *           member of the requested service interface</li>
+   *           </ul>
+   */
+  public static RPCRequest decodeRequest(String encodedRequest)
+      throws SerializationException {
+    return decodeRequest(encodedRequest, null);
+  }
+
+  /**
+   * Returns an {@link RPCRequest} that is built by decoding the contents of an
+   * encoded RPC request and optionally validating that type can handle the
+   * request. If the type parameter is not <code>null</code>, the
+   * implementation checks that the type is assignable to the
+   * {@link RemoteService} interface requested in the encoded request string.
+   * 
+   * <p>
+   * Invoking this method with <code>null</code> for the type parameter,
+   * <code>decodeRequest(encodedRequest, null)</code>, is equivalent to
+   * calling <code>decodeRequest(encodedRequest)</code>.
+   * </p>
+   * 
+   * @param encodedRequest a string that encodes the {@link RemoteService}
+   *          interface, the service method, and the arguments to pass to the
+   *          service method
+   * @param type if not <code>null</code>, the implementation checks that the
+   *          type is assignable to the {@link RemoteService} interface encoded
+   *          in the encoded request string.
+   * @return an {@link RPCRequest} instance
+   * 
+   * @throws NullPointerException if the encodedRequest is <code>null</code>
+   * @throws IllegalArgumentException if the encodedRequest is an empty string
+   * @throws SerializationException if the types in the encoded request cannot
+   *           be deserialized
+   * @throws SecurityException if any of the following conditions apply:
+   *           <ul>
+   *           <li><code>RPC.class.getClassLoader()</code> cannot load the
+   *           service interface requested in the encodedRequest</li>
+   *           <li>the requested interface is not assignable to
+   *           {@link RemoteService}</li>
+   *           <li>the service method requested in the encodedRequest is not a
+   *           member of the requested service interface</li>
+   *           <li>the type parameter is not <code>null</code> and is not
+   *           assignable to the requested {@link RemoteService} interface
+   *           </ul>
+   */
+  public static RPCRequest decodeRequest(String encodedRequest, Class type)
+      throws SerializationException {
+    if (encodedRequest == null) {
+      throw new NullPointerException("encodedRequest cannot be null");
+    }
+
+    if (encodedRequest.length() == 0) {
+      throw new IllegalArgumentException("encodedRequest cannot be empty");
+    }
+
+    ServerSerializationStreamReader streamReader = new ServerSerializationStreamReader(
+        serializableTypeOracle);
+    streamReader.prepareToRead(encodedRequest);
+
+    String serviceIntfName = streamReader.readString();
+
+    if (type != null) {
+      if (!implementsInterface(type, serviceIntfName)) {
+        // The service does not implement the requested interface
+        throw new SecurityException("Blocked attempt to access interface '"
+            + serviceIntfName + "', which is not implemented by '"
+            + TypeInfo.getSourceRepresentation(type, "")
+            + "'; this is either misconfiguration or a hack attempt");
+      }
+    }
+
+    Class serviceIntf;
+    try {
+      serviceIntf = getClassFromSerializedName(serviceIntfName);
+      if (!RemoteService.class.isAssignableFrom(serviceIntf)) {
+        // The requested interface is not a RemoteService interface
+        throw new SecurityException(
+            "Blocked attempt to access interface '"
+                + TypeInfo.getSourceRepresentation(serviceIntf, "")
+                + "', which doesn't extend RemoteService; this is either misconfiguration or a hack attempt");
+      }
+    } catch (ClassNotFoundException e) {
+      throw new SecurityException("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(paramClassName);
+      } catch (ClassNotFoundException e) {
+        throw new SerializationException("Unknown parameter " + i + " type '"
+            + paramClassName + "'", e);
+      }
+    }
+
+    Method method = findInterfaceMethod(serviceIntf, serviceMethodName,
+        parameterTypes, true);
+
+    if (method == null) {
+      throw new SecurityException(formatMethodNotFoundErrorMessage(serviceIntf,
+          serviceMethodName, parameterTypes));
+    }
+
+    Object[] parameterValues = new Object[parameterTypes.length];
+    for (int i = 0; i < parameterValues.length; i++) {
+      parameterValues[i] = streamReader.deserializeValue(parameterTypes[i]);
+    }
+
+    return new RPCRequest(method, parameterValues);
+  }
+
+  /**
+   * Returns a string that encodes an exception. It is an error to try to encode
+   * an exception that is not in the method's list of checked exceptions.
+   * 
+   * @param serviceMethod the method that threw the exception
+   * @param cause the {@link Throwable} that was thrown
+   * @return a string that encodes the exception, if the exception was expected
+   * 
+   * @throws NullPointerException if either the serviceMethod or the cause are
+   *           <code>null</code>
+   * @throws SerializationException if the result cannot be serialized
+   * @throws UnexpectedException if the result was an unexpected exception (a
+   *           checked exception not declared in the serviceMethod's signature)
+   */
+  public static String encodeResponseForFailure(Method serviceMethod,
+      Throwable cause) throws SerializationException {
+    if (serviceMethod == null) {
+      throw new NullPointerException("serviceMethod cannot be null");
+    }
+
+    if (cause == null) {
+      throw new NullPointerException("cause cannot be null");
+    }
+
+    if (RPC.isExpectedException(serviceMethod, cause)) {
+      return encodeResponse(cause.getClass(), cause, true);
+    } else {
+      throw new UnexpectedException("Service method '"
+          + getSourceRepresentation(serviceMethod)
+          + "' threw an unexpected exception: " + cause.toString(), cause);
+    }
+  }
+
+  /**
+   * Returns a string that encodes the object. It is an error to try to encode
+   * an object that is not assignable to the service method's return type.
+   * 
+   * @param serviceMethod the method whose result we are encoding
+   * @param object the instance that we wish to encode
+   * @return a string that encodes the object, if the object is compatible with
+   *         the service method's declared return type
+   * 
+   * @throws IllegalArgumentException if the result is not assignable to the
+   *           service method's return type
+   * @throws NullPointerException if the service method is <code>null</code>
+   * @throws SerializationException if the result cannot be serialized
+   */
+  public static String encodeResponseForSuccess(Method serviceMethod,
+      Object object) throws SerializationException {
+    if (serviceMethod == null) {
+      throw new NullPointerException("serviceMethod cannot be null");
+    }
+
+    Class methodReturnType = serviceMethod.getReturnType();
+    if (methodReturnType != void.class && object != null) {
+      Class actualReturnType;
+      if (methodReturnType.isPrimitive()) {
+        actualReturnType = getPrimitiveClassFromWrapper(object.getClass());
+      } else {
+        actualReturnType = object.getClass();
+      }
+
+      if (actualReturnType == null
+          || !methodReturnType.isAssignableFrom(actualReturnType)) {
+        throw new IllegalArgumentException("Type '"
+            + TypeInfo.getSourceRepresentation(object.getClass(), "")
+            + "' does not match the return type in the method's signature: '"
+            + getSourceRepresentation(serviceMethod) + "'");
+      }
+    }
+
+    return encodeResponse(methodReturnType, object, false);
+  }
+
+  /**
+   * Returns a string that encodes the result of calling a service method, which
+   * could be the value returned by the method or an exception thrown by it.
+   * 
+   * <p>
+   * This method does no security checking; security checking must be done on
+   * the method prior to this invocation.
+   * </p>
+   * 
+   * @param target instance on which to invoke the serviceMethod
+   * @param serviceMethod the method to invoke
+   * @param args arguments used for the method invocation
+   * @return a string which encodes either the method's return or a checked
+   *         exception thrown by the method
+   * 
+   * @throws SecurityException if the method cannot be accessed or if the number
+   *           or type of actual and formal arguments differ
+   * @throws SerializationException if an object could not be serialized by the
+   *           stream
+   * @throws UnexpectedException if the serviceMethod throws a checked exception
+   *           that is not declared in its signature
+   */
+  public static String invokeAndEncodeResponse(Object target,
+      Method serviceMethod, Object[] args) throws SerializationException {
+
+    if (serviceMethod == null) {
+      throw new NullPointerException("serviceMethod cannot be null");
+    }
+
+    String responsePayload;
+    try {
+      Object result = serviceMethod.invoke(target, args);
+
+      responsePayload = encodeResponseForSuccess(serviceMethod, result);
+    } catch (IllegalAccessException e) {
+      throw new SecurityException(formatIllegalAccessErrorMessage(target,
+          serviceMethod), e);
+    } catch (IllegalArgumentException e) {
+      throw new SecurityException(formatIllegalArgumentErrorMessage(target,
+          serviceMethod, args), e);
+    } catch (InvocationTargetException e) {
+      // Try to encode the caught exception
+      //
+      Throwable cause = e.getCause();
+
+      responsePayload = encodeResponseForFailure(serviceMethod, cause);
+    }
+
+    return responsePayload;
+  }
+
+  /**
+   * Returns a string that encodes the results of an RPC call. Private overload
+   * that takes a flag signaling the preamble of the response payload.
+   * 
+   * @param serviceMethod the method whose return object we are encoding
+   * @param object the object that we wish to send back to the client
+   * @param wasThrown if true, the object being returned was an exception thrown
+   *          by the service method; if false, it was the result of the service
+   *          method's invocation
+   * @return a string that encodes the response from a service method
+   * @throws SerializationException if the object cannot be serialized
+   */
+  private static String encodeResponse(Class responseClass, Object object,
+      boolean wasThrown) throws SerializationException {
+
+    ServerSerializationStreamWriter stream = new ServerSerializationStreamWriter(
+        serializableTypeOracle);
+
+    stream.prepareToWrite();
+    if (responseClass != void.class) {
+      stream.serializeValue(object, responseClass);
+    }
+
+    String bufferStr = (wasThrown ? "{EX}" : "{OK}") + stream.toString();
+    return bufferStr;
+  }
+
+  /**
+   * Find the invoked method on either the specified interface or any super.
+   */
+  private static Method findInterfaceMethod(Class intf, String methodName,
+      Class[] paramTypes, boolean includeInherited) {
+    try {
+      return intf.getDeclaredMethod(methodName, paramTypes);
+    } catch (NoSuchMethodException e) {
+      if (includeInherited) {
+        Class[] superintfs = intf.getInterfaces();
+        for (int i = 0; i < superintfs.length; i++) {
+          Method method = findInterfaceMethod(superintfs[i], methodName,
+              paramTypes, true);
+          if (method != null) {
+            return method;
+          }
+        }
+      }
+
+      return null;
+    }
+  }
+
+  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(TypeInfo.getSourceRepresentation(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(TypeInfo.getSourceRepresentation(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(TypeInfo.getSourceRepresentation(parameterTypes[i], ""));
+    }
+    sb.append(")'");
+
+    sb.append(" in interface '");
+    sb.append(TypeInfo.getSourceRepresentation(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
+   * @return Class instance for the given type name
+   * @throws ClassNotFoundException if the named type was not found
+   */
+  private static Class getClassFromSerializedName(String serializedName)
+      throws ClassNotFoundException {
+    Object value = TYPE_NAMES.get(serializedName);
+    if (value != null) {
+      return (Class) value;
+    }
+
+    return Class.forName(serializedName, false, RPC.class.getClassLoader());
+  }
+
+  /**
+   * Obtain the special package-prefixes we use to check for custom serializers
+   * that would like to live in a package that they cannot. For example,
+   * "java.util.ArrayList" is in a sealed package, so instead we use this prefix
+   * to check for a custom serializer in
+   * "com.google.gwt.user.client.rpc.core.java.util.ArrayList". Right now, it's
+   * hard-coded because we don't have a pressing need for this mechanism to be
+   * extensible, but it is imaginable, which is why it's implemented this way.
+   */
+  private static String[] getPackagePaths() {
+    return new String[] {"com.google.gwt.user.client.rpc.core"};
+  }
+
+  /**
+   * Returns the {@link java.lang.Class Class} for a primitive type given its
+   * corresponding wrapper {@link java.lang.Class Class}.
+   * 
+   * @param wrapperClass primitive wrapper class
+   * @return primitive class
+   */
+  private static Class getPrimitiveClassFromWrapper(Class wrapperClass) {
+    return (Class) PRIMITIVE_WRAPPER_CLASS_TO_PRIMITIVE_CLASS.get(wrapperClass);
+  }
+
+  /**
+   * 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 = (Set) 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) && !RemoteServiceServlet.class.equals(service)) {
+          Class[] intfs = service.getInterfaces();
+          for (int i = 0; i < intfs.length; i++) {
+            Class intf = intfs[i];
+            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;
+    }
+  }
+
+  /**
+   * Only called from 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 (int i = 0; i < intfs.length; i++) {
+      Class intf = intfs[i];
+      if (implementsInterfaceRecursive(intf, intfName)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Returns true if the {@link java.lang.reflect.Method Method} definition on
+   * the service is specified to throw the exception contained in the
+   * InvocationTargetException or false otherwise. NOTE we do not check that the
+   * type is serializable here. We assume that it must be otherwise the
+   * application would never have been allowed to run.
+   * 
+   * @param serviceIntfMethod the method from the RPC request
+   * @param cause the exception that the method threw
+   * @return true if the exception's type is in the method's signature
+   */
+  private static boolean isExpectedException(Method serviceIntfMethod,
+      Throwable cause) {
+    assert (serviceIntfMethod != null);
+    assert (cause != null);
+
+    Class[] exceptionsThrown = serviceIntfMethod.getExceptionTypes();
+    if (exceptionsThrown.length <= 0) {
+      // The method is not specified to throw any exceptions
+      //
+      return false;
+    }
+
+    Class causeType = cause.getClass();
+
+    for (int index = 0; index < exceptionsThrown.length; ++index) {
+      Class exceptionThrown = exceptionsThrown[index];
+      assert (exceptionThrown != null);
+
+      if (exceptionThrown.isAssignableFrom(causeType)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Static classes have no constructability.
+   */
+  private RPC() {
+  }
+}
diff --git a/user/src/com/google/gwt/user/server/rpc/RPCRequest.java b/user/src/com/google/gwt/user/server/rpc/RPCRequest.java
new file mode 100644
index 0000000..e21ed52
--- /dev/null
+++ b/user/src/com/google/gwt/user/server/rpc/RPCRequest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2007 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 java.lang.reflect.Method;
+
+/**
+ * Describes an incoming RPC request in terms of a resolved
+ * {@link Method} and an array of arguments.
+ */
+public final class RPCRequest {
+
+  /**
+   * The method for this request.
+   */
+  private final Method method;
+
+  /**
+   * The parameters for this request.
+   */
+  private final Object[] parameters;
+
+  /**
+   * Construct an RPCRequest.
+   */
+  public RPCRequest (Method method, Object[] parameters) {
+    this.method = method;
+    this.parameters = parameters;
+  }
+
+  /**
+   * Get the request's method.
+   */
+  public Method getMethod () {
+    return method;
+  }
+
+  /**
+   * Get the request's parameters.
+   */
+  public Object[] getParameters () {
+    return parameters;
+  }
+}
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 d329c2a..ce65ebb 100644
--- a/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
+++ b/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 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
@@ -15,22 +15,11 @@
  */
 package com.google.gwt.user.server.rpc;
 
-import com.google.gwt.user.client.rpc.RemoteService;
 import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.server.rpc.impl.ServerSerializableTypeOracle;
-import com.google.gwt.user.server.rpc.impl.ServerSerializableTypeOracleImpl;
-import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader;
-import com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
 import java.util.zip.GZIPOutputStream;
 
 import javax.servlet.ServletContext;
@@ -45,7 +34,6 @@
  * outgoing responses for client/server RPCs.
  */
 public class RemoteServiceServlet extends HttpServlet {
-
   /*
    * These members are used to get and set the different HttpServletResponse and
    * HttpServletRequest headers.
@@ -56,7 +44,6 @@
   private static final String CONTENT_ENCODING_GZIP = "gzip";
   private static final String CONTENT_TYPE_TEXT_PLAIN_UTF8 = "text/plain; charset=utf-8";
   private static final String GENERIC_FAILURE_MSG = "The call failed on the server; see server log for details";
-  private static final HashMap TYPE_NAMES;
 
   /**
    * Controls the compression threshold at and below which no compression will
@@ -64,18 +51,6 @@
    */
   private static final int UNCOMPRESSED_BYTE_SIZE_LIMIT = 256;
 
-  static {
-    TYPE_NAMES = new HashMap();
-    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);
-  }
-
   /**
    * Return true if the response object accepts Gzip encoding. This is done by
    * checking that the accept-encoding header specifies gzip as a supported
@@ -107,50 +82,77 @@
   }
 
   /**
-   * Find the invoked method on either the specified interface or any super.
+   * Read the payload as UTF-8 from the request stream.
    */
-  private static Method findInterfaceMethod(Class intf, String methodName,
-      Class[] paramTypes, boolean includeInherited) {
-    try {
-      return intf.getDeclaredMethod(methodName, paramTypes);
-    } catch (NoSuchMethodException e) {
-      if (includeInherited) {
-        Class[] superintfs = intf.getInterfaces();
-        for (int i = 0; i < superintfs.length; i++) {
-          Method method = findInterfaceMethod(superintfs[i], methodName,
-              paramTypes, true);
-          if (method != null) {
-            return method;
-          }
+  private static String readPayloadAsUtf8(HttpServletRequest request)
+      throws IOException, ServletException {
+    int contentLength = request.getContentLength();
+    if (contentLength == -1) {
+      // Content length must be known.
+      throw new ServletException("Content-Length must be specified");
+    }
+
+    String contentType = request.getContentType();
+    boolean contentTypeIsOkay = false;
+    // Content-Type must be specified.
+    if (contentType != null) {
+      // The type must be plain text.
+      if (contentType.startsWith("text/plain")) {
+        // And it must be UTF-8 encoded (or unspecified, in which case we assume
+        // that it's either UTF-8 or ASCII).
+        if (contentType.indexOf("charset=") == -1) {
+          contentTypeIsOkay = true;
+        } else if (contentType.indexOf("charset=utf-8") != -1) {
+          contentTypeIsOkay = true;
         }
       }
-
-      return null;
+    }
+    if (!contentTypeIsOkay) {
+      throw new ServletException(
+          "Content-Type must be 'text/plain' with 'charset=utf-8' (or unspecified charset)");
+    }
+    InputStream in = request.getInputStream();
+    try {
+      byte[] payload = new byte[contentLength];
+      int offset = 0;
+      int len = contentLength;
+      int byteCount;
+      while (offset < contentLength) {
+        byteCount = in.read(payload, offset, len);
+        if (byteCount == -1) {
+          throw new ServletException("Client did not send " + contentLength
+              + " bytes as expected");
+        }
+        offset += byteCount;
+        len -= byteCount;
+      }
+      return new String(payload, "UTF-8");
+    } finally {
+      if (in != null) {
+        in.close();
+      }
     }
   }
 
-  private final Set knownImplementedInterfaces = new HashSet();
-
   private final ThreadLocal perThreadRequest = new ThreadLocal();
 
   private final ThreadLocal perThreadResponse = new ThreadLocal();
 
-  private final ServerSerializableTypeOracle serializableTypeOracle;
-
   /**
    * The default constructor.
    */
   public RemoteServiceServlet() {
-    serializableTypeOracle = new ServerSerializableTypeOracleImpl(
-        getPackagePaths());
   }
 
   /**
-   * This is called internally.
+   * 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.
    */
   public final void doPost(HttpServletRequest request,
       HttpServletResponse response) {
-    Throwable caught;
     try {
       // Store the request & response objects in thread-local storage.
       //
@@ -161,166 +163,91 @@
       //
       String requestPayload = readPayloadAsUtf8(request);
 
+      // Let subclasses see the serialized request.
+      //
+      onBeforeRequestDeserialized(requestPayload);
+
       // Invoke the core dispatching logic, which returns the serialized
       // result.
       //
       String responsePayload = processCall(requestPayload);
 
+      // Let subclasses see the serialized response.
+      //
+      onAfterResponseSerialized(responsePayload);
+
       // Write the response.
       //
       writeResponse(request, response, responsePayload);
       return;
-    } catch (IOException e) {
-      caught = e;
-    } catch (ServletException e) {
-      caught = e;
-    } catch (SerializationException e) {
-      caught = e;
     } catch (Throwable e) {
-      caught = e;
+      // Give a subclass a chance to either handle the exception or rethrow it
+      //
+      doUnexpectedFailure(e);
+    } finally {
+      // null the thread-locals to avoid holding request/response
+      //
+      perThreadRequest.set(null);
+      perThreadResponse.set(null);
     }
-
-    respondWithFailure(response, caught);
   }
 
   /**
+   * Process a call originating from the given request. Uses the
+   * {@link RPC#invokeAndEncodeResponse(Object, java.lang.reflect.Method, Object[])}
+   * 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 payload the UTF-8 request payload
+   * @throws SerializationException if cannot deserialize the request, or cannot
+   *           serialize the response
+   * @throws SecurityException if there is a problem locating or invoking the
+   *           service method on the destination object
+   * @throws UnexpectedException if the invocation throws a checked exception
+   *           that is not declared in the service method's signature
+   * @throws RuntimeException if the service method throws an unchecked
+   *           exception (the exception will be the one thrown by the service)
    */
   public String processCall(String payload) throws SerializationException {
+    RPCRequest rpcRequest = RPC.decodeRequest(payload, this.getClass());
+    return RPC.invokeAndEncodeResponse(this, rpcRequest.getMethod(),
+        rpcRequest.getParameters());
+  }
 
-    // Let subclasses see the serialized request.
+  /**
+   * Override this method to control what should happen when an exception
+   * escapes the {@link #processCall(String)} method. The default implementation
+   * will log the failure and send a generic failure response to the client.<p/>
+   * 
+   * An "expected failure" is an exception thrown by a service method that is
+   * declared in the signature of the service method. These exceptions are
+   * serialized back to the client, and are not passed to this method. This
+   * method is called only for exceptions or errors that are not part of the
+   * service method's signature, or that result from SecurityExceptions,
+   * SerializationExceptions, or other failures within the RPC framework.<p/>
+   * 
+   * Note that if the desired behavior is to both send the GENERIC_FAILURE_MSG
+   * response AND to rethrow the exception, then this method should first send
+   * the GENERIC_FAILURE_MSG response itself (using getThreadLocalResponse), and
+   * then rethrow the exception.  Rethrowing the exception will cause it to escape
+   * into the servlet container.
+   * 
+   * @param e the exception which was thrown
+   */
+  protected void doUnexpectedFailure(Throwable e) {
+    ServletContext servletContext = getServletContext();
+    servletContext.log("Exception while dispatching incoming RPC call", e);
+
+    // Send GENERIC_FAILURE_MSG with 500 status.
     //
-    onBeforeRequestDeserialized(payload);
-
-    // Create a stream to deserialize the request.
-    //
-    ServerSerializationStreamReader streamReader = new ServerSerializationStreamReader(
-        serializableTypeOracle);
-    streamReader.prepareToRead(payload);
-
-    // Read the service interface
-    //
-    String serviceIntfName = streamReader.readString();
-
-    // TODO(mmendez): need a way to check the type signature of the service intf
-    // Verify that this very servlet implements the specified interface name.
-    //
-    if (!isImplementedRemoteServiceInterface(serviceIntfName)) {
-      // Bad payload, possible hack attempt.
-      //
-      throw new SecurityException(
-          "Blocked attempt to access interface '"
-              + serviceIntfName
-              + "', which is either not implemented by this servlet or which doesn't extend RemoteService; this is either misconfiguration or a hack attempt");
-    }
-
-    // Actually get the service interface, so that we can query its methods.
-    //
-    Class serviceIntf;
-    try {
-      serviceIntf = getClassFromName(serviceIntfName);
-    } catch (ClassNotFoundException e) {
-      throw new SerializationException("Unknown service interface class '"
-          + serviceIntfName + "'", e);
-    }
-
-    // Read the method name.
-    //
-    String methodName = streamReader.readString();
-
-    // Read the number and names of the parameter classes from the stream.
-    // We have to do this so that we can find the correct overload of the
-    // method.
-    //
-    int paramCount = streamReader.readInt();
-    Class[] paramTypes = new Class[paramCount];
-    for (int i = 0; i < paramTypes.length; i++) {
-      String paramClassName = streamReader.readString();
-      try {
-        paramTypes[i] = getClassOrPrimitiveFromName(paramClassName);
-      } catch (ClassNotFoundException e) {
-        throw new SerializationException("Unknown parameter " + i + " type '"
-            + paramClassName + "'", e);
-      }
-    }
-
-    // For security, make sure the method is found in the service interface
-    // and not just one that happens to be defined on this class.
-    //
-    Method serviceIntfMethod = findInterfaceMethod(serviceIntf, methodName,
-        paramTypes, true);
-
-    // If it wasn't found, don't continue.
-    //
-    if (serviceIntfMethod == null) {
-      // Bad payload, possible hack attempt.
-      //
-      throw new SecurityException(
-          "Method '"
-              + methodName
-              + "' (or a particular overload) on interface '"
-              + serviceIntfName
-              + "' was not found, this is either misconfiguration or a hack attempt");
-    }
-
-    // Deserialize the parameters.
-    //
-    Object[] args = new Object[paramCount];
-    for (int i = 0; i < args.length; i++) {
-      args[i] = streamReader.deserializeValue(paramTypes[i]);
-    }
-
-    // Make the call via reflection.
-    //
-    String responsePayload = GENERIC_FAILURE_MSG;
-    ServerSerializationStreamWriter streamWriter = new ServerSerializationStreamWriter(
-        serializableTypeOracle);
-    Throwable caught = null;
-    try {
-      Class returnType = serviceIntfMethod.getReturnType();
-      Object returnVal = serviceIntfMethod.invoke(this, args);
-      responsePayload = createResponse(streamWriter, returnType, returnVal,
-          false);
-    } catch (IllegalArgumentException e) {
-      caught = e;
-    } catch (IllegalAccessException e) {
-      caught = e;
-    } catch (InvocationTargetException e) {
-      // Try to serialize the caught exception if the client is expecting it,
-      // otherwise log the exception server-side.
-      caught = e;
-      Throwable cause = e.getCause();
-      if (cause != null) {
-        // Update the caught exception to the underlying cause
-        caught = cause;
-        // Serialize the exception back to the client if it's a declared
-        // exception
-        if (isExpectedException(serviceIntfMethod, cause)) {
-          Class thrownClass = cause.getClass();
-          responsePayload = createResponse(streamWriter, thrownClass, cause,
-              true);
-          // Don't log the exception on the server
-          caught = null;
-        }
-      }
-    }
-
-    if (caught != null) {
-      responsePayload = GENERIC_FAILURE_MSG;
-      ServletContext servletContext = getServletContext();
-      // servletContext may be null (for example, when unit testing)
-      if (servletContext != null) {
-        // Log the exception server side
-        servletContext.log("Exception while dispatching incoming RPC call",
-            caught);
-      }
-    }
-
-    // Let subclasses see the serialized response.
-    //
-    onAfterResponseSerialized(responsePayload);
-
-    return responsePayload;
+    respondWithFailure(getThreadLocalResponse());
   }
 
   /**
@@ -379,239 +306,25 @@
   }
 
   /**
-   * @param stream
-   * @param responseType
-   * @param responseObj
-   * @param isException
-   * @return response
-   */
-  private String createResponse(ServerSerializationStreamWriter stream,
-      Class responseType, Object responseObj, boolean isException) {
-    stream.prepareToWrite();
-    if (responseType != void.class) {
-      try {
-        stream.serializeValue(responseObj, responseType);
-      } catch (SerializationException e) {
-        responseObj = e;
-        isException = true;
-      }
-    }
-
-    String bufferStr = (isException ? "{EX}" : "{OK}") + stream.toString();
-    return bufferStr;
-  }
-
-  /**
-   * Returns the {@link Class} instance for the named class.
-   * 
-   * @param name the name of a class or primitive type
-   * @return Class instance for the given type name
-   * @throws ClassNotFoundException if the named type was not found
-   */
-  private Class getClassFromName(String name) throws ClassNotFoundException {
-    return Class.forName(name, false, this.getClass().getClassLoader());
-  }
-
-  /**
-   * Returns the {@link Class} instance for the named class or primitive type.
-   * 
-   * @param name the name of a class or primitive type
-   * @return Class instance for the given type name
-   * @throws ClassNotFoundException if the named type was not found
-   */
-  private Class getClassOrPrimitiveFromName(String name)
-      throws ClassNotFoundException {
-    Object value = TYPE_NAMES.get(name);
-    if (value != null) {
-      return (Class) value;
-    }
-
-    return getClassFromName(name);
-  }
-
-  /**
-   * Obtain the special package-prefixes we use to check for custom serializers
-   * that would like to live in a package that they cannot. For example,
-   * "java.util.ArrayList" is in a sealed package, so instead we use this prefix
-   * to check for a custom serializer in
-   * "com.google.gwt.user.client.rpc.core.java.util.ArrayList". Right now, it's
-   * hard-coded because we don't have a pressing need for this mechanism to be
-   * extensible, but it is imaginable, which is why it's implemented this way.
-   */
-  private String[] getPackagePaths() {
-    return new String[] {"com.google.gwt.user.client.rpc.core"};
-  }
-
-  /**
-   * Returns true if the {@link java.lang.reflect.Method Method} definition on
-   * the service is specified to throw the exception contained in the
-   * InvocationTargetException or false otherwise. NOTE we do not check that the
-   * type is serializable here. We assume that it must be otherwise the
-   * application would never have been allowed to run.
-   * 
-   * @param serviceIntfMethod
-   * @param e
-   * @return is expected exception
-   */
-  private boolean isExpectedException(Method serviceIntfMethod, Throwable cause) {
-    assert (serviceIntfMethod != null);
-    assert (cause != null);
-
-    Class[] exceptionsThrown = serviceIntfMethod.getExceptionTypes();
-    if (exceptionsThrown.length <= 0) {
-      // The method is not specified to throw any exceptions
-      //
-      return false;
-    }
-
-    Class causeType = cause.getClass();
-
-    for (int index = 0; index < exceptionsThrown.length; ++index) {
-      Class exceptionThrown = exceptionsThrown[index];
-      assert (exceptionThrown != null);
-
-      if (exceptionThrown.isAssignableFrom(causeType)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  /**
-   * Used to determine whether the specified interface name is implemented by
-   * this class without loading the class (for security).
-   */
-  private boolean isImplementedRemoteServiceInterface(String intfName) {
-    synchronized (knownImplementedInterfaces) {
-      // See if it's cached.
-      //
-      if (knownImplementedInterfaces.contains(intfName)) {
-        return true;
-      }
-
-      Class cls = getClass();
-
-      // Unknown, so walk up the class hierarchy to find the first class that
-      // implements the requested interface
-      //
-      while ((cls != null) && !RemoteServiceServlet.class.equals(cls)) {
-        Class[] intfs = cls.getInterfaces();
-        for (int i = 0; i < intfs.length; i++) {
-          Class intf = intfs[i];
-          if (isImplementedRemoteServiceInterfaceRecursive(intfName, intf)) {
-            knownImplementedInterfaces.add(intfName);
-            return true;
-          }
-        }
-
-        // did not find the interface in this class so we look in the
-        // superclass
-        cls = cls.getSuperclass();
-      }
-
-      return false;
-    }
-  }
-
-  /**
-   * Only called from isImplementedInterface().
-   */
-  private boolean isImplementedRemoteServiceInterfaceRecursive(String intfName,
-      Class intfToCheck) {
-    assert (intfToCheck.isInterface());
-
-    if (intfToCheck.getName().equals(intfName)) {
-      // The name is right, but we also verify that it is assignable to
-      // RemoteService.
-      // 
-      if (RemoteService.class.isAssignableFrom(intfToCheck)) {
-        return true;
-      } else {
-        return false;
-      }
-    }
-
-    Class[] intfs = intfToCheck.getInterfaces();
-    for (int i = 0; i < intfs.length; i++) {
-      Class intf = intfs[i];
-      if (isImplementedRemoteServiceInterfaceRecursive(intfName, intf)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  private String readPayloadAsUtf8(HttpServletRequest request)
-      throws IOException, ServletException {
-    int contentLength = request.getContentLength();
-    if (contentLength == -1) {
-      // Content length must be known.
-      throw new ServletException("Content-Length must be specified");
-    }
-
-    String contentType = request.getContentType();
-    boolean contentTypeIsOkay = false;
-    // Content-Type must be specified.
-    if (contentType != null) {
-      // The type must be plain text.
-      if (contentType.startsWith("text/plain")) {
-        // And it must be UTF-8 encoded (or unspecified, in which case we assume
-        // that it's either UTF-8 or ASCII).
-        if (contentType.indexOf("charset=") == -1) {
-          contentTypeIsOkay = true;
-        } else if (contentType.indexOf("charset=utf-8") != -1) {
-          contentTypeIsOkay = true;
-        }
-      }
-    }
-    if (!contentTypeIsOkay) {
-      throw new ServletException(
-          "Content-Type must be 'text/plain' with 'charset=utf-8' (or unspecified charset)");
-    }
-    InputStream in = request.getInputStream();
-    try {
-      byte[] payload = new byte[contentLength];
-      int offset = 0;
-      int len = contentLength;
-      int byteCount;
-      while (offset < contentLength) {
-        byteCount = in.read(payload, offset, len);
-        if (byteCount == -1) {
-          throw new ServletException("Client did not send " + contentLength
-              + " bytes as expected");
-        }
-        offset += byteCount;
-        len -= byteCount;
-      }
-      return new String(payload, "UTF-8");
-    } finally {
-      if (in != null) {
-        in.close();
-      }
-    }
-  }
-
-  /**
    * Called when the machinery of this class itself has a problem, rather than
    * the invoked third-party method. It writes a simple 500 message back to the
    * client.
    */
-  private void respondWithFailure(HttpServletResponse response, Throwable caught) {
-    ServletContext servletContext = getServletContext();
-    servletContext.log("Exception while dispatching incoming RPC call", caught);
+  private void respondWithFailure(HttpServletResponse response) {
     try {
       response.setContentType("text/plain");
       response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
       response.getWriter().write(GENERIC_FAILURE_MSG);
     } catch (IOException e) {
-      servletContext.log(
-          "sendError() failed while sending the previous failure to the client",
-          caught);
+      getServletContext().log(
+          "respondWithFailure failed while sending the previous failure to the client",
+          e);
     }
   }
 
+  /**
+   * Write the response payload to the response stream.
+   */
   private void writeResponse(HttpServletRequest request,
       HttpServletResponse response, String responsePayload) throws IOException {
 
@@ -633,8 +346,6 @@
         gzipOutputStream.flush();
         response.setHeader(CONTENT_ENCODING, CONTENT_ENCODING_GZIP);
         reply = output.toByteArray();
-      } catch (UnsupportedEncodingException e) {
-        caught = e;
       } catch (IOException e) {
         caught = e;
       } finally {
diff --git a/user/src/com/google/gwt/user/server/rpc/UnexpectedException.java b/user/src/com/google/gwt/user/server/rpc/UnexpectedException.java
new file mode 100644
index 0000000..04bac90
--- /dev/null
+++ b/user/src/com/google/gwt/user/server/rpc/UnexpectedException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2007 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;
+
+/**
+ * The GWT RPC class throws UnexpectedException when a service method, being
+ * invoked by GWT RPC, throws a checked exception that is not in the service
+ * method's signature.  Such exceptions are "unexpected" and the specific
+ * exception will be the cause of the UnexpectedException.
+ */
+public class UnexpectedException extends RuntimeException {
+  /**
+   * Construct an UnexpectedException.
+   * 
+   * @param message the detail message
+   * @param cause the cause of this {@link UnexpectedException}
+   */
+  public UnexpectedException (String message, Throwable cause) {
+    super(message, cause);
+  }
+}
diff --git a/user/src/com/google/gwt/user/server/rpc/package.html b/user/src/com/google/gwt/user/server/rpc/package.html
index f7aade4..ceed157 100644
--- a/user/src/com/google/gwt/user/server/rpc/package.html
+++ b/user/src/com/google/gwt/user/server/rpc/package.html
@@ -2,7 +2,32 @@
 <body>
 Classes used in server-side implementation of remote procedure calls.
 
-Of primary interest is RemoteServiceServlet, which is the base class of all RPC
-servers.
+<p>
+The {@link com.google.gwt.user.server.rpc.RemoteServiceServlet RemoteServiceServlet}
+class provides the most convenient implementation
+of server-side GWT RPC.  This class can be used in two ways:  it can be
+subclassed by servlets that directly implement one or more service
+interfaces, in which case incoming RPC calls will be directed to the
+servlet subclass itself; or it can be overridden to give finer control over
+routing RPC calls within a server framework.  (For more details on the
+latter, see the {@link com.google.gwt.user.server.rpc.RemoteServiceServlet#processCall(String) RemoteServiceServlet.processCall(String)} method.)
+</p>
+
+<p>
+Alternatively, GWT RPC can be integrated into an existing framework, by using 
+the {@link com.google.gwt.user.server.rpc.RPC RPC} class to perform GWT 
+RPC decoding, invocation, and encoding.  RemoteServiceServlet need not 
+be subclassed at all in this case, though reading its source is advisable.
+</p>
+
+<p>
+Note that the default RemoteServiceServlet implementation never throws
+exceptions to the servlet container.  All exceptions that escape the the 
+{@link com.google.gwt.user.server.rpc.RemoteServiceServlet#processCall(String) RemoteServiceServlet.processCall(String)}
+method will be caught, logged in the servlet context, and will cause a generic 
+failure message to be sent to the GWT client -- with a 500 status code.  To 
+customize this behavior, override 
+{@link com.google.gwt.user.server.rpc.RemoteServiceServlet#doUnexpectedFailure(java.lang.Throwable) RemoteServiceServlet.doUnexpectedFailure(java.lang.Throwable)}.
+</p>
 </body>
 </html>
diff --git a/user/test/com/google/gwt/user/RPCSuite.java b/user/test/com/google/gwt/user/RPCSuite.java
index 3dcc3eb..ffd0e8e 100644
--- a/user/test/com/google/gwt/user/RPCSuite.java
+++ b/user/test/com/google/gwt/user/RPCSuite.java
@@ -19,7 +19,9 @@
 import com.google.gwt.user.client.rpc.CustomFieldSerializerTest;
 import com.google.gwt.user.client.rpc.InheritanceTest;
 import com.google.gwt.user.client.rpc.ObjectGraphTest;
+import com.google.gwt.user.client.rpc.RemoteServiceServletTest;
 import com.google.gwt.user.client.rpc.ValueTypesTest;
+import com.google.gwt.user.server.rpc.RPCTest;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -30,13 +32,16 @@
 public class RPCSuite {
   public static Test suite() {
     TestSuite suite = new TestSuite("Test for com.google.gwt.user.client.rpc");
+    
 
+    suite.addTestSuite(RPCTest.class);
     suite.addTestSuite(ValueTypesTest.class);
     suite.addTestSuite(InheritanceTest.class);
     suite.addTestSuite(CollectionsTest.class);
     suite.addTestSuite(CustomFieldSerializerTest.class);
     suite.addTestSuite(ObjectGraphTest.class);
-
+    suite.addTestSuite(RemoteServiceServletTest.class);
+    
     return suite;
   }
 }
diff --git a/user/test/com/google/gwt/user/server/rpc/RPCTest.java b/user/test/com/google/gwt/user/server/rpc/RPCTest.java
new file mode 100644
index 0000000..d6ec304
--- /dev/null
+++ b/user/test/com/google/gwt/user/server/rpc/RPCTest.java
@@ -0,0 +1,420 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.server.rpc;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.SerializableException;
+import com.google.gwt.user.client.rpc.SerializationException;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Method;
+
+/**
+ * Tests for the {@link com.google.gwt.user.server.rpc.RPC RPC} class.
+ */
+public class RPCTest extends TestCase {
+
+  private static interface A extends RemoteService {
+    void method1() throws SerializableException;
+
+    int method2();
+
+    int method3(int val);
+  }
+
+  private static interface B {
+    void method1();
+  }
+
+  private final String VALID_ENCODED_REQUEST = "0\uffff" + // version
+      "0\uffff" + // flags
+      "2\uffff" + // string table entry count
+      A.class.getName() + "\uffff" + // string table entry #0
+      "method2" + "\uffff" + // string table entry #1
+      "1\uffff" + // interface name
+      "2\uffff" + // method name
+      "0\uffff"; // param count
+
+  private final String INVALID_METHOD_REQUEST = "0\uffff" + // version
+      "0\uffff" + // flags
+      "2\uffff" + // string table entry count
+      A.class.getName() + "\uffff" + // string table entry #0
+      "method3" + "\uffff" + // string table entry #1
+      "1\uffff" + // interface name
+      "2\uffff" + // method name
+      "0\uffff"; // param count
+
+  private final String INVALID_INTERFACE_REQUEST = "0\uffff" + // version
+      "0\uffff" + // flags
+      "2\uffff" + // string table entry count
+      B.class.getName() + "\uffff" + // string table entry #0
+      "method1" + "\uffff" + // string table entry #1
+      "1\uffff" + // interface name
+      "2\uffff" + // method name
+      "0\uffff"; // param count
+
+  /**
+   * Tests for method {@link RPC#decodeRequest(String)}
+   * 
+   * <p/> Cases:
+   * <ol>
+   * <li>String == null</li>
+   * <li>String == ""</li>
+   * <li>Valid request
+   * </ol>
+   */
+  public void testDecodeRequestString() {
+    // Case 1
+    try {
+      RPC.decodeRequest(null);
+      fail("Expected NullPointerException");
+    } catch (NullPointerException e) {
+      // expected to get here
+    } catch (SerializationException e) {
+      fail(e.getMessage());
+    }
+
+    // Case 2
+    try {
+      RPC.decodeRequest("");
+      fail("Expected IllegalArgumentException");
+    } catch (IllegalArgumentException e) {
+      // expected to get here
+    } catch (SerializationException e) {
+      fail(e.getMessage());
+    }
+
+    // Case 3
+    try {
+      RPCRequest request = RPC.decodeRequest(VALID_ENCODED_REQUEST);
+    } catch (SerializationException e) {
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * Tests for method {@link RPC#decodeRequest(String, Class)}
+   * 
+   * <p/> Cases:
+   * <ol>
+   * <li>String == null</li>
+   * <li>String == ""</li>
+   * <li>Class is null</li>
+   * <li>Class implements RemoteService subinterface</li>
+   * <li>Class implements the requested interface but it is not a subtype of
+   * RemoteService</li>
+   * <li>Class implements RemoteService derived interface but the method does
+   * not exist
+   * </ol>
+   * 
+   * @throws NoSuchMethodException
+   * @throws SecurityException
+   */
+  public void testDecodeRequestStringClass() throws SecurityException,
+      NoSuchMethodException {
+    // Case 1
+    try {
+      RPC.decodeRequest(null, null);
+      fail("Expected NullPointerException");
+    } catch (NullPointerException e) {
+      // expected to get here
+    } catch (SerializationException e) {
+      fail(e.getMessage());
+    }
+
+    // Case 2
+    try {
+      RPC.decodeRequest("", null);
+      fail("Expected IllegalArgumentException");
+    } catch (IllegalArgumentException e) {
+      // expected to get here
+    } catch (SerializationException e) {
+      fail(e.getMessage());
+    }
+
+    // Case 3
+    try {
+      RPCRequest request = RPC.decodeRequest(VALID_ENCODED_REQUEST, null);
+      assertEquals(A.class.getMethod("method2", null), request.getMethod());
+      assertTrue(request.getParameters().length == 0);
+    } catch (SerializationException e) {
+      e.printStackTrace();
+    }
+
+    // Case 4
+    try {
+      RPCRequest request = RPC.decodeRequest(VALID_ENCODED_REQUEST, A.class);
+      assertEquals(A.class.getMethod("method2", null), request.getMethod());
+      assertTrue(request.getParameters().length == 0);
+    } catch (SerializationException e) {
+      e.printStackTrace();
+    }
+
+    // Case 5
+    try {
+      RPCRequest request = RPC.decodeRequest(INVALID_INTERFACE_REQUEST, B.class);
+    } catch (SecurityException e) {
+      // should get here
+      System.out.println(e.getMessage());
+    } catch (Throwable e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+
+    // Case 6
+    try {
+      RPCRequest request = RPC.decodeRequest(INVALID_METHOD_REQUEST, A.class);
+    } catch (SecurityException e) {
+      // should get here
+      System.out.println(e.getMessage());
+    } catch (Throwable e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
+
+  /**
+   * Tests for method {@link RPC#encodeResponseForFailure(Method, Throwable)}
+   * 
+   * Cases:
+   * <ol>
+   * <li>Method == null</li>
+   * <li>Object == null</li>
+   * <li>Method is not specified to throw an exception of the given type</li>
+   * <li>Method is specified to throw an exception of the given type</li>
+   * </ol>
+   * 
+   */
+  public void testEncodeResponseForFailure() {
+    // Case 1
+    try {
+      RPC.encodeResponseForFailure(null, new Throwable());
+      fail("Expected NullPointerException");
+    } catch (NullPointerException e) {
+      // expected to get here
+    } catch (Throwable e) {
+      fail(e.getMessage());
+    }
+
+    Method A_method1 = null;
+    try {
+      A_method1 = A.class.getMethod("method1", null);
+    } catch (Throwable e) {
+      fail(e.getMessage());
+    }
+
+    // Case 2
+    try {
+      RPC.encodeResponseForFailure(A_method1, null);
+      fail("Expected NullPointerException");
+    } catch (NullPointerException e) {
+      // expected to get here
+    } catch (Throwable e) {
+      fail(e.getMessage());
+    }
+
+    // Case 3
+    try {
+      RPC.encodeResponseForFailure(A.class.getMethod("method1", null),
+          new IllegalArgumentException());
+      fail("Expected UnexpectedException");
+    } catch (UnexpectedException e) {
+      // expected to get here
+      System.out.println(e.getMessage());
+    } catch (Throwable e) {
+      fail(e.getMessage());
+    }
+
+    // Case 4
+    try {
+      String str = RPC.encodeResponseForFailure(A.class.getMethod("method1",
+          null), new SerializableException());
+      assertTrue(str.contains("SerializableException"));
+    } catch (Throwable e) {
+      fail(e.getMessage());
+    }
+  }
+
+  /**
+   * Tests for {@link RPC#encodeResponseForSuccess(Method, Object)}
+   * 
+   * Cases:
+   * <ol>
+   * <li>Method == null</li>
+   * <li>Object == null</li>
+   * <li>Method is not specified to return the given type</li>
+   * <li>Method is specified to return the given type</li>
+   * </ol>
+   */
+  public void testEncodeResponseForSuccess() {
+    Method A_method1 = null;
+    Method A_method2 = null;
+    try {
+      A_method1 = A.class.getMethod("method1", null);
+      A_method2 = A.class.getMethod("method2", null);
+    } catch (Throwable e) {
+      fail(e.getMessage());
+    }
+
+    // Case 1
+    try {
+      RPC.encodeResponseForSuccess(null, new Object());
+      fail("Expected NullPointerException");
+    } catch (NullPointerException e) {
+      // expected to get here
+    } catch (Throwable e) {
+      fail(e.getMessage());
+    }
+
+    // Case 2
+    try {
+      RPC.encodeResponseForSuccess(A_method1, null);
+    } catch (NullPointerException e) {
+      // expected to get here
+    } catch (Throwable e) {
+      fail(e.getMessage());
+    }
+
+    // Case 3
+    try {
+      RPC.encodeResponseForSuccess(A_method2, new SerializableException());
+    } catch (IllegalArgumentException e) {
+      // expected to get here
+      System.out.println(e.getMessage());
+    } catch (Throwable e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+
+    // Case 4
+    try {
+      RPC.encodeResponseForSuccess(A_method2, new Integer(1));
+    } catch (Throwable e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
+
+  /**
+   * Tests for {@link RPC#invokeAndEncodeResponse(Object, Method, Object[])}
+   * 
+   * Cases:
+   * <ol>
+   * <li>Method == null</li>
+   * <li>Object does not implement Method</li>
+   * <li>Method parameters do not match given parameters
+   * <li>Method throws exception that it is not specified to
+   * <li>Method throws exception that it is specified to throw
+   * </ol>
+   * 
+   * @throws NoSuchMethodException
+   * @throws SecurityException
+   * 
+   */
+  public void testInvokeAndEncodeResponse() throws SecurityException,
+      NoSuchMethodException {
+    // Case 1
+    try {
+      RPC.invokeAndEncodeResponse(null, null, null);
+    } catch (NullPointerException e) {
+      // expected to get here
+    } catch (Throwable e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+
+    Method A_method1 = A.class.getMethod("method1", null);
+
+    // Case 2
+    try {
+      RPC.invokeAndEncodeResponse(new B() {
+        public void method1() {
+        }
+      }, A_method1, null);
+    } catch (SecurityException e) {
+      // expected to get here
+      System.out.println(e.getMessage());
+    } catch (Throwable e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+
+    // Case 3
+    try {
+      RPC.invokeAndEncodeResponse(new A() {
+        public void method1() throws SerializableException {
+        }
+
+        public int method2() {
+          return 0;
+        }
+
+        public int method3(int val) {
+          return 0;
+        }
+      }, A_method1, new Integer[] {new Integer(1)});
+    } catch (SecurityException e) {
+      // expected to get here
+      System.out.println(e.getMessage());
+    } catch (Throwable e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+
+    // Case 4
+    try {
+      RPC.invokeAndEncodeResponse(new A() {
+        public void method1() throws SerializableException {
+          throw new IllegalArgumentException();
+        }
+
+        public int method2() {
+          return 0;
+        }
+
+        public int method3(int val) {
+          return 0;
+        }
+      }, A_method1, null);
+    } catch (UnexpectedException e) {
+      // expected to get here
+      System.out.println(e.getMessage());
+    } catch (Throwable e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+
+    // Case 5
+    try {
+      RPC.invokeAndEncodeResponse(new A() {
+        public void method1() throws SerializableException {
+          throw new SerializableException();
+        }
+
+        public int method2() {
+          return 0;
+        }
+
+        public int method3(int val) {
+          return 0;
+        }
+      }, A_method1, null);
+    } catch (Throwable e) {
+      fail(e.getMessage());
+    }
+  }
+}
