Optimizations for server-side invocations of CustomFieldSerializers.

Review at http://gwt-code-reviews.appspot.com/1273801

Patch by: mchaston
Review by: jat


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9592 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/rpc/CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/CustomFieldSerializer.java
new file mode 100644
index 0000000..7f794cb
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/rpc/CustomFieldSerializer.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.rpc;
+
+/**
+ * An interface that may be implemented by class-based custom field serializers
+ * which will reduce the amount of server-side reflection during serialization,
+ * hence improving their serialization performance.
+ *
+ * @param <T> the type of the object being serialized
+ */
+public abstract class CustomFieldSerializer<T> {
+
+  /**
+   * Deserializes the content of the object from the
+   * {@link SerializationStreamReader}.
+   *
+   * @param streamReader the {@link SerializationStreamReader} to read the
+   *        object's content from
+   * @param instance the object instance to deserialize
+   *
+   * @throws SerializationException if the deserialization operation is not
+   *        successful
+   */
+  public abstract void deserializeInstance(
+      SerializationStreamReader streamReader, T instance)
+      throws SerializationException;
+
+  /**
+   * @return <code>true</code> if a specialist {@link #instantiateInstance} is
+   *         implemented; <code>false</code> otherwise
+   */
+  public boolean hasCustomInstantiateInstance() {
+    return false;
+  }
+
+  /**
+   * Instantiates an object from the {@link SerializationStreamReader}.
+   * <p>
+   * Most of the time, this can be left unimplemented and the framework
+   * will instantiate the instance itself.  This is typically used when the
+   * object being deserialized is immutable, hence it has to be created with
+   * its state already set.
+   * <p>
+   * If this is overridden, the {@link #hasCustomInstantiateInstance} method
+   * must return <code>true</code> in order for the framework to know to call
+   * it.
+   *
+   * @param streamReader the {@link SerializationStreamReader} to read the
+   *        object's content from
+   *
+   * @return an object that has been loaded from the
+   *         {@link SerializationStreamReader}
+   *
+   * @throws SerializationException if the instantiation operation is not
+   *        successful
+   */
+  public T instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    throw new SerializationException(
+        "instantiateInstance is not supported by " + getClass().getName());
+  }
+
+  /**
+   * Serializes the content of the object into the
+   * {@link SerializationStreamWriter}.
+   *
+   * @param streamWriter the {@link SerializationStreamWriter} to write the
+   *        object's content to
+   * @param instance the object instance to serialize
+   *
+   * @throws SerializationException if the serialization operation is not
+   *        successful
+   */
+  public abstract void serializeInstance(SerializationStreamWriter streamWriter,
+      T instance) throws SerializationException;
+}
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Boolean_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Boolean_CustomFieldSerializer.java
index 379ef0e..4deb604 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Boolean_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Boolean_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.Boolean}.
  */
-public final class Boolean_CustomFieldSerializer {
+public final class Boolean_CustomFieldSerializer extends
+    CustomFieldSerializer<Boolean> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -39,4 +41,25 @@
       Boolean instance) throws SerializationException {
     streamWriter.writeBoolean(instance.booleanValue());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Boolean instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Boolean instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Boolean instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Byte_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Byte_CustomFieldSerializer.java
index b10fa5d..ee21d33 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Byte_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Byte_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.Byte}.
  */
-public final class Byte_CustomFieldSerializer {
+public final class Byte_CustomFieldSerializer extends
+    CustomFieldSerializer<Byte> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -40,4 +42,24 @@
     streamWriter.writeByte(instance.byteValue());
   }
 
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Byte instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Byte instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Byte instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Character_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Character_CustomFieldSerializer.java
index 3f7d085..58e6554 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Character_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Character_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.Character}.
  */
-public final class Character_CustomFieldSerializer {
+public final class Character_CustomFieldSerializer extends
+    CustomFieldSerializer<Character> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -39,4 +41,25 @@
       Character instance) throws SerializationException {
     streamWriter.writeChar(instance.charValue());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Character instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Character instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Character instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Double_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Double_CustomFieldSerializer.java
index a7bc6cd..f0a706b 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Double_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Double_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.Double}.
  */
-public final class Double_CustomFieldSerializer {
+public final class Double_CustomFieldSerializer extends
+    CustomFieldSerializer<Double> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -39,4 +41,25 @@
       Double instance) throws SerializationException {
     streamWriter.writeDouble(instance.doubleValue());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Double instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Double instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Double instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Float_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Float_CustomFieldSerializer.java
index f19e38c..10ff4c4 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Float_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Float_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.Float}.
  */
