You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by rv...@apache.org on 2015/04/28 23:40:53 UTC

[48/51] [partial] incubator-geode git commit: Init

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializer.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializer.java b/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializer.java
new file mode 100644
index 0000000..e677593
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializer.java
@@ -0,0 +1,3542 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Stack;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.RegionNotFoundException;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.DSCODE;
+import com.gemstone.gemfire.internal.HeapDataOutputStream;
+import com.gemstone.gemfire.internal.InternalDataSerializer;
+import com.gemstone.gemfire.internal.ObjToByteArraySerializer;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
+import com.gemstone.gemfire.pdx.PdxInstance;
+
+/**
+ * Provides static helper methods for reading and writing
+ * non-primitive data when working with a {@link DataSerializable}.
+ * For instance, classes that implement <code>DataSerializable</code>
+ * can use the <code>DataSerializer</code> in their
+ * <code>toData</code> and <code>fromData</code> methods:
+ *
+ * <!--
+ * The source code for the Employee class resides in
+ *         tests/com/examples/ds/Employee.java
+ * Please keep the below code snippet in sync with that file.
+ * -->
+ *
+ * <PRE>
+public class Employee implements DataSerializable {
+  private int id;
+  private String name;
+  private Date birthday;
+  private Company employer;
+
+  public void toData(DataOutput out) throws IOException {
+    out.writeInt(this.id);
+    out.writeUTF(this.name);
+    DataSerializer.writeDate(this.birthday, out);
+    DataSerializer.writeObject(this.employer, out);
+  }
+
+  public void fromData(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    this.id = in.readInt();
+    this.name = in.readUTF();
+    this.birthday = DataSerializer.readDate(in);
+    this.employer = (Company) DataSerializer.readObject(in);
+  }
+}
+
+ * </PRE>
+ *
+ * <P>
+ *
+ * Instances of <code>DataSerializer</code> are used to data serialize
+ * objects (such as instances of standard Java classes or third-party
+ * classes for which the source code is not available) that do not
+ * implement the <code>DataSerializable</code> interface.
+ *
+ * <P>
+ *
+ * The following <code>DataSerializer</code> data serializes instances
+ * of <code>Company</code>.  In order for the data serialization
+ * framework to consult this custom serializer, it must be {@linkplain
+ * #register(Class) registered} with the framework.
+ *
+ * <!--
+ * The source code for the CompanySerializer class resides in
+ *         tests/com/examples/ds/CompanySerializer.java
+ * Please keep the below code snippet in sync with that file.
+ * -->
+ *
+ * <PRE>
+public class CompanySerializer extends DataSerializer {
+
+  static {
+    DataSerializer.register(CompanySerializer.class);
+  }
+
+  &#47;**
+   * May be invoked reflectively if instances of Company are
+   * distributed to other VMs.
+   *&#47;
+  public CompanySerializer() {
+
+  }
+
+  public Class[] getSupportedClasses() {
+    return new Class[] { Company.class };
+  }
+  public int getId() {
+    return 42;
+  }
+
+  public boolean toData(Object o, DataOutput out)
+    throws IOException {
+    if (o instanceof Company) {
+      Company company = (Company) o;
+      out.writeUTF(company.getName());
+
+      // Let's assume that Address is java.io.Serializable
+      Address address = company.getAddress();
+      writeObject(address, out);
+      return true;
+
+    } else {
+      return false;
+    }
+  }
+
+  public Object fromData(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    String name = in.readUTF();
+    Address address = (Address) readObject(in);
+    return new Company(name, address);
+  }
+}
+ * </PRE>
+ *
+ * Just like {@link Instantiator}s, a <code>DataSerializer</code> may
+ * be sent to other members of the distributed system when it is
+ * {@linkplain #register(Class) registered}.  The data serialization
+ * framework does not require that a <code>DataSerializer</code> be
+ * {@link Serializable}, but it does require that it provide a
+ * {@linkplain #DataSerializer() zero-argument constructor}.
+ *
+ * @see #writeObject(Object, DataOutput)
+ * @see #readObject
+ *
+ * @author David Whitlock
+ * @since 3.5 */
+public abstract class DataSerializer {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  /** The eventId of this <code>DataSerializer</code> */
+  private EventID eventId;
+
+  /** The originator of this <code>DataSerializer</code> */
+  private ClientProxyMembershipID context;
+
+  protected static final boolean TRACE_SERIALIZABLE =
+    Boolean.getBoolean("DataSerializer.TRACE_SERIALIZABLE");
+
+  /* Used to prevent standard Java serialization when sending data to a non-Java client */
+  protected static final ThreadLocal<Boolean> DISALLOW_JAVA_SERIALIZATION = new ThreadLocal<Boolean>();
+
+  //////////////////////  Instance Fields  /////////////////////
+
+  //////////////////////  Static Methods  //////////////////////
+
+  /**
+   * Writes an instance of <code>Class</code> to a
+   * <code>DataOutput</code>.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readClass
+   */
+  public static void writeClass(Class<?> c, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Class {}", c);
+    }
+
+    if (c == null || c.isPrimitive()) {
+      InternalDataSerializer.writePrimitiveClass(c, out);
+    }
+    else {
+      // non-primitive classes have a second CLASS byte
+      // if readObject/writeObject is called:
+      // the first CLASS byte indicates it's a Class, the second
+      // one indicates it's a non-primitive Class
+      out.writeByte(DSCODE.CLASS);
+      String cname = c.getName();
+      cname = swizzleClassNameForWrite(cname);
+      writeString(cname, out);
+    }
+  }
+
+  /**
+   * Writes class name to a <code>DataOutput</code>. This method will handle a
+   * <code>null</code> value and not throw a <code>NullPointerException</code>.
+   * 
+   * @throws IOException
+   *           A problem occurs while writing to <code>out</code>
+   * 
+   * @see #readNonPrimitiveClassName(DataInput)
+   */
+  public static void writeNonPrimitiveClassName(String className, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Class name {}", className);
+    }
+
+    writeString(swizzleClassNameForWrite(className), out);
+  }
+
+  /**
+   * Reads an instance of <code>Class</code> from a
+   * <code>DataInput</code>.  The class will be loaded using the
+   * {@linkplain Thread#getContextClassLoader current content class
+   * loader}.
+   * The return value may be <code>null</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class cannot be loaded
+   */
+  public static Class<?> readClass(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    byte typeCode = in.readByte();
+    if (typeCode == DSCODE.CLASS) {
+      String className = readString(in);
+      className = swizzleClassNameForRead(className);
+      Class<?> c = InternalDataSerializer.getCachedClass(className); // fix for bug 41206
+      return c;
+    }
+    else {
+      return InternalDataSerializer.decodePrimitiveClass(typeCode);
+    }
+  }
+  
+  /**
+   * For backward compatibility we must swizzle the package of
+   * some classes that had to be moved when GemFire was open-
+   * sourced.  This preserves backward-compatibility.
+   * 
+   * @param name the fully qualified class name
+   * @return the name of the class in this implementation
+   */
+  private static String swizzleClassNameForRead(String name) {
+    String oldPackage = "com.gemstone.org.jgroups.stack.tcpserver";
+    String newPackage = "com.gemstone.gemfire.distributed.internal.tcpserver";
+    String result = name;
+    if (name.startsWith(oldPackage)) {
+      result = newPackage + name.substring(oldPackage.length());
+    }
+    return result;
+  }
+  
+  /**
+   * For backward compatibility we must swizzle the package of
+   * some classes that had to be moved when GemFire was open-
+   * sourced.  This preserves backward-compatibility.
+   * 
+   * @param name the fully qualified class name
+   * @return the name of the class in this implementation
+   */
+  private static String swizzleClassNameForWrite(String name) {
+    String oldPackage = "com.gemstone.org.jgroups.stack.tcpserver";
+    String newPackage = "com.gemstone.gemfire.distributed.internal.tcpserver";
+    String result = name;
+    if (name.startsWith(newPackage)) {
+      result = oldPackage + name.substring(newPackage.length());
+    }
+    return result;
+  }
+  
+  /**
+   * Reads name of an instance of <code>Class</code> from a
+   * <code>DataInput</code>.
+   * 
+   * The return value may be <code>null</code>.
+   * 
+   * @throws IOException
+   *           A problem occurs while reading from <code>in</code>
+   * @see #writeNonPrimitiveClassName(String, DataOutput)
+   */
+  public static String readNonPrimitiveClassName(DataInput in)
+      throws IOException {
+
+    InternalDataSerializer.checkIn(in);
+
+    return swizzleClassNameForRead(readString(in));
+  }
+
+  /**
+   * Writes an instance of Region. A Region is serialized as just a reference
+   * to a full path only. It will be recreated on the other end by calling
+   * {@link CacheFactory#getAnyInstance} and then calling
+   * <code>getRegion</code> on it.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   */
+  public static void writeRegion(Region<?,?> rgn, DataOutput out)
+  throws IOException {
+    writeString((rgn != null) ? rgn.getFullPath() : null, out);
+  }
+
+  /**
+   * Reads an instance of Region. A Region is serialized as a reference to a
+   * full path only. It is recreated on the other end by calling
+   * {@link CacheFactory#getAnyInstance} and then calling
+   * <code>getRegion</code> on it.
+   * The return value may be <code>null</code>.
+   *
+   * @param in the input stream
+   * @return the Region instance
+   * @throws com.gemstone.gemfire.cache.CacheClosedException if a cache has not been created or the only
+   * created one is closed.
+   * @throws RegionNotFoundException if there is no region by this name
+   * in the Cache
+   */
+  public static <K,V> Region<K,V> readRegion(DataInput in)
+  throws IOException, ClassNotFoundException {
+    String fullPath = readString(in);
+    Region<K,V> rgn = null;
+    if (fullPath != null) {
+      // use getExisting to fix bug 43151
+      rgn = ((Cache)GemFireCacheImpl.getExisting("Needed cache to find region.")).getRegion(fullPath);
+      if (rgn == null) {
+      throw new RegionNotFoundException(LocalizedStrings.DataSerializer_REGION_0_COULD_NOT_BE_FOUND_WHILE_READING_A_DATASERIALIZER_STREAM.toLocalizedString(fullPath));
+      }
+    }
+    return rgn;
+  }
+
+
+  /**
+   * Writes an instance of <code>Date</code> to a
+   * <code>DataOutput</code>.  Note that even though <code>date</code>
+   * may be an instance of a subclass of <code>Date</code>,
+   * <code>readDate</code> will always return an instance of
+   * <code>Date</code>, <B>not</B> an instance of the subclass.  To
+   * preserve the class type of <code>date</code>,\
+   * {@link #writeObject(Object, DataOutput)} should be used for data serialization.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readDate
+   */
+  public static void writeDate(Date date, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Date {}", date);
+    }
+
+    long v;
+    if (date == null) {
+      v = -1L;
+    } else {
+      v = date.getTime();
+      if (v == -1L) {
+        throw new IllegalArgumentException("Dates whose getTime returns -1 can not be DataSerialized.");
+      }
+    }
+    out.writeLong(v);
+  }
+
+  /**
+   * Reads an instance of <code>Date</code> from a
+   * <code>DataInput</code>.
+   * The return value may be <code>null</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Date readDate(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    long time = in.readLong();
+    Date date = null;
+    if (time != -1L) {
+      date = new Date(time);
+    }
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Date {}", date);
+    }
+
+    return date;
+  }
+
+  /**
+   * Writes an instance of <code>File</code> to a
+   * <code>DataOutput</code>.  Note that even though <code>file</code>
+   * may be an instance of a subclass of <code>File</code>,
+   * <code>readFile</code> will always return an instance of
+   * <code>File</code>, <B>not</B> an instance of the subclass.  To
+   * preserve the class type of <code>file</code>,
+   * {@link #writeObject(Object, DataOutput)} should be used for data serialization.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readFile
+   * @see File#getCanonicalPath
+   */
+  public static void writeFile(File file, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing File {}", file);
+    }
+
+    writeString((file != null) ? file.getCanonicalPath() : null, out);
+  }
+
+  /**
+   * Reads an instance of <code>File</code> from a
+   * <code>DataInput</code>.
+   * The return value may be <code>null</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static File readFile(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    String s = readString(in);
+    File file = null;
+    if (s != null) {
+      file = new File(s);
+    }
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read File {}", file);
+    }
+
+    return file;
+  }
+
+  /**
+   * Writes an instance of <code>InetAddress</code> to a
+   * <code>DataOutput</code>.  The <code>InetAddress</code> is data
+   * serialized by writing its {@link InetAddress#getAddress byte}
+   * representation to the <code>DataOutput</code>.  {@link
+   * #readInetAddress} converts the <code>byte</code> representation
+   * to an instance of <code>InetAddress</code> using {@link
+   * InetAddress#getAddress}.  As a result, if <code>address</code>
+   * is an instance of a user-defined subclass of
+   * <code>InetAddress</code> (that is, not an instance of one of the
+   * subclasses from the <code>java.net</code> package), its class
+   * will not be preserved.  In order to be able to read an instance
+   * of the user-defined class, {@link #writeObject(Object, DataOutput)} should be used.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readInetAddress
+   */
+  public static void writeInetAddress(InetAddress address,
+                                      DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing InetAddress {}", address);
+    }
+
+    writeByteArray((address != null) ? address.getAddress() : null, out);
+  }
+
+  /**
+   * Reads an instance of <code>InetAddress</code> from a
+   * <code>DataInput</code>.
+   * The return value may be <code>null</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *         or the address read from <code>in</code> is unknown
+   *
+   * @see InetAddress#getAddress
+   */
+  public static InetAddress readInetAddress(DataInput in)
+    throws IOException {
+
+    InternalDataSerializer.checkIn(in);
+
+    byte[] address = readByteArray(in);
+    if (address == null) {
+      return null;
+    }
+
+    try {
+      InetAddress addr = InetAddress.getByAddress(address);
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read InetAddress {}", addr);
+      }
+      return addr;
+    } catch (UnknownHostException ex) {
+      IOException ex2 = new IOException(LocalizedStrings.DataSerializer_WHILE_READING_AN_INETADDRESS.toLocalizedString());
+      ex2.initCause(ex);
+      throw ex2;
+    }
+
+  }
+
+  /**
+   * Writes an instance of <code>String</code> to a
+   * <code>DataOutput</code>.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   * <p>As of 5.7 strings longer than 0xFFFF can be serialized.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readString
+   */
+  public static void writeString(String value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    final boolean isDebugEnabled = logger.isTraceEnabled(LogMarker.SERIALIZER);
+    if (isDebugEnabled) {
+      logger.trace(LogMarker.SERIALIZER, "Writing String \"{}\"", value);
+    }
+
+    if (value == null) {
+      if (isDebugEnabled) {
+        logger.trace(LogMarker.SERIALIZER, "Writing NULL_STRING");
+      }
+      out.writeByte(DSCODE.NULL_STRING);
+
+    } else {
+      // [bruce] writeUTF is expensive - it creates a char[] to fetch
+      // the string's contents, iterates over the array to compute the
+      // encoded length, creates a byte[] to hold the encoded bytes,
+      // iterates over the char[] again to create the encode bytes,
+      // then writes the bytes.  Since we usually deal with ISO-8859-1
+      // strings, we can accelerate this by accessing chars directly
+      // with charAt and fill a single-byte buffer.  If we run into
+      // a multibyte char, we revert to using writeUTF()
+      int len = value.length();
+      int utfLen = len; // added for bug 40932
+      for (int i=0; i<len; i++) {
+        char c = value.charAt(i);
+        if ((c <= 0x007F) && (c >= 0x0001)) {
+          // nothing needed
+        } else if (c > 0x07FF) {
+          utfLen += 2;
+        } else {
+          utfLen += 1;
+        }
+        // Note we no longer have an early out when we detect the first
+        // non-ascii char because we need to compute the utfLen for bug 40932.
+        // This is not a performance problem because most strings are ascii
+        // and they never did the early out.
+      }
+      boolean writeUTF = utfLen > len;
+      if (writeUTF) {
+        if (utfLen > 0xFFFF) {
+          if (isDebugEnabled) {
+            logger.trace(LogMarker.SERIALIZER, "Writing utf HUGE_STRING of len={}", len);
+          }
+          out.writeByte(DSCODE.HUGE_STRING);
+          out.writeInt(len);
+          out.writeChars(value);
+        } else {
+          if (isDebugEnabled) {
+            logger.trace(LogMarker.SERIALIZER, "Writing utf STRING of len={}", len);
+          }
+          out.writeByte(DSCODE.STRING);
+          out.writeUTF(value);
+        }
+      }
+      else {
+        if (len > 0xFFFF) {
+          if (isDebugEnabled) {
+            logger.trace(LogMarker.SERIALIZER, "Writing HUGE_STRING_BYTES of len={}", len);
+          }
+          out.writeByte(DSCODE.HUGE_STRING_BYTES);
+          out.writeInt(len);
+          out.writeBytes(value);
+        } else {
+          if (isDebugEnabled) {
+            logger.trace(LogMarker.SERIALIZER, "Writing STRING_BYTES of len={}", len);
+          }
+          out.writeByte(DSCODE.STRING_BYTES);
+          out.writeShort(len);
+          out.writeBytes(value);
+        }
+      }
+    }
+  }
+
+  /**
+   * Reads an instance of <code>String</code> from a
+   * <code>DataInput</code>.  The return value may be
+   * <code>null</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeString
+   */
+  public static String readString(DataInput in) throws IOException {
+    return InternalDataSerializer.readString(in, in.readByte());
+  }
+
+  /**
+   * Writes an instance of <code>Boolean</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readBoolean
+   */
+  public static void writeBoolean(Boolean value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Boolean {}", value);
+    }
+
+    out.writeBoolean(value.booleanValue());
+  }
+
+  /**
+   * Reads an instance of <code>Boolean</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Boolean readBoolean(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Boolean value = Boolean.valueOf(in.readBoolean());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Boolean {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Character</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readCharacter
+   */
+  public static void writeCharacter(Character value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Character {}", value);
+    }
+
+    out.writeChar(value.charValue());
+  }
+
+  /**
+   * Reads an instance of <code>Character</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Character readCharacter(DataInput in)
+    throws IOException {
+
+    InternalDataSerializer.checkIn(in);
+
+    Character value = Character.valueOf(in.readChar());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Character {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Byte</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readByte
+   */
+  public static void writeByte(Byte value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Byte {}", value);
+    }
+
+    out.writeByte(value.byteValue());
+  }
+
+  /**
+   * Reads an instance of <code>Byte</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Byte readByte(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Byte value = Byte.valueOf(in.readByte());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Byte {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Short</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readShort
+   */
+  public static void writeShort(Short value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Short {}", value);
+    }
+
+    out.writeShort(value.shortValue());
+  }
+
+  /**
+   * Reads an instance of <code>Short</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Short readShort(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Short value = Short.valueOf(in.readShort());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Short {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Integer</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readInteger
+   */
+  public static void writeInteger(Integer value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Integer {}", value);
+    }
+
+    out.writeInt(value.intValue());
+  }
+
+  /**
+   * Reads an instance of <code>Integer</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Integer readInteger(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Integer value = Integer.valueOf(in.readInt());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Integer {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Long</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readLong
+   */
+  public static void writeLong(Long value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Long {}", value);
+    }
+
+    out.writeLong(value.longValue());
+  }
+
+  /**
+   * Reads an instance of <code>Long</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Long readLong(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Long value = Long.valueOf(in.readLong());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Long {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Float</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readFloat
+   */
+  public static void writeFloat(Float value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Float {}", value);
+    }
+
+    out.writeFloat(value.floatValue());
+  }
+
+  /**
+   * Reads an instance of <code>Float</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Float readFloat(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Float value = Float.valueOf(in.readFloat());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Float {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Double</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readDouble
+   */
+  public static void writeDouble(Double value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Double {}", value);
+    }
+
+    out.writeDouble(value.doubleValue());
+  }
+
+  /**
+   * Reads an instance of <code>Double</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Double readDouble(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Double value = Double.valueOf(in.readDouble());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Double {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>boolean</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeBoolean
+   * @since 5.1
+   */
+  public static void writePrimitiveBoolean(boolean value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Boolean {}", value);
+    }
+
+    out.writeBoolean(value);
+  }
+
+  /**
+   * Reads a primitive <code>boolean</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readBoolean
+   * @since 5.1
+   */
+  public static boolean readPrimitiveBoolean(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    boolean value = in.readBoolean();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Boolean {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>byte</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeByte
+   * @since 5.1
+   */
+  public static void writePrimitiveByte(byte value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Byte {}", value);
+    }
+
+    out.writeByte(value);
+  }
+
+  /**
+   * Reads a primitive <code>byte</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readByte
+   * @since 5.1
+   */
+  public static byte readPrimitiveByte(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    byte value = in.readByte();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Byte {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive  <code>char</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeChar
+   * @since 5.1
+   */
+  public static void writePrimitiveChar(char value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Char {}", value);
+    }
+
+    out.writeChar(value);
+  }
+
+  /**
+   * Reads a primitive <code>char</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readChar
+   * @since 5.1
+   */
+  public static char readPrimitiveChar(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    char value = in.readChar();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Char {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>short</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeShort
+   * @since 5.1
+   */
+  public static void writePrimitiveShort(short value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Short {}", value);
+    }
+
+    out.writeShort(value);
+  }
+
+  /**
+   * Reads a primitive <code>short</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readShort
+   * @since 5.1
+   */
+  public static short readPrimitiveShort(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    short value = in.readShort();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Short {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>int</code> as an unsigned byte to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeByte
+   * @see DataInput#readUnsignedByte
+   * @since 5.1
+   */
+  public static void writeUnsignedByte(int value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Unsigned Byte {}", value);
+    }
+
+    out.writeByte(value);
+  }
+
+  /**
+   * Reads a primitive <code>int</code> as an unsigned byte from a
+   * <code>DataInput</code> using {@link DataInput#readUnsignedByte}.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @since 5.1
+   */
+  public static int readUnsignedByte(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    int value = in.readUnsignedByte();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Unsigned Byte {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>int</code> as an unsigned short to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeShort
+   * @see DataInput#readUnsignedShort
+   * @since 5.1
+   */
+  public static void writeUnsignedShort(int value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Unsigned Short {}", value);
+    }
+
+    out.writeShort(value);
+  }
+
+  /**
+   * Reads a primitive <code>int</code> as an unsigned short from a
+   * <code>DataInput</code> using {@link DataInput#readUnsignedShort}.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @since 5.1
+   */
+  public static int readUnsignedShort(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    int value = in.readUnsignedShort();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Unsigned Short {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>int</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeInt
+   */
+  public static void writePrimitiveInt(int value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Integer {}", value);
+    }
+
+    out.writeInt(value);
+  }
+
+  /**
+   * Reads a primitive <code>int</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readInt
+   * @since 5.1
+   */
+  public static int readPrimitiveInt(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    int value = in.readInt();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Integer {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>long</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeLong
+   * @since 5.1
+   */
+  public static void writePrimitiveLong(long value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Long {}", value);
+    }
+
+    out.writeLong(value);
+  }
+
+  /**
+   * Reads a primitive <code>long</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readLong
+   * @since 5.1
+   */
+  public static long readPrimitiveLong(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    long value = in.readLong();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Long {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>float</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeFloat
+   * @since 5.1
+   */
+  public static void writePrimitiveFloat(float value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Float {}", value);
+    }
+
+    out.writeFloat(value);
+  }
+
+  /**
+   * Reads a primitive <code>float</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readFloat
+   * @since 5.1
+   */
+  public static float readPrimitiveFloat(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    float value = in.readFloat();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Float {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primtive <code>double</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeDouble
+   * @since 5.1
+   */
+  public static void writePrimitiveDouble(double value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Double {}", value);
+    }
+
+    out.writeDouble(value);
+  }
+
+  /**
+   * Reads a primitive <code>double</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readDouble
+   * @since 5.1
+   */
+  public static double readPrimitiveDouble(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    double value = in.readDouble();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Double {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an array of <code>byte</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readByteArray
+   */
+  public static void writeByteArray(byte[] array, DataOutput out)
+    throws IOException {
+    int len = 0;
+    if (array != null) {
+      len = array.length;
+    }
+    writeByteArray(array, len, out);
+  }
+
+  /**
+   * Writes the first <code>len</code> elements
+   * of an array of <code>byte</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @param len the actual number of entries to write. If len is greater
+   * than then length of the array then the entire array is written.
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readByteArray
+   */
+  public static void writeByteArray(byte[] array, int len, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length = len; // to avoid warnings about parameter assignment
+    
+    if (array == null) {
+      length = -1;
+    } else {
+      if (length > array.length) {
+        length = array.length;
+      }
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing byte array of length {}", length);
+    }
+    if (length > 0) {
+      out.write(array, 0, length);
+    }
+  }
+  /**
+   * Serialize the given object <code>obj</code> into a byte array
+   * using {@link #writeObject(Object, DataOutput)} and then writes the byte array
+   * to the given data output <code>out</code> in the same format
+   * {@link #writeByteArray(byte[], DataOutput)} does.
+   * This method will serialize a
+   * <code>null</code> obj and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @param obj the object to serialize and write
+   * @param out the data output to write the byte array to
+   * @throws IllegalArgumentException
+   *         if a problem occurs while serialize <code>obj</code>
+   * @throws IOException
+   *         if a problem occurs while writing to <code>out</code>
+   *
+   * @see #readByteArray
+   * @since 5.0.2
+   */
+  public static void writeObjectAsByteArray(Object obj, DataOutput out)
+    throws IOException {
+    Object object = obj;
+    if (obj instanceof CachedDeserializable) {
+      object = ((CachedDeserializable) obj).getSerializedValue();
+    }
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      if (object == null) {
+        logger.trace(LogMarker.SERIALIZER, "writeObjectAsByteArray null");
+      } else {
+        logger.trace(LogMarker.SERIALIZER, "writeObjectAsByteArray obj.getClass={}", object.getClass());
+      }
+    }
+    if (object instanceof byte[] || object == null) {
+      writeByteArray((byte[])object, out);
+    } else if (out instanceof ObjToByteArraySerializer) {
+      ((ObjToByteArraySerializer)out).writeAsSerializedByteArray(object);
+    } else {
+      HeapDataOutputStream hdos;
+      if (object instanceof HeapDataOutputStream) {
+        hdos = (HeapDataOutputStream)object;
+      } else {
+        Version v = InternalDataSerializer.getVersionForDataStreamOrNull(out);
+        if (v == null) {
+          v = Version.CURRENT;
+        }
+        hdos = new HeapDataOutputStream(v);
+        try {
+          DataSerializer.writeObject(object, hdos);
+        } catch (IOException e) {
+          RuntimeException e2 = new IllegalArgumentException(LocalizedStrings.DataSerializer_PROBELM_WHILE_SERIALIZING.toLocalizedString());
+          e2.initCause(e);
+          throw e2;
+        }
+      }
+      InternalDataSerializer.writeArrayLength(hdos.size(), out);
+      hdos.sendTo(out);
+    }
+  }
+
+  /**
+   * Reads an array of <code>byte</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeByteArray(byte[], DataOutput)
+   */
+  public static byte[] readByteArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        byte[] array = new byte[length];
+        in.readFully(array, 0, length);
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read byte array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>String</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readStringArray
+   * @see #writeString
+   */
+  public static void writeStringArray(String[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing String array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        writeString(array[i], out);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>String</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeStringArray
+   */
+  public static String[] readStringArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        String[] array = new String[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = readString(in);
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read String array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>short</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readShortArray
+   */
+  public static void writeShortArray(short[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing short array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeShort(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>short</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeShortArray
+   */
+  public static short[] readShortArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        short[] array = new short[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = in.readShort();
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read short array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>char</code>s to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readCharArray
+   * @since 5.7
+   */
+  public static void writeCharArray(char[] array, DataOutput out)
+      throws IOException {
+
+    InternalDataSerializer.writeCharArray(array, array != null ? array.length
+        : -1, out);
+  }
+
+  /**
+   * Reads an array of <code>char</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeCharArray
+   * @since 5.7 
+   */
+  public static char[] readCharArray(DataInput in)
+    throws IOException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int length = InternalDataSerializer.readArrayLength(in);
+    if (length == -1) {
+      return null;
+    } else {
+      char[] array = new char[length];
+      for (int i = 0; i < length; i++) {
+        array[i] = in.readChar();
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read char array of length {}", length);
+      }
+
+      return array;
+    }
+  }
+  /**
+   * Writes an array of <code>boolean</code>s to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readBooleanArray
+   * @since 5.7
+   */
+  public static void writeBooleanArray(boolean[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing boolean array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeBoolean(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>boolean</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeBooleanArray
+   * @since 5.7
+   */
+  public static boolean[] readBooleanArray(DataInput in)
+    throws IOException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int length = InternalDataSerializer.readArrayLength(in);
+    if (length == -1) {
+      return null;
+    } else {
+      boolean[] array = new boolean[length];
+      for (int i = 0; i < length; i++) {
+        array[i] = in.readBoolean();
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read boolean array of length {}", length);
+      }
+
+      return array;
+    }
+  }
+  /**
+   * Writes an <code>int</code> array to a <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readIntArray
+   */
+  public static void writeIntArray(int[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing int array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeInt(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an <code>int</code> array from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeIntArray
+   */
+  public static int[] readIntArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        int[] array = new int[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = in.readInt();
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read int array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>long</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readLongArray
+   */
+  public static void writeLongArray(long[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing long array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeLong(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>long</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeLongArray
+   */
+  public static long[] readLongArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        long[] array = new long[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = in.readLong();
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read long array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>float</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readFloatArray
+   */
+  public static void writeFloatArray(float[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing float array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeFloat(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>float</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeFloatArray
+   */
+  public static float[] readFloatArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        float[] array = new float[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = in.readFloat();
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read float array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>double</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readDoubleArray
+   */
+  public static void writeDoubleArray(double[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing double array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeDouble(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>double</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeDoubleArray
+   */
+  public static double[] readDoubleArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        double[] array = new double[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = in.readDouble();
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read double array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>Object</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readObjectArray
+   * @see #writeObject(Object, DataOutput)
+   */
+  public static void writeObjectArray(Object[] array, DataOutput out)
+    throws IOException {
+    InternalDataSerializer.writeObjectArray(array, out, false);
+  }
+  
+  /**
+   * Reads an array of <code>Object</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeObjectArray
+   * @see #readObject
+   */
+  public static Object[] readObjectArray(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        Class<?> c = null;
+        byte typeCode = in.readByte();
+        String typeString = null;
+        if (typeCode == DSCODE.CLASS) {
+          typeString = readString(in);
+        }
+        
+        GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+        boolean lookForPdxInstance = false;
+        ClassNotFoundException cnfEx = null;
+        if (typeCode == DSCODE.CLASS
+            && cache != null && cache.getPdxReadSerializedByAnyGemFireServices()) {
+          try {
+            c = InternalDataSerializer.getCachedClass(typeString);
+            lookForPdxInstance = true;
+          } catch (ClassNotFoundException ignore) {
+            c = Object.class;
+            cnfEx = ignore;
+          }
+        } else {
+          if (typeCode == DSCODE.CLASS) {
+            c = InternalDataSerializer.getCachedClass(typeString);
+          } else {
+            c = InternalDataSerializer.decodePrimitiveClass(typeCode);
+          }
+        }
+        Object o = null;
+        if (length > 0) {
+          o = readObject(in);
+          if (lookForPdxInstance && o instanceof PdxInstance) {
+            lookForPdxInstance = false;
+            c = Object.class;
+          }
+        }
+        Object[] array = (Object[]) Array.newInstance(c, length);
+        if (length > 0) {
+          array[0] = o;
+        }
+        for (int i = 1; i < length; i++) {
+          o = readObject(in);
+          if (lookForPdxInstance && o instanceof PdxInstance) {
+            // create an Object[] and copy all the entries we already did into it
+            lookForPdxInstance = false;
+            c = Object.class;
+            Object[] newArray = (Object[])Array.newInstance(c, length);
+            System.arraycopy(array, 0, newArray, 0, i);
+            array = newArray;
+          }
+          array[i] = o;
+        }
+        if (lookForPdxInstance && cnfEx != null && length > 0) {
+          // We have a non-empty array and didn't find any
+          // PdxInstances in it. So we should have been able
+          // to load the element type.
+          // Note that empty arrays in this case will deserialize
+          // as an Object[] since we can't tell if the element
+          // type is a pdx one.
+          throw cnfEx;
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read Object array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+  
+  /**
+   * Writes an array of <tt>byte[]</tt> to a <tt>DataOutput</tt>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <tt>out</tt>.
+   *
+   */
+  public static void writeArrayOfByteArrays(byte[][] array, DataOutput out)
+  throws IOException {    
+    
+    InternalDataSerializer.checkOut(out);
+    int length;
+    if (array == null) {
+      length = -1;
+    }
+    else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing byte[][] of length {}", length);
+    }
+    if (length >= 0) {
+      for (int i = 0; i < length; i++) {
+        writeByteArray(array[i], out);
+      }
+    }
+  }
+  
+  /**
+   * Reads an array of <code>byte[]</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static byte[][] readArrayOfByteArrays(DataInput in)
+  throws IOException, ClassNotFoundException {
+    
+    InternalDataSerializer.checkIn(in);
+    
+    int length = InternalDataSerializer.readArrayLength(in);
+    if (length == -1) {
+      return null;
+    } else {
+      byte[][] array = new byte[length][];
+      for (int i = 0; i < length; i++) {
+        array[i] = readByteArray(in);
+      }
+      
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read byte[][] of length {}", length);
+      }
+      
+      return array;
+    }
+  }
+  
+  
+  /**
+   * Writes an <code>ArrayList</code> to a <code>DataOutput</code>.
+   * Note that even though <code>list</code> may be an instance of a
+   * subclass of <code>ArrayList</code>, <code>readArrayList</code>
+   * will always return an instance of <code>ArrayList</code>,
+   * <B>not</B> an instance of the subclass.  To preserve the class
+   * type of <code>list</code>, {@link #writeObject(Object, DataOutput)} should be used
+   * for data serialization.
+   * This method will serialize a
+   * <code>null</code> list and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readArrayList
+   */
+  public static void writeArrayList(ArrayList<?> list, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (list == null) {
+      size = -1;
+    } else {
+      size = list.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing ArrayList with {} elements: {}", size, list);
+    }
+    if (size > 0) {
+      for (int i=0; i < size; i++) {
+        writeObject(list.get(i), out);
+      }
+    }
+  }
+  
+  
+
+  /**
+   * Reads an <code>ArrayList</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>ArrayList</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeArrayList
+   */
+  public static <E> ArrayList<E> readArrayList(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      ArrayList<E> list = new ArrayList<E>(size);
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        list.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read ArrayList with {} elements: {}", size, list);
+      }
+
+      return list;
+    }
+  }
+
+  /**
+   * Writes an <code>Vector</code> to a <code>DataOutput</code>.
+   * Note that even though <code>list</code> may be an instance of a
+   * subclass of <code>Vector</code>, <code>readVector</code>
+   * will always return an instance of <code>Vector</code>,
+   * <B>not</B> an instance of the subclass.  To preserve the class
+   * type of <code>list</code>, {@link #writeObject(Object, DataOutput)} should be used
+   * for data serialization.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readVector
+   * @since 5.7
+   */
+  public static void writeVector(Vector<?> list, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (list == null) {
+      size = -1;
+    } else {
+      size = list.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Vector with {} elements: {}", size, list);
+    }
+    if (size > 0) {
+      for (int i=0; i < size; i++) {
+        writeObject(list.get(i), out);
+      }
+    }
+  }
+
+  /**
+   * Reads an <code>Vector</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>Vector</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeVector
+   * @since 5.7
+   */
+  public static <E> Vector<E> readVector(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      Vector<E> list = new Vector<E>(size);
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        list.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read Vector with {} elements: {}", size, list);
+      }
+
+      return list;
+    }
+  }
+
+  /**
+   * Writes an <code>Stack</code> to a <code>DataOutput</code>.
+   * Note that even though <code>list</code> may be an instance of a
+   * subclass of <code>Stack</code>, <code>readStack</code>
+   * will always return an instance of <code>Stack</code>,
+   * <B>not</B> an instance of the subclass.  To preserve the class
+   * type of <code>list</code>, {@link #writeObject(Object, DataOutput)} should be used
+   * for data serialization.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readStack
+   * @since 5.7
+   */
+  public static void writeStack(Stack<?> list, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (list == null) {
+      size = -1;
+    } else {
+      size = list.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Stack with {} elements: {}", size, list);
+    }
+    if (size > 0) {
+      for (int i=0; i < size; i++) {
+        writeObject(list.get(i), out);
+      }
+    }
+  }
+
+  /**
+   * Reads an <code>Stack</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>Stack</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeStack
+   * @since 5.7
+   */
+  public static <E> Stack<E> readStack(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      Stack<E> list = new Stack<E>();
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        list.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read Stack with {} elements: {}", size, list);
+      }
+
+      return list;
+    }
+  }
+
+  /**
+   * Writes an <code>LinkedList</code> to a <code>DataOutput</code>.
+   * Note that even though <code>list</code> may be an instance of a
+   * subclass of <code>LinkedList</code>, <code>readLinkedList</code>
+   * will always return an instance of <code>LinkedList</code>,
+   * <B>not</B> an instance of the subclass.  To preserve the class
+   * type of <code>list</code>, {@link #writeObject(Object, DataOutput)} should be used
+   * for data serialization.
+   * This method will serialize a
+   * <code>null</code> list and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readLinkedList
+   */
+  public static void writeLinkedList(LinkedList<?> list, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (list == null) {
+      size = -1;
+    } else {
+      size = list.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing LinkedList with {} elements: {}", size, list);
+    }
+    if (size > 0) {
+      for (Object e: list) {
+        writeObject(e, out);
+      }
+    }
+  }
+
+  /**
+   * Reads an <code>LinkedList</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>LinkedList</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeLinkedList
+   */
+  public static <E> LinkedList<E> readLinkedList(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      LinkedList<E> list = new LinkedList<E>();
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        list.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read LinkedList with {} elements: {}", size, list);
+      }
+
+      return list;
+    }
+  }
+
+  /**
+   * Writes a <code>HashSet</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>set</code> may be an instance of a
+   * subclass of <code>HashSet</code>, <code>readHashSet</code> will
+   * always return an instance of <code>HashSet</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>set</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   * This method will serialize a
+   * <code>null</code> set and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readHashSet
+   */
+  public static void writeHashSet(HashSet<?> set, DataOutput out)
+    throws IOException {
+    InternalDataSerializer.writeSet(set, out);
+  }
+
+  /**
+   * Reads a <code>HashSet</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>HashSet</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeHashSet
+   */
+  public static <E> HashSet<E> readHashSet(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      HashSet<E> set = new HashSet<E>(size);
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        set.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read HashSet with {} elements: {}", size, set);
+      }
+
+      return set;
+    }
+  }
+
+  /**
+   * Writes a <code>LinkedHashSet</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>set</code> may be an instance of a
+   * subclass of <code>LinkedHashSet</code>, <code>readLinkedHashSet</code> will
+   * always return an instance of <code>LinkedHashSet</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>set</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readLinkedHashSet
+   * @since 5.7
+   */
+  public static void writeLinkedHashSet(LinkedHashSet<?> set, DataOutput out)
+    throws IOException {
+    InternalDataSerializer.writeSet(set, out);
+  }
+
+  /**
+   * Reads a <code>LinkedHashSet</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>LinkedHashSet</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeLinkedHashSet
+   * @since 5.7
+   */
+  public static <E> LinkedHashSet<E> readLinkedHashSet(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      LinkedHashSet<E> set = new LinkedHashSet<E>(size);
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        set.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read LinkedHashSet with {} elements: {}", size, set);
+      }
+
+      return set;
+    }
+  }
+
+  /**
+   * Writes a <code>HashMap</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>map</code> may be an instance of a
+   * subclass of <code>HashMap</code>, <code>readHashMap</code> will
+   * always return an instance of <code>HashMap</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>map</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   * This method will serialize a
+   * <code>null</code> map and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readHashMap
+   */
+  public static void writeHashMap(HashMap<?,?> map, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (map == null) {
+      size = -1;
+    } else {
+      size = map.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing HashMap with {} elements: {}", size, map);
+    }
+    if (size > 0) {
+      for (Map.Entry<?,?> entry: map.entrySet()) {
+        writeObject(entry.getKey(), out);
+        writeObject(entry.getValue(), out);
+      }
+    }
+  }
+
+  /**
+   * Reads a <code>HashMap</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>HashMap</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeHashMap
+   */
+  public static <K,V> HashMap<K,V> readHashMap(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      HashMap<K,V> map = new HashMap<K,V>(size);
+      for (int i = 0; i < size; i++) {
+        K key = DataSerializer.<K>readObject(in);
+        V value = DataSerializer.<V>readObject(in);
+        map.put(key, value);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read HashMap with {} elements: {}", size, map);
+      }
+
+      return map;
+    }
+  }
+
+  /**
+   * Writes a <code>IdentityHashMap</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>map</code> may be an instance of a
+   * subclass of <code>IdentityHashMap</code>, <code>readIdentityHashMap</code> will
+   * always return an instance of <code>IdentityHashMap</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>map</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readIdentityHashMap
+   */
+  public static void writeIdentityHashMap(IdentityHashMap<?,?> map, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (map == null) {
+      size = -1;
+    } else {
+      size = map.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing IdentityHashMap with {} elements: {}", size, map);
+    }
+    if (size > 0) {
+      for (Map.Entry<?,?> entry: map.entrySet()){
+        writeObject(entry.getKey(), out);
+        writeObject(entry.getValue(), out);
+      }
+    }
+  }
+
+  /**
+   * Reads a <code>IdentityHashMap</code> from a <code>DataInput</code>.
+   * Note that key identity is not preserved unless the keys belong to a class
+   * whose serialization preserves identity.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>IdentityHashMap</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeIdentityHashMap
+   */
+  public static <K,V> IdentityHashMap<K,V> readIdentityHashMap(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      IdentityHashMap<K,V> map = new IdentityHashMap<K,V>(size);
+      for (int i = 0; i < size; i++) {
+        K key = DataSerializer.<K>readObject(in);
+        V value = DataSerializer.<V>readObject(in);
+        map.put(key, value);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read IdentityHashMap with {} elements: {}", size, map);
+      }
+
+      return map;
+    }
+  }
+
+  /**
+   * Writes a <code>ConcurrentHashMap</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>map</code> may be an instance of a
+   * subclass of <code>ConcurrentHashMap</code>, <code>readConcurrentHashMap</code> will
+   * always return an instance of <code>ConcurrentHashMap</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>map</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   * <P>At this time if {@link #writeObject(Object, DataOutput)} is called with an instance
+   * of ConcurrentHashMap then it will be serialized with normal java.io Serialization. So
+   * if you want the keys and values of a ConcurrentHashMap to take advantage of GemFire serialization
+   * it must be serialized with this method.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readConcurrentHashMap
+   * @since 6.6
+   */
+  public static void writeConcurrentHashMap(ConcurrentHashMap<?,?> map, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    Collection<Map.Entry<?,?>> entrySnapshot = null;
+    if (map == null) {
+      size = -1;
+    } else {
+      // take a snapshot to fix bug 44562
+      entrySnapshot = new ArrayList<Map.Entry<?,?>>(map.entrySet());
+      size = entrySnapshot.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing ConcurrentHashMap with {} elements: {}", size, entrySnapshot);
+    }
+    if (size > 0) {
+      for (Map.Entry<?,?> entry: entrySnapshot) {
+        writeObject(entry.getKey(), out);
+        writeObject(entry.getValue(), out);
+      }
+    }
+  }
+
+  /**
+   * Reads a <code>ConcurrentHashMap</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>ConcurrentHashMap</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeConcurrentHashMap
+   * @since 6.6
+   */
+  public static <K,V> ConcurrentHashMap<K,V> readConcurrentHashMap(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      ConcurrentHashMap<K,V> map = new ConcurrentHashMap<K,V>(size);
+      for (int i = 0; i < size; i++) {
+        K key = DataSerializer.<K>readObject(in);
+        V value = DataSerializer.<V>readObject(in);
+        map.put(key, value);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read ConcurrentHashMap with {} elements: {}", size, map);
+      }
+
+      return map;
+    }
+  }
+
+  /**
+   * Writes a <code>Hashtable</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>map</code> may be an instance of a
+   * subclass of <code>Hashtable</code>, <code>readHashtable</code> will
+   * always return an instance of <code>Hashtable</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>map</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readHashtable
+   * @since 5.7
+   */
+  public static void writeHashtable(Hashtable<?,?> map, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (map == null) {
+      size = -1;
+    } else {
+      size = map.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Hashtable with {} elements: {}", size, map);
+    }
+    if (size > 0) {
+      for (Map.Entry<?,?> entry: map.entrySet()) {
+        writeObject(entry.getKey(), out);
+        writeObject(entry.getValue(), out);
+      }
+    }
+  }
+
+  /**
+   * Reads a <code>Hashtable</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>Hashtable</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeHashtable
+   * @since 5.7
+   */
+  public static <K,V> Hashtable<K,V> readHashtable(DataInput in)

<TRUNCATED>