-public final class Float_CustomFieldSerializer {
+public final class Float_CustomFieldSerializer extends 
+    CustomFieldSerializer<Float> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -39,4 +41,25 @@
       Float instance) throws SerializationException {
     streamWriter.writeFloat(instance.floatValue());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Float instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Float instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Float instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Integer_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Integer_CustomFieldSerializer.java
index 9d01e79..2e4a253 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Integer_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Integer_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.Integer}.
  */
-public final class Integer_CustomFieldSerializer {
+public final class Integer_CustomFieldSerializer extends
+    CustomFieldSerializer<Integer> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -40,4 +42,24 @@
     streamWriter.writeInt(instance.intValue());
   }
 
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Integer instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Integer instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Integer instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Long_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Long_CustomFieldSerializer.java
index 4b416b5..b2938a6 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Long_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Long_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.Long}.
  */
-public final class Long_CustomFieldSerializer {
+public final class Long_CustomFieldSerializer extends
+    CustomFieldSerializer<Long> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -40,4 +42,24 @@
     streamWriter.writeLong(instance.longValue());
   }
 
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Long instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Long instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Long instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Object_Array_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Object_Array_CustomFieldSerializer.java
index 836e627..e7a5ef9 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Object_Array_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Object_Array_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom Serializer for arrays of {@link java.lang.Object}.
  */
-public class Object_Array_CustomFieldSerializer {
+public class Object_Array_CustomFieldSerializer extends
+    CustomFieldSerializer<Object[]> {
 
   public static void deserialize(SerializationStreamReader streamReader,
       Object[] instance) throws SerializationException {
@@ -40,4 +42,13 @@
     }
   }
 
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Object[] instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Object[] instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Short_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Short_CustomFieldSerializer.java
index 77935dd..180c471 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Short_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Short_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.Short}.
  */
-public final class Short_CustomFieldSerializer {
+public final class Short_CustomFieldSerializer extends
+    CustomFieldSerializer<Short> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -40,4 +42,24 @@
     streamWriter.writeShort(instance.shortValue());
   }
 
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Short instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Short instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Short instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/StackTraceElement_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/StackTraceElement_CustomFieldSerializer.java
index ea07f4b..d86374b 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/StackTraceElement_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/StackTraceElement_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.StackTraceElement}.
  */
-public final class StackTraceElement_CustomFieldSerializer {
+public final class StackTraceElement_CustomFieldSerializer extends
+    CustomFieldSerializer<StackTraceElement> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -30,8 +32,8 @@
     // No fields
   }
 
-  public static StackTraceElement instantiate(SerializationStreamReader streamReader)
-      throws SerializationException {
+  public static StackTraceElement instantiate(
+      SerializationStreamReader streamReader) throws SerializationException {
     return new StackTraceElement(streamReader.readString(),
         streamReader.readString(),
         streamReader.readString(),
@@ -45,4 +47,25 @@
     streamWriter.writeString(instance.getFileName());
     streamWriter.writeInt(instance.getLineNumber());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      StackTraceElement instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public StackTraceElement instantiateInstance(SerializationStreamReader
+      streamReader) throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      StackTraceElement instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/String_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/String_CustomFieldSerializer.java
index 93502a6..523e17c 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/String_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/String_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.String}.
  */
-public class String_CustomFieldSerializer {
+public class String_CustomFieldSerializer extends
+    CustomFieldSerializer<String> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -40,4 +42,24 @@
     streamWriter.writeString(instance);
   }
 
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      String instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public String instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      String instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Void_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Void_CustomFieldSerializer.java
index ad1cf52..a8f97d5 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Void_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Void_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.lang;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -22,7 +23,8 @@
 /**
  * Custom field serializer for {@link java.lang.Void}.
  */
-public final class Void_CustomFieldSerializer {
+public final class Void_CustomFieldSerializer extends
+    CustomFieldSerializer<Void> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -39,4 +41,25 @@
   public static void serialize(SerializationStreamWriter streamWriter,
       Void instance) throws SerializationException {
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Void instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Void instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Void instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/math/BigDecimal_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/math/BigDecimal_CustomFieldSerializer.java
index 40cb643..8feb009 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/math/BigDecimal_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/math/BigDecimal_CustomFieldSerializer.java
@@ -18,6 +18,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.math;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -27,7 +28,8 @@
 /**
  * Custom field serializer for BigDecimal.
  */
-public class BigDecimal_CustomFieldSerializer {
+public class BigDecimal_CustomFieldSerializer extends
+    CustomFieldSerializer<BigDecimal> {
 
   /**
    * @param streamReader a SerializationStreamReader instance
@@ -46,4 +48,25 @@
       BigDecimal instance) throws SerializationException {
     streamWriter.writeString(instance.toString());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      BigDecimal instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public BigDecimal instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      BigDecimal instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/math/BigInteger_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/math/BigInteger_CustomFieldSerializer.java
index a69d51f..3aed572 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/math/BigInteger_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/math/BigInteger_CustomFieldSerializer.java
@@ -18,6 +18,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.math;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -27,7 +28,8 @@
 /**
  * Custom field serializer for BigInteger.
  */
-public class BigInteger_CustomFieldSerializer {
+public class BigInteger_CustomFieldSerializer extends
+    CustomFieldSerializer<BigInteger> {
 
   /**
    * @param streamReader a SerializationStreamReader instance
@@ -46,4 +48,25 @@
       BigInteger instance) throws SerializationException {
     streamWriter.writeString(instance.toString());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      BigInteger instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public BigInteger instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      BigInteger instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/math/MathContext_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/math/MathContext_CustomFieldSerializer.java
index 3221a4c..2d46243 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/math/MathContext_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/math/MathContext_CustomFieldSerializer.java
@@ -18,6 +18,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.math;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -28,7 +29,8 @@
 /**
  * Custom field serializer for MathContext.
  */
-public class MathContext_CustomFieldSerializer {
+public class MathContext_CustomFieldSerializer extends
+    CustomFieldSerializer<MathContext> {
 
   /**
    * @param streamReader a SerializationStreamReader instance
@@ -49,4 +51,25 @@
     streamWriter.writeInt(instance.getPrecision());
     streamWriter.writeInt(instance.getRoundingMode().ordinal());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      MathContext instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public MathContext instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      MathContext instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/sql/Date_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/sql/Date_CustomFieldSerializer.java
index 4e410a4..bedcfb4 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/sql/Date_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/sql/Date_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.sql;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -26,7 +27,8 @@
  * the three-arg constructor to account for variances in implementations of
  * Date.
  */
-public final class Date_CustomFieldSerializer {
+public final class Date_CustomFieldSerializer extends
+    CustomFieldSerializer<Date> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -43,4 +45,25 @@
       Date instance) throws SerializationException {
     streamWriter.writeLong(instance.getTime());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Date instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Date instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Date instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/sql/Time_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/sql/Time_CustomFieldSerializer.java
index 7c8c7e7..60d9d0b 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/sql/Time_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/sql/Time_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.sql;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -26,7 +27,8 @@
  * constructor due to differences in implementations when using the single-arg
  * constructor (is the day Jan 1 1970, what are the millis).
  */
-public final class Time_CustomFieldSerializer {
+public final class Time_CustomFieldSerializer extends
+    CustomFieldSerializer<Time> {
 
   @SuppressWarnings("unused")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -43,4 +45,25 @@
       Time instance) throws SerializationException {
     streamWriter.writeLong(instance.getTime());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Time instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Time instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Time instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/sql/Timestamp_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/sql/Timestamp_CustomFieldSerializer.java
index 6733fd4..9923de8 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/sql/Timestamp_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/sql/Timestamp_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.sql;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -24,7 +25,8 @@
 /**
  * Custom field serializer for {@link java.sql.Timestamp}.
  */
-public final class Timestamp_CustomFieldSerializer {
+public final class Timestamp_CustomFieldSerializer extends
+    CustomFieldSerializer<Timestamp> {
 
   public static void deserialize(SerializationStreamReader streamReader,
       Timestamp instance) throws SerializationException {
@@ -41,4 +43,25 @@
     streamWriter.writeLong(instance.getTime());
     streamWriter.writeInt(instance.getNanos());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Timestamp instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Timestamp instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Timestamp instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/ArrayList_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/ArrayList_CustomFieldSerializer.java
index abfe265..e0a6b62 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/ArrayList_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/ArrayList_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -24,7 +25,8 @@
 /**
  * Custom field serializer for {@link java.util.ArrayList}.
  */
-public final class ArrayList_CustomFieldSerializer {
+public final class ArrayList_CustomFieldSerializer extends
+    CustomFieldSerializer<ArrayList> {
 
   @SuppressWarnings("unchecked")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -37,4 +39,14 @@
       ArrayList instance) throws SerializationException {
     Collection_CustomFieldSerializerBase.serialize(streamWriter, instance);
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      ArrayList instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      ArrayList instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java
index b27afae..9a477c6 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/Arrays.java
@@ -16,6 +16,7 @@
 package com.google.gwt.user.client.rpc.core.java.util;
 
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -28,9 +29,10 @@
 public final class Arrays {
 
   /**
-   * Custom field serializer for {@link java.util.Arrays$ArrayList}.
+   * Custom field serializer for {@link java.util.Arrays.ArrayList}.
    */
-  public static final class ArrayList_CustomFieldSerializer {
+  public static final class ArrayList_CustomFieldSerializer extends
+      CustomFieldSerializer<List> {
 
     public static String concreteType() {
       return java.util.Arrays.asList().getClass().getName();
@@ -67,5 +69,26 @@
       }
       streamWriter.writeObject(array);
     }
+
+    public void deserializeInstance(SerializationStreamReader streamReader,
+        List instance) throws SerializationException {
+      deserialize(streamReader, instance);
+    }
+
+    @Override
+    public boolean hasCustomInstantiateInstance() {
+      return true;
+    }
+
+    @Override
+    public List instantiateInstance(SerializationStreamReader streamReader)
+        throws SerializationException {
+      return instantiate(streamReader);
+    }
+
+    public void serializeInstance(SerializationStreamWriter streamWriter,
+        List instance) throws SerializationException {
+      serialize(streamWriter, instance);
+    }
   }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java
index 6b54997..8ee6e70 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -29,9 +30,10 @@
 public final class Collections {
 
   /**
-   * Custom field serializer for {@link java.util.Collections$EmptyList}.
+   * Custom field serializer for {@link java.util.Collections.EmptyList}.
    */
-  public static final class EmptyList_CustomFieldSerializer {
+  public static final class EmptyList_CustomFieldSerializer extends
+      CustomFieldSerializer<List> {
 
     public static String concreteType() {
       return java.util.Collections.emptyList().getClass().getName();
@@ -54,12 +56,34 @@
         List instance) throws SerializationException {
       // Nothing to serialize -- instantiate always returns the same thing
     }
+
+    public void deserializeInstance(SerializationStreamReader streamReader,
+        List instance) throws SerializationException {
+      deserialize(streamReader, instance);
+    }
+
+    @Override
+    public boolean hasCustomInstantiateInstance() {
+      return true;
+    }
+
+    @Override
+    public List instantiateInstance(SerializationStreamReader streamReader)
+        throws SerializationException {
+      return instantiate(streamReader);
+    }
+
+    public void serializeInstance(SerializationStreamWriter streamWriter,
+        List instance) throws SerializationException {
+      serialize(streamWriter, instance);
+    }
   }
 
   /**
-   * Custom field serializer for {@link java.util.Collections$EmptyMap}.
+   * Custom field serializer for {@link java.util.Collections.EmptyMap}.
    */
-  public static final class EmptyMap_CustomFieldSerializer {
+  public static final class EmptyMap_CustomFieldSerializer extends
+      CustomFieldSerializer<Map> {
 
     public static String concreteType() {
       return java.util.Collections.emptyMap().getClass().getName();
@@ -82,12 +106,34 @@
         Map instance) throws SerializationException {
       // Nothing to serialize -- instantiate always returns the same thing
     }
+
+    public void deserializeInstance(SerializationStreamReader streamReader,
+        Map instance) throws SerializationException {
+      deserialize(streamReader, instance);
+    }
+
+    @Override
+    public boolean hasCustomInstantiateInstance() {
+      return true;
+    }
+
+    @Override
+    public Map instantiateInstance(SerializationStreamReader streamReader)
+        throws SerializationException {
+      return instantiate(streamReader);
+    }
+
+    public void serializeInstance(SerializationStreamWriter streamWriter,
+        Map instance) throws SerializationException {
+      serialize(streamWriter, instance);
+    }
   }
 
   /**
-   * Custom field serializer for {@link java.util.Collections$EmptySet}.
+   * Custom field serializer for {@link java.util.Collections.EmptySet}.
    */
-  public static final class EmptySet_CustomFieldSerializer {
+  public static final class EmptySet_CustomFieldSerializer extends
+      CustomFieldSerializer<Set> {
 
     public static String concreteType() {
       return java.util.Collections.emptySet().getClass().getName();
@@ -110,12 +156,34 @@
         Set instance) throws SerializationException {
       // Nothing to serialize -- instantiate always returns the same thing
     }
+
+    public void deserializeInstance(SerializationStreamReader streamReader,
+        Set instance) throws SerializationException {
+      deserialize(streamReader, instance);
+    }
+
+    @Override
+    public boolean hasCustomInstantiateInstance() {
+      return true;
+    }
+
+    @Override
+    public Set instantiateInstance(SerializationStreamReader streamReader)
+        throws SerializationException {
+      return instantiate(streamReader);
+    }
+
+    public void serializeInstance(SerializationStreamWriter streamWriter,
+        Set instance) throws SerializationException {
+      serialize(streamWriter, instance);
+    }
   }
 
   /**
-   * Custom field serializer for {@link java.util.Collections$SingletonList}.
+   * Custom field serializer for {@link java.util.Collections.SingletonList}.
    */
-  public static final class SingletonList_CustomFieldSerializer {
+  public static final class SingletonList_CustomFieldSerializer extends
+      CustomFieldSerializer<List> {
 
     public static String concreteType() {
       return java.util.Collections.singletonList(null).getClass().getName();
@@ -137,5 +205,26 @@
         List instance) throws SerializationException {
       streamWriter.writeObject(instance.get(0));
     }
+
+    public void deserializeInstance(SerializationStreamReader streamReader,
+        List instance) throws SerializationException {
+      deserialize(streamReader, instance);
+    }
+
+    @Override
+    public boolean hasCustomInstantiateInstance() {
+      return true;
+    }
+
+    @Override
+    public List instantiateInstance(SerializationStreamReader streamReader)
+        throws SerializationException {
+      return instantiate(streamReader);
+    }
+
+    public void serializeInstance(SerializationStreamWriter streamWriter,
+        List instance) throws SerializationException {
+      serialize(streamWriter, instance);
+    }
   }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/Date_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/Date_CustomFieldSerializer.java
index 3470b3f..42409ec 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/Date_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/Date_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -24,7 +25,8 @@
 /**
  * Custom field serializer for {@link java.util.Date}.
  */
-public final class Date_CustomFieldSerializer {
+public final class Date_CustomFieldSerializer extends
+    CustomFieldSerializer<Date> {
 
   /**
    * @param streamReader a SerializationStreamReader instance
@@ -44,4 +46,25 @@
       Date instance) throws SerializationException {
     streamWriter.writeLong(instance.getTime());
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Date instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public Date instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Date instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/HashMap_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/HashMap_CustomFieldSerializer.java
index 94c51f6..007f787 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/HashMap_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/HashMap_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -24,7 +25,8 @@
 /**
  * Custom field serializer for {@link java.util.HashMap}.
  */
-public final class HashMap_CustomFieldSerializer {
+public final class HashMap_CustomFieldSerializer extends
+    CustomFieldSerializer<HashMap> {
 
   @SuppressWarnings("unchecked")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -38,4 +40,13 @@
     Map_CustomFieldSerializerBase.serialize(streamWriter, instance);
   }
 
-}
\ No newline at end of file
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      HashMap instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      HashMap instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
+}
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/HashSet_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/HashSet_CustomFieldSerializer.java
index 15d62d1..925a280 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/HashSet_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/HashSet_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -24,7 +25,8 @@
 /**
  * Custom field serializer for {@link java.util.HashSet}.
  */
-public final class HashSet_CustomFieldSerializer {
+public final class HashSet_CustomFieldSerializer extends
+    CustomFieldSerializer<HashSet> {
 
   @SuppressWarnings("unchecked")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -37,4 +39,14 @@
       HashSet instance) throws SerializationException {
     Collection_CustomFieldSerializerBase.serialize(streamWriter, instance);
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      HashSet instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      HashSet instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/IdentityHashMap_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/IdentityHashMap_CustomFieldSerializer.java
index 59f3342..858e6ff 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/IdentityHashMap_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/IdentityHashMap_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -24,7 +25,8 @@
 /**
  * Custom field serializer for {@link java.util.HashMap}.
  */
-public final class IdentityHashMap_CustomFieldSerializer {
+public final class IdentityHashMap_CustomFieldSerializer extends
+    CustomFieldSerializer<IdentityHashMap> {
 
   @SuppressWarnings("unchecked")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -37,4 +39,14 @@
       IdentityHashMap instance) throws SerializationException {
     Map_CustomFieldSerializerBase.serialize(streamWriter, instance);
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      IdentityHashMap instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      IdentityHashMap instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java
index 62b6073..efca74a 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -29,7 +30,8 @@
  * (uses reflection).
  */
 @SuppressWarnings("unchecked")
-public final class LinkedHashMap_CustomFieldSerializer {
+public final class LinkedHashMap_CustomFieldSerializer extends
+    CustomFieldSerializer<LinkedHashMap> {
 
   /**
    * We use an atomic reference to avoid having to synchronize. This is safe
@@ -126,4 +128,25 @@
     // Use a (possibly slower) technique that does not require reflection.
     return getAccessOrderNoReflection(instance);
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      LinkedHashMap instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public LinkedHashMap instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      LinkedHashMap instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/LinkedList_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/LinkedList_CustomFieldSerializer.java
index c1388a3..1e57dbf 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/LinkedList_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/LinkedList_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -24,7 +25,8 @@
 /**
  * Custom field serializer for {@link java.util.ArrayList}.
  */
-public final class LinkedList_CustomFieldSerializer {
+public final class LinkedList_CustomFieldSerializer extends
+    CustomFieldSerializer<LinkedList> {
 
   @SuppressWarnings("unchecked")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -37,4 +39,14 @@
       LinkedList instance) throws SerializationException {
     Collection_CustomFieldSerializerBase.serialize(streamWriter, instance);
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      LinkedList instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      LinkedList instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeMap_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeMap_CustomFieldSerializer.java
index ddc24f2..ea1ff62 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeMap_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeMap_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -26,7 +27,8 @@
  * Custom field serializer for {@link java.util.TreeMap}.
  */
 @SuppressWarnings("unchecked")
-public class TreeMap_CustomFieldSerializer {
+public class TreeMap_CustomFieldSerializer extends
+    CustomFieldSerializer<TreeMap> {
 
   /* for now, build it entry by entry. Can optimize later via bulk loading */
   public static void deserialize(SerializationStreamReader streamReader,
@@ -44,4 +46,25 @@
     streamWriter.writeObject(instance.comparator());
     Map_CustomFieldSerializerBase.serialize(streamWriter, instance);
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      TreeMap instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public TreeMap instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      TreeMap instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeSet_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeSet_CustomFieldSerializer.java
index f48f95e..e6458b8 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeSet_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeSet_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -26,7 +27,8 @@
  * Custom field serializer for {@link java.util.TreeMap}.
  */
 @SuppressWarnings("unchecked")
-public class TreeSet_CustomFieldSerializer {
+public class TreeSet_CustomFieldSerializer extends
+    CustomFieldSerializer<TreeSet> {
 
   /* for now, build it entry by entry. Can optimize later via bulk loading */
   public static void deserialize(SerializationStreamReader streamReader,
@@ -44,4 +46,25 @@
     streamWriter.writeObject(instance.comparator());
     Collection_CustomFieldSerializerBase.serialize(streamWriter, instance);
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      TreeSet instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public TreeSet instantiateInstance(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      TreeSet instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/util/Vector_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/util/Vector_CustomFieldSerializer.java
index 9e91bef..a887bd1 100644
--- a/user/src/com/google/gwt/user/client/rpc/core/java/util/Vector_CustomFieldSerializer.java
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/util/Vector_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -24,7 +25,8 @@
 /**
  * Custom field serializer for {@link java.util.Vector}.
  */
-public final class Vector_CustomFieldSerializer {
+public final class Vector_CustomFieldSerializer extends
+    CustomFieldSerializer<Vector> {
 
   @SuppressWarnings("unchecked")
   public static void deserialize(SerializationStreamReader streamReader,
@@ -37,4 +39,14 @@
       Vector instance) throws SerializationException {
     Collection_CustomFieldSerializerBase.serialize(streamWriter, instance);
   }
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      Vector instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      Vector instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }
diff --git a/user/src/com/google/gwt/user/server/rpc/impl/SerializabilityUtil.java b/user/src/com/google/gwt/user/server/rpc/impl/SerializabilityUtil.java
index 54d45eb..db212f3 100644
--- a/user/src/com/google/gwt/user/server/rpc/impl/SerializabilityUtil.java
+++ b/user/src/com/google/gwt/user/server/rpc/impl/SerializabilityUtil.java
@@ -16,6 +16,10 @@
 package com.google.gwt.user.server.rpc.impl;
 
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
+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.GwtTransient;
 import com.google.gwt.user.server.rpc.SerializationPolicy;
 
@@ -81,8 +85,36 @@
    */
   private static final Map<Class<?>, Class<?>> classCustomSerializerCache = new IdentityHashMap<Class<?>, Class<?>>();
 
+  /**
+   * Map of {@link Class} objects to singleton instances of that
+   * {@link CustomFieldSerializer}.
+   */
+  private static final Map<Class<?>, CustomFieldSerializer<?>>
+      CLASS_TO_SERIALIZER_INSTANCE =
+      new IdentityHashMap<Class<?>, CustomFieldSerializer<?>>();
+
   private static final String JRE_SERIALIZER_PACKAGE = "com.google.gwt.user.client.rpc.core";
 
+  /**
+   * A re-usable, non-functional {@link CustomFieldSerializer} for when the
+   * Custom Field Serializer does not implement the
+   * {@link CustomFieldSerializer} interface.
+   */
+  private static final CustomFieldSerializer NO_SUCH_SERIALIZER =
+      new CustomFieldSerializer<Object>() {
+        @Override
+        public void deserializeInstance(SerializationStreamReader
+            streamReader, Object instance) {
+          throw new AssertionError("This should never be called.");
+        }
+
+        @Override
+        public void serializeInstance(SerializationStreamWriter streamWriter,
+            Object instance) {
+          throw new AssertionError("This should never be called.");
+        }
+      };
+
   private static final Map<String, String> SERIALIZED_PRIMITIVE_TYPE_NAMES = new HashMap<String, String>();
 
   private static final Set<Class<?>> TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES = new HashSet<Class<?>>();
@@ -245,6 +277,53 @@
   }
 
   /**
+   * Loads a {@link CustomFieldSerializer} from a class that may implement that
+   * interface.
+   *
+   * @param customSerializerClass the Custom Field Serializer class
+   *
+   * @return an instance the class provided if it implements
+   *         {@link CustomFieldSerializer} or {@code null} if it does not
+   *
+   * @throws SerializationException if the load process encounters an
+   *         unexpected problem
+   */
+  static CustomFieldSerializer<?> loadCustomFieldSerializer(
+      final Class<?> customSerializerClass) throws SerializationException {
+    /**
+     * Note that neither reading or writing to the CLASS_TO_SERIALIZER_INSTANCE
+     * is synchronized for performance reasons.  This could cause get misses,
+     * put misses and the same CustomFieldSerializer to be instantiated more
+     * than once, but none of these are critical operations as
+     * CLASS_TO_SERIALIZER_INSTANCE is only a performance improving cache.
+     */
+    CustomFieldSerializer<?> customFieldSerializer =
+        CLASS_TO_SERIALIZER_INSTANCE.get(customSerializerClass);
+    if (customFieldSerializer == null) {
+      if (CustomFieldSerializer.class.isAssignableFrom(customSerializerClass)) {
+        try {
+          customFieldSerializer =
+              (CustomFieldSerializer) customSerializerClass.newInstance();
+        } catch (InstantiationException e) {
+          throw new SerializationException(e);
+
+        } catch (IllegalAccessException e) {
+          throw new SerializationException(e);
+        }
+      } else {
+        customFieldSerializer = NO_SUCH_SERIALIZER;
+      }
+      CLASS_TO_SERIALIZER_INSTANCE.put(customSerializerClass,
+          customFieldSerializer);
+    }
+    if (customFieldSerializer == NO_SUCH_SERIALIZER) {
+      return null;
+    } else {
+      return customFieldSerializer;
+    }
+  }
+
+  /**
    * This method treats arrays in a special way.
    */
   private static Class<?> computeHasCustomFieldSerializer(Class<?> instanceType) {
diff --git a/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamReader.java b/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamReader.java
index 3b5da63..b78efb7 100644
--- a/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamReader.java
+++ b/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamReader.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.server.rpc.impl;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader;
@@ -705,8 +706,16 @@
       InvocationTargetException, SerializationException, ClassNotFoundException {
 
     if (customSerializer != null) {
-      deserializeWithCustomFieldDeserializer(customSerializer, instanceClass,
-          instance);
+      @SuppressWarnings("unchecked")
+      CustomFieldSerializer<Object> customFieldSerializer =
+          (CustomFieldSerializer<Object>)
+              SerializabilityUtil.loadCustomFieldSerializer(customSerializer);
+      if (customFieldSerializer == null) {
+        deserializeWithCustomFieldDeserializer(customSerializer, instanceClass,
+            instance);
+      } else {
+        customFieldSerializer.deserializeInstance(this, instance);
+      }
     } else if (instanceClass.isArray()) {
       instance = deserializeArray(instanceClass, instance);
     } else if (instanceClass.isEnum()) {
@@ -876,12 +885,18 @@
       IllegalArgumentException, InvocationTargetException,
       NoSuchMethodException, SerializationException {
     if (customSerializer != null) {
-      for (Method method : customSerializer.getMethods()) {
-        if ("instantiate".equals(method.getName())) {
-          return method.invoke(null, this);
+      CustomFieldSerializer customFieldSerializer =
+          SerializabilityUtil.loadCustomFieldSerializer(customSerializer);
+      if (customFieldSerializer == null) {
+        for (Method method : customSerializer.getMethods()) {
+          if ("instantiate".equals(method.getName())) {
+            return method.invoke(null, this);
+          }
         }
+        // Ok to not have one.
+      } else if (customFieldSerializer.hasCustomInstantiateInstance()) {
+        return customFieldSerializer.instantiateInstance(this);
       }
-      // Ok to not have one.
     }
 
     if (instanceClass.isArray()) {
diff --git a/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamWriter.java b/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamWriter.java
index b129c9f..9cfd5b0 100644
--- a/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamWriter.java
+++ b/user/src/com/google/gwt/user/server/rpc/impl/ServerSerializationStreamWriter.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.server.rpc.impl;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter;
 import com.google.gwt.user.server.Base64Utils;
@@ -724,7 +725,16 @@
     Class<?> customSerializer = SerializabilityUtil.hasCustomFieldSerializer(instanceClass);
     if (customSerializer != null) {
       // Use custom field serializer
-      serializeWithCustomSerializer(customSerializer, instance, instanceClass);
+      @SuppressWarnings("unchecked")
+      CustomFieldSerializer<Object> customFieldSerializer =
+          (CustomFieldSerializer<Object>)
+              SerializabilityUtil.loadCustomFieldSerializer(customSerializer);
+      if (customFieldSerializer == null) {
+        serializeWithCustomSerializer(customSerializer, instance,
+            instanceClass);
+      } else {
+        customFieldSerializer.serializeInstance(this, instance);
+      }
     } else if (instanceClass.isArray()) {
       serializeArray(instanceClass, instance);
     } else if (instanceClass.isEnum()) {
diff --git a/user/super/com/google/gwt/user/translatable/com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java b/user/super/com/google/gwt/user/translatable/com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java
index eee075b..c093e8e 100644
--- a/user/super/com/google/gwt/user/translatable/com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java
+++ b/user/super/com/google/gwt/user/translatable/com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.core.java.util;
 
+import com.google.gwt.user.client.rpc.CustomFieldSerializer;
 import com.google.gwt.user.client.rpc.SerializationException;
 import com.google.gwt.user.client.rpc.SerializationStreamReader;
 import com.google.gwt.user.client.rpc.SerializationStreamWriter;
@@ -25,7 +26,8 @@
  * Custom field serializer for {@link java.util.LinkedHashMap}, which uses
  * JSNI.
  */
-public final class LinkedHashMap_CustomFieldSerializer {
+public final class LinkedHashMap_CustomFieldSerializer extends
+    CustomFieldSerializer<LinkedHashMap> {
 
   public static void deserialize(SerializationStreamReader streamReader,
       LinkedHashMap instance) throws SerializationException {
@@ -54,4 +56,25 @@
   private static native boolean getAccessOrder(LinkedHashMap instance) /*-{
     return instance.@java.util.LinkedHashMap::accessOrder;
   }-*/;
+
+  public void deserializeInstance(SerializationStreamReader streamReader,
+      LinkedHashMap instance) throws SerializationException {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public LinkedHashMap instantiateInstance(
+      SerializationStreamReader streamReader) throws SerializationException {
+    return instantiate(streamReader);
+  }
+
+  public void serializeInstance(SerializationStreamWriter streamWriter,
+      LinkedHashMap instance) throws SerializationException {
+    serialize(streamWriter, instance);
+  }
 }