Index: src/test/org/apache/lucene/index/DocHelper.java
===================================================================
--- src/test/org/apache/lucene/index/DocHelper.java	(revision 723418)
+++ src/test/org/apache/lucene/index/DocHelper.java	(working copy)
@@ -30,7 +30,7 @@
 import org.apache.lucene.search.Similarity;
 import org.apache.lucene.store.Directory;
 
-class DocHelper {
+public class DocHelper {
   public static final String FIELD_1_TEXT = "field one text";
   public static final String TEXT_FIELD_1_KEY = "textField1";
   public static Field textField1 = new Field(TEXT_FIELD_1_KEY, FIELD_1_TEXT,
Index: src/test/org/apache/lucene/util/TestSerialization.java
===================================================================
--- src/test/org/apache/lucene/util/TestSerialization.java	(revision 0)
+++ src/test/org/apache/lucene/util/TestSerialization.java	(revision 0)
@@ -0,0 +1,70 @@
+package org.apache.lucene.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.DocHelper;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.TermQuery;
+
+public class TestSerialization extends LuceneTestCase
+{
+  public static File tempDir = new File(System.getProperty("java.io.tmpdir"));
+  
+  /**
+   * Term uses Externalization
+   * @throws IOException
+   */
+  public void testSerializeTerm() throws Exception {
+    File termFile = new File(tempDir, "term.obj");
+    FileOutputStream fileOut = new FileOutputStream(termFile);
+    ObjectOutputStream objOut = new ObjectOutputStream(fileOut);
+    objOut.writeObject(new Term("date", "01/01/2001"));
+    objOut.close();
+    
+    ObjectInputStream objIn = new ObjectInputStream(new FileInputStream(termFile));
+    Term readTerm = (Term)objIn.readObject();
+    assertEquals(readTerm.field(), "date");
+    assertEquals(readTerm.text(), "01/01/2001");
+  }
+  
+  public void testSerializeQueries() throws Exception {
+    File queryFile = new File(tempDir, "query.obj");
+    BooleanQuery bq2 = new BooleanQuery();
+    bq2.add(new TermQuery(new Term("field", "value1")), BooleanClause.Occur.SHOULD);
+    bq2.add(new TermQuery(new Term("field", "value2")), BooleanClause.Occur.SHOULD);
+    BooleanQuery nested2 = new BooleanQuery();
+    nested2.add(new TermQuery(new Term("field", "nestedvalue1")), BooleanClause.Occur.SHOULD);
+    nested2.add(new TermQuery(new Term("field", "nestedvalue2")), BooleanClause.Occur.SHOULD);
+    bq2.add(nested2, BooleanClause.Occur.SHOULD);
+    
+    ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream(queryFile));
+    objOut.writeObject(bq2);
+    objOut.close();
+    
+    ObjectInputStream objIn = new ObjectInputStream(new FileInputStream(queryFile));
+    BooleanQuery readbq = (BooleanQuery)objIn.readObject();
+    assertEquals(readbq, bq2);
+  }
+  
+  public void testSerializeDocument() throws Exception {
+    File docsFile = new File(tempDir, "docs.obj");
+    Document doc = new Document();
+    DocHelper.setupDoc(doc);
+    ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream(docsFile));
+    objOut.writeObject(doc);
+    objOut.close();
+    
+    ObjectInputStream objIn = new ObjectInputStream(new FileInputStream(docsFile));
+    Document readdoc = (Document)objIn.readObject();
+    System.out.println("d1: "+doc+" d2: "+readdoc);
+    assertEquals(readdoc, doc);
+  }
+}

Property changes on: src/test/org/apache/lucene/util/TestSerialization.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + "Date Rev Author URL Id"
Name: svn:eol-style
   + native

Index: src/java/org/apache/lucene/search/MultiTermQuery.java
===================================================================
--- src/java/org/apache/lucene/search/MultiTermQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/MultiTermQuery.java	(working copy)
@@ -43,6 +43,7 @@
  * override equals and hashcode.
  */
 public abstract class MultiTermQuery extends Query {
+  private static final long serialVersionUID = 10L;
   protected Term term;
   protected boolean constantScoreRewrite = false;
 
Index: src/java/org/apache/lucene/search/ConstantScoreQuery.java
===================================================================
--- src/java/org/apache/lucene/search/ConstantScoreQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/ConstantScoreQuery.java	(working copy)
@@ -30,6 +30,7 @@
  * @version $Id$
  */
 public class ConstantScoreQuery extends Query {
+  private static final long serialVersionUID = 10L;
   protected final Filter filter;
 
   public ConstantScoreQuery(Filter filter) {
Index: src/java/org/apache/lucene/search/FuzzyQuery.java
===================================================================
--- src/java/org/apache/lucene/search/FuzzyQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/FuzzyQuery.java	(working copy)
@@ -28,7 +28,7 @@
  * is based on the Levenshtein (edit distance) algorithm.
  */
 public class FuzzyQuery extends MultiTermQuery {
-  
+  private static final long serialVersionUID = 10L;
   public final static float defaultMinSimilarity = 0.5f;
   public final static int defaultPrefixLength = 0;
   
Index: src/java/org/apache/lucene/search/Filter.java
===================================================================
--- src/java/org/apache/lucene/search/Filter.java	(revision 723418)
+++ src/java/org/apache/lucene/search/Filter.java	(working copy)
@@ -31,6 +31,7 @@
  *  in order to work with Lucene 3.0.
  */
 public abstract class Filter implements java.io.Serializable {
+  private static final long serialVersionUID = 10L;
   /**
    * @return A BitSet with true for documents which should be permitted in
    * search results, and false for those that should not.
Index: src/java/org/apache/lucene/search/FieldCacheRangeFilter.java
===================================================================
--- src/java/org/apache/lucene/search/FieldCacheRangeFilter.java	(revision 723418)
+++ src/java/org/apache/lucene/search/FieldCacheRangeFilter.java	(working copy)
@@ -43,6 +43,7 @@
  */
 
 public class FieldCacheRangeFilter extends Filter {
+  private static final long serialVersionUID = 10L;
   private String field;
   private String lowerVal;
   private String upperVal;
Index: src/java/org/apache/lucene/search/TopFieldDocs.java
===================================================================
--- src/java/org/apache/lucene/search/TopFieldDocs.java	(revision 723418)
+++ src/java/org/apache/lucene/search/TopFieldDocs.java	(working copy)
@@ -29,7 +29,7 @@
  */
 public class TopFieldDocs
 extends TopDocs {
-
+    private static final long serialVersionUID = 10L;
 	/** The fields which were used to sort results by. */
 	public SortField[] fields;
         
Index: src/java/org/apache/lucene/search/RangeQuery.java
===================================================================
--- src/java/org/apache/lucene/search/RangeQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/RangeQuery.java	(working copy)
@@ -38,6 +38,7 @@
  * @version $Id$
  */
 public class RangeQuery extends MultiTermQuery {
+  private static final long serialVersionUID = 10L;
   private Term lowerTerm;
   private Term upperTerm;
   private Collator collator;
Index: src/java/org/apache/lucene/search/ConstantScoreRangeQuery.java
===================================================================
--- src/java/org/apache/lucene/search/ConstantScoreRangeQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/ConstantScoreRangeQuery.java	(working copy)
@@ -35,7 +35,8 @@
  */
 public class ConstantScoreRangeQuery extends RangeQuery
 {
-
+  private static final long serialVersionUID = 10L;
+  
   public ConstantScoreRangeQuery(String fieldName, String lowerVal, String upperVal, boolean includeLower, boolean includeUpper)
   {
     super(fieldName, lowerVal, upperVal, includeLower, includeUpper);
Index: src/java/org/apache/lucene/search/function/IntFieldSource.java
===================================================================
--- src/java/org/apache/lucene/search/function/IntFieldSource.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/IntFieldSource.java	(working copy)
@@ -40,6 +40,7 @@
  *
  */
 public class IntFieldSource extends FieldCacheSource {
+  private static final long serialVersionUID = 10L;
   private FieldCache.IntParser parser;
 
   /**
Index: src/java/org/apache/lucene/search/function/ValueSourceQuery.java
===================================================================
--- src/java/org/apache/lucene/search/function/ValueSourceQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/ValueSourceQuery.java	(working copy)
@@ -39,6 +39,7 @@
  * supported anymore in such a case.</font>
  */
 public class ValueSourceQuery extends Query {
+  private static final long serialVersionUID = 10L;
   ValueSource valSrc;
 
   /**
Index: src/java/org/apache/lucene/search/function/ShortFieldSource.java
===================================================================
--- src/java/org/apache/lucene/search/function/ShortFieldSource.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/ShortFieldSource.java	(working copy)
@@ -38,6 +38,7 @@
  * on the field.
  */
 public class ShortFieldSource extends FieldCacheSource {
+  private static final long serialVersionUID = 10L;
   private FieldCache.ShortParser parser;
 
   /**
Index: src/java/org/apache/lucene/search/function/FieldScoreQuery.java
===================================================================
--- src/java/org/apache/lucene/search/function/FieldScoreQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/FieldScoreQuery.java	(working copy)
@@ -58,7 +58,7 @@
  * supported anymore in such a case.</font>
  */
 public class FieldScoreQuery extends ValueSourceQuery {
-
+  private static final long serialVersionUID = 10L;
   /**
    * Type of score field, indicating how field values are interpreted/parsed.  
    * <p>
Index: src/java/org/apache/lucene/search/function/ReverseOrdFieldSource.java
===================================================================
--- src/java/org/apache/lucene/search/function/ReverseOrdFieldSource.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/ReverseOrdFieldSource.java	(working copy)
@@ -48,6 +48,7 @@
  */
 
 public class ReverseOrdFieldSource extends ValueSource {
+  private static final long serialVersionUID = 10L;
   public String field;
 
   /** 
Index: src/java/org/apache/lucene/search/function/ByteFieldSource.java
===================================================================
--- src/java/org/apache/lucene/search/function/ByteFieldSource.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/ByteFieldSource.java	(working copy)
@@ -38,6 +38,7 @@
  * on the field. 
  */
 public class ByteFieldSource extends FieldCacheSource {
+  private static final long serialVersionUID = 10L;
   private FieldCache.ByteParser parser;
 
   /**
Index: src/java/org/apache/lucene/search/function/FieldCacheSource.java
===================================================================
--- src/java/org/apache/lucene/search/function/FieldCacheSource.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/FieldCacheSource.java	(working copy)
@@ -41,6 +41,7 @@
  *
  */
 public abstract class FieldCacheSource extends ValueSource {
+  private static final long serialVersionUID = 10L;
   private String field;
 
   /**
Index: src/java/org/apache/lucene/search/function/OrdFieldSource.java
===================================================================
--- src/java/org/apache/lucene/search/function/OrdFieldSource.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/OrdFieldSource.java	(working copy)
@@ -47,6 +47,7 @@
  */
 
 public class OrdFieldSource extends ValueSource {
+  private static final long serialVersionUID = 10L;
   protected String field;
 
   /** 
Index: src/java/org/apache/lucene/search/function/FloatFieldSource.java
===================================================================
--- src/java/org/apache/lucene/search/function/FloatFieldSource.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/FloatFieldSource.java	(working copy)
@@ -39,6 +39,7 @@
  *
  */
 public class FloatFieldSource extends FieldCacheSource {
+  private static final long serialVersionUID = 10L;
   private FieldCache.FloatParser parser;
 
   /**
Index: src/java/org/apache/lucene/search/function/CustomScoreQuery.java
===================================================================
--- src/java/org/apache/lucene/search/function/CustomScoreQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/CustomScoreQuery.java	(working copy)
@@ -46,7 +46,7 @@
  * supported anymore in such a case.</font>
  */
 public class CustomScoreQuery extends Query {
-
+  private static final long serialVersionUID = 10L;
   private Query subQuery;
   private ValueSourceQuery[] valSrcQueries; // never null (empty array if there are no valSrcQueries).
   private boolean strict = false; // if true, valueSource part of query does not take part in weights normalization.  
Index: src/java/org/apache/lucene/search/function/ValueSource.java
===================================================================
--- src/java/org/apache/lucene/search/function/ValueSource.java	(revision 723418)
+++ src/java/org/apache/lucene/search/function/ValueSource.java	(working copy)
@@ -39,7 +39,7 @@
  *
  */
 public abstract class ValueSource implements Serializable {
-
+  private static final long serialVersionUID = 10L;
   /**
    * Return the DocValues used by the function query.
    * @param reader the IndexReader used to read these values.
Index: src/java/org/apache/lucene/search/BooleanQuery.java
===================================================================
--- src/java/org/apache/lucene/search/BooleanQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/BooleanQuery.java	(working copy)
@@ -29,7 +29,7 @@
   * BooleanQuerys.
   */
 public class BooleanQuery extends Query {
-
+  private static final long serialVersionUID = 10L;
   
   private static int maxClauseCount = 1024;
 
Index: src/java/org/apache/lucene/search/Query.java
===================================================================
--- src/java/org/apache/lucene/search/Query.java	(revision 723418)
+++ src/java/org/apache/lucene/search/Query.java	(working copy)
@@ -45,6 +45,7 @@
     </ul>
 */
 public abstract class Query implements java.io.Serializable, Cloneable {
+  private static final long serialVersionUID = 10L;
   private float boost = 1.0f;                     // query boost factor
 
   /** Sets the boost for this query clause to <code>b</code>.  Documents
Index: src/java/org/apache/lucene/search/PhraseQuery.java
===================================================================
--- src/java/org/apache/lucene/search/PhraseQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/PhraseQuery.java	(working copy)
@@ -32,6 +32,7 @@
  * <p>This query may be combined with other terms or queries with a {@link BooleanQuery}.
  */
 public class PhraseQuery extends Query {
+  private static final long serialVersionUID = 10L;
   private String field;
   private ArrayList terms = new ArrayList(4);
   private ArrayList positions = new ArrayList(4);
Index: src/java/org/apache/lucene/search/FieldDoc.java
===================================================================
--- src/java/org/apache/lucene/search/FieldDoc.java	(revision 723418)
+++ src/java/org/apache/lucene/search/FieldDoc.java	(working copy)
@@ -40,7 +40,7 @@
  */
 public class FieldDoc
 extends ScoreDoc {
-
+    private static final long serialVersionUID = 10L;
 	/** Expert: The values which are used to sort the referenced document.
 	 * The order of these will match the original sort criteria given by a
 	 * Sort object.  Each Object will be either an Integer, Float or String,
Index: src/java/org/apache/lucene/search/TopDocs.java
===================================================================
--- src/java/org/apache/lucene/search/TopDocs.java	(revision 723418)
+++ src/java/org/apache/lucene/search/TopDocs.java	(working copy)
@@ -20,6 +20,7 @@
 /** Expert: Returned by low-level search implementations.
  * @see Searcher#search(Query,Filter,int) */
 public class TopDocs implements java.io.Serializable {
+  private static final long serialVersionUID = 10L;
   /** Expert: The total number of hits for the query.
    * @see Hits#length()
   */
Index: src/java/org/apache/lucene/search/Explanation.java
===================================================================
--- src/java/org/apache/lucene/search/Explanation.java	(revision 723418)
+++ src/java/org/apache/lucene/search/Explanation.java	(working copy)
@@ -21,6 +21,7 @@
 
 /** Expert: Describes the score computation for document and query. */
 public class Explanation implements java.io.Serializable {
+  private static final long serialVersionUID = 10L;
   private float value;                            // the value of this node
   private String description;                     // what it represents
   private ArrayList details;                      // sub-explanations
Index: src/java/org/apache/lucene/search/Sort.java
===================================================================
--- src/java/org/apache/lucene/search/Sort.java	(revision 723418)
+++ src/java/org/apache/lucene/search/Sort.java	(working copy)
@@ -99,7 +99,7 @@
  */
 public class Sort
 implements Serializable {
-
+  private static final long serialVersionUID = 10L;
   /**
    * Represents sorting by computed relevance. Using this sort criteria returns
    * the same results as calling
Index: src/java/org/apache/lucene/search/SortField.java
===================================================================
--- src/java/org/apache/lucene/search/SortField.java	(revision 723418)
+++ src/java/org/apache/lucene/search/SortField.java	(working copy)
@@ -32,7 +32,7 @@
  */
 public class SortField
 implements Serializable {
-
+  private static final long serialVersionUID = 10L;
   /** Sort by document score (relevancy).  Sort values are Float and higher
    * values are at the front. */
   public static final int SCORE = 0;
Index: src/java/org/apache/lucene/search/TermQuery.java
===================================================================
--- src/java/org/apache/lucene/search/TermQuery.java	(revision 723418)
+++ src/java/org/apache/lucene/search/TermQuery.java	(working copy)
@@ -29,6 +29,7 @@
   This may be combined with other terms with a {@link BooleanQuery}.
   */
 public class TermQuery extends Query {
+  private static final long serialVersionUID = 10L;
   private Term term;
 
   private class TermWeight implements Weight {
Index: src/java/org/apache/lucene/search/ScoreDoc.java
===================================================================
--- src/java/org/apache/lucene/search/ScoreDoc.java	(revision 723418)
+++ src/java/org/apache/lucene/search/ScoreDoc.java	(working copy)
@@ -20,6 +20,7 @@
 /** Expert: Returned by low-level search implementations.
  * @see TopDocs */
 public class ScoreDoc implements java.io.Serializable {
+  private static final long serialVersionUID = 10L;
   /** Expert: The score of this document for the query. */
   public float score;
 
Index: src/java/org/apache/lucene/search/ComplexExplanation.java
===================================================================
--- src/java/org/apache/lucene/search/ComplexExplanation.java	(revision 723418)
+++ src/java/org/apache/lucene/search/ComplexExplanation.java	(working copy)
@@ -20,6 +20,7 @@
 /** Expert: Describes the score computation for document and query, and
  * can distinguish a match independent of a positive value. */
 public class ComplexExplanation extends Explanation {
+  private static final long serialVersionUID = 10L;
   private Boolean match;
   
   public ComplexExplanation() {
Index: src/java/org/apache/lucene/search/BooleanClause.java
===================================================================
--- src/java/org/apache/lucene/search/BooleanClause.java	(revision 723418)
+++ src/java/org/apache/lucene/search/BooleanClause.java	(working copy)
@@ -21,6 +21,7 @@
 
 /** A clause in a BooleanQuery. */
 public class BooleanClause implements java.io.Serializable {
+  private static final long serialVersionUID = 10L;
   
   /** Specifies how clauses are to occur in matching documents. */
   public static final class Occur extends Parameter implements java.io.Serializable {
Index: src/java/org/apache/lucene/index/Payload.java
===================================================================
--- src/java/org/apache/lucene/index/Payload.java	(revision 723418)
+++ src/java/org/apache/lucene/index/Payload.java	(working copy)
@@ -35,6 +35,7 @@
  *
  */
 public class Payload implements Serializable, Cloneable {
+  private static final long serialVersionUID = 10L;
   /** the byte array containing the payload data */
   protected byte[] data;
     
Index: src/java/org/apache/lucene/index/Term.java
===================================================================
--- src/java/org/apache/lucene/index/Term.java	(revision 723418)
+++ src/java/org/apache/lucene/index/Term.java	(working copy)
@@ -1,5 +1,12 @@
 package org.apache.lucene.index;
 
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Externalizable;
+
+import org.apache.lucene.util.SerializeUtils;
+
 /**
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -25,10 +32,13 @@
   Note that terms may represent more than words from text fields, but also
   things like dates, email addresses, urls, etc.  */
 
-public final class Term implements Comparable, java.io.Serializable {
+public final class Term implements Comparable, Externalizable {
+  private static final long serialVersionUID = 10L;
   String field;
   String text;
-
+  
+  public Term() {}
+  
   /** Constructs a Term with the given field and text.
    * <p>Note that a null field or null text value results in undefined
    * behavior for most Lucene APIs that accept a Term parameter. */
@@ -113,10 +123,15 @@
 
   public final String toString() { return field + ":" + text; }
 
-  private void readObject(java.io.ObjectInputStream in)
-    throws java.io.IOException, ClassNotFoundException
-  {
-      in.defaultReadObject();
-      field = field.intern();
+  public void writeExternal(ObjectOutput out) throws IOException {
+    SerializeUtils.writeVLong(out, serialVersionUID);
+    out.writeUTF(field);
+    out.writeUTF(text);
   }
+  
+  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    long serialVersionUID = SerializeUtils.readVLong(in);
+	field = in.readUTF().intern();
+	text = in.readUTF();
+  }
 }
Index: src/java/org/apache/lucene/util/SerializeUtils.java
===================================================================
--- src/java/org/apache/lucene/util/SerializeUtils.java	(revision 0)
+++ src/java/org/apache/lucene/util/SerializeUtils.java	(revision 0)
@@ -0,0 +1,172 @@
+package org.apache.lucene.util;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * From Hadoop WriteableUtils
+ *
+ */
+public class SerializeUtils
+{
+  
+  /**
+   * Reads a zero-compressed encoded integer from input stream and returns it.
+   * @param stream Binary input stream
+   * @throws java.io.IOException 
+   * @return deserialized integer from stream.
+   */
+  public static int readVInt(DataInput stream) throws IOException {
+    return (int) readVLong(stream);
+  }
+  
+  /**
+   * Serializes an integer to a binary stream with zero-compressed encoding.
+   * For -120 <= i <= 127, only one byte is used with the actual value.
+   * For other values of i, the first byte value indicates whether the
+   * integer is positive or negative, and the number of bytes that follow.
+   * If the first byte value v is between -121 and -124, the following integer
+   * is positive, with number of bytes that follow are -(v+120).
+   * If the first byte value v is between -125 and -128, the following integer
+   * is negative, with number of bytes that follow are -(v+124). Bytes are
+   * stored in the high-non-zero-byte-first order.
+   *
+   * @param stream Binary output stream
+   * @param i Integer to be serialized
+   * @throws java.io.IOException 
+   */
+  public static void writeVInt(DataOutput stream, int i) throws IOException {
+    writeVLong(stream, i);
+  }
+
+  /**
+   * Given the first byte of a vint/vlong, determine the sign
+   * 
+   * @param value
+   *          the first byte
+   * @return is the value negative
+   */
+  public static boolean isNegativeVInt(byte value)
+  {
+    return value < -120 || (value >= -112 && value < 0);
+  }
+
+  /**
+   * Serializes a long to a binary stream with zero-compressed encoding. For -112 <= i <=
+   * 127, only one byte is used with the actual value. For other values of i, the first
+   * byte value indicates whether the long is positive or negative, and the number of
+   * bytes that follow. If the first byte value v is between -113 and -120, the following
+   * long is positive, with number of bytes that follow are -(v+112). If the first byte
+   * value v is between -121 and -128, the following long is negative, with number of
+   * bytes that follow are -(v+120). Bytes are stored in the high-non-zero-byte-first
+   * order.
+   * 
+   * @param stream
+   *          Binary output stream
+   * @param i
+   *          Long to be serialized
+   * @throws java.io.IOException
+   */
+  public static void writeVLong(DataOutput stream, long i) throws IOException
+  {
+    if (i >= -112 && i <= 127)
+    {
+      stream.writeByte((byte) i);
+      return;
+    }
+
+    int len = -112;
+    if (i < 0)
+    {
+      i ^= -1L; // take one's complement'
+      len = -120;
+    }
+
+    long tmp = i;
+    while (tmp != 0)
+    {
+      tmp = tmp >> 8;
+      len--;
+    }
+
+    stream.writeByte((byte) len);
+
+    len = (len < -120) ? -(len + 120) : -(len + 112);
+
+    for (int idx = len; idx != 0; idx--)
+    {
+      int shiftbits = (idx - 1) * 8;
+      long mask = 0xFFL << shiftbits;
+      stream.writeByte((byte) ((i & mask) >> shiftbits));
+    }
+  }
+
+  /**
+   * Reads a zero-compressed encoded long from input stream and returns it.
+   * 
+   * @param stream
+   *          Binary input stream
+   * @throws java.io.IOException
+   * @return deserialized long from stream.
+   */
+  public static long readVLong(DataInput stream) throws IOException
+  {
+    byte firstByte = stream.readByte();
+    int len = decodeVIntSize(firstByte);
+    if (len == 1)
+    {
+      return firstByte;
+    }
+    long i = 0;
+    for (int idx = 0; idx < len - 1; idx++)
+    {
+      byte b = stream.readByte();
+      i = i << 8;
+      i = i | (b & 0xFF);
+    }
+    return (isNegativeVInt(firstByte) ? (i ^ -1L) : i);
+  }
+
+  /**
+   * Parse the first byte of a vint/vlong to determine the number of bytes
+   * 
+   * @param value
+   *          the first byte of the vint/vlong
+   * @return the total number of bytes (1 to 9)
+   */
+  public static int decodeVIntSize(byte value)
+  {
+    if (value >= -112)
+    {
+      return 1;
+    }
+    else if (value < -120)
+    {
+      return -119 - value;
+    }
+    return -111 - value;
+  }
+
+  /**
+   * Get the encoded length if an integer is stored in a variable-length format
+   * 
+   * @return the encoded length
+   */
+  public static int getVIntSize(long i)
+  {
+    if (i >= -112 && i <= 127)
+    {
+      return 1;
+    }
+
+    if (i < 0)
+    {
+      i ^= -1L; // take one's complement'
+    }
+    // find the number of bytes with non-leading zeros
+    int dataBits = Long.SIZE - Long.numberOfLeadingZeros(i);
+    // find the number of data bytes + length byte
+    return (dataBits + 7) / 8 + 1;
+  }
+}

Property changes on: src/java/org/apache/lucene/util/SerializeUtils.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + "Date Rev Author URL Id"
Name: svn:eol-style
   + native

Index: src/java/org/apache/lucene/document/Field.java
===================================================================
--- src/java/org/apache/lucene/document/Field.java	(revision 723418)
+++ src/java/org/apache/lucene/document/Field.java	(working copy)
@@ -20,8 +20,13 @@
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.index.IndexWriter;   // for javadoc
 import org.apache.lucene.util.Parameter;
+import org.apache.lucene.util.SerializeUtils;
 
 import java.io.Reader;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.io.Serializable;
 
 /**
@@ -32,7 +37,8 @@
   index, so that they may be returned with hits on the document.
   */
 
-public final class Field extends AbstractField implements Fieldable, Serializable {
+public final class Field extends AbstractField implements Fieldable, Externalizable {
+  private static final long serialVersionUID = 10L;
   
   /** Specifies whether and how a field should be stored. */
   public static final class Store extends Parameter implements Serializable {
@@ -234,8 +240,13 @@
   public void setValue(TokenStream value) {
     fieldsData = value;
   }
-
+  
   /**
+   * No argument constructor for Externalizable based serialization
+   */
+  public Field() {}
+  
+  /**
    * Create a field by specifying its name, value and how it will
    * be saved in the index. Term vectors will not be stored in the index.
    * 
@@ -473,4 +484,18 @@
     
     setStoreTermVector(TermVector.NO);
   }
+  
+  public boolean equals(Object o) {
+    return super.equals(o);
+  }
+  
+  public void writeExternal(ObjectOutput out) throws IOException {
+    SerializeUtils.writeVLong(out, serialVersionUID);
+    super.writeExternal(out);
+  }
+  
+  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    long svuid = SerializeUtils.readVLong(in);
+    super.readExternal(in);
+  }
 }
Index: src/java/org/apache/lucene/document/AbstractField.java
===================================================================
--- src/java/org/apache/lucene/document/AbstractField.java	(revision 723418)
+++ src/java/org/apache/lucene/document/AbstractField.java	(working copy)
@@ -15,13 +15,21 @@
  * limitations under the License.
  */
 
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+import java.io.NotSerializableException;
+import java.util.Arrays;
 
+import org.apache.lucene.util.SerializeUtils;
 /**
  *
  *
  **/
-public abstract class AbstractField implements Fieldable {
-
+public abstract class AbstractField implements Fieldable, Externalizable {
+  private static final long serialVersionUID = 10L;
   protected String name = "body";
   protected boolean storeTermVector = false;
   protected boolean storeOffsetWithTermVector = false;
@@ -44,7 +52,7 @@
   protected AbstractField()
   {
   }
-
+  
   protected AbstractField(String name, Field.Store store, Field.Index index, Field.TermVector termVector) {
     if (name == null)
       throw new NullPointerException("name cannot be null");
@@ -282,7 +290,75 @@
   public boolean isLazy() {
     return lazy;
   }
-
+  
+  public boolean equals(Object o) {
+    AbstractField other = (AbstractField)o;
+    return (storeTermVector == other.storeTermVector 
+        && storeOffsetWithTermVector == other.storeOffsetWithTermVector
+        && storePositionWithTermVector == other.storePositionWithTermVector
+        && omitNorms == other.omitNorms
+        && isStored == other.isStored
+        && isIndexed == other.isIndexed
+        && isTokenized == other.isTokenized
+        && isBinary == other.isBinary
+        && isCompressed == other.isCompressed
+        && lazy == other.lazy
+        && omitTf == other.omitTf
+        && boost == other.boost
+        && binaryLength == other.binaryLength
+        && binaryOffset == other.binaryOffset
+        && equalsFieldData(fieldsData, other.fieldsData));
+  }
+  
+  private static boolean equalsFieldData(Object o1, Object o2) {
+    if (o1 instanceof String && o2 instanceof String) {
+      return o1.equals(o2);
+    } else if (o1 instanceof byte[] && o2 instanceof byte[]) {
+      return Arrays.equals((byte[])o1, (byte[])o2);
+    }
+    return true;
+  }
+  
+  public void writeExternal(ObjectOutput out) throws IOException {
+    SerializeUtils.writeVLong(out, serialVersionUID);
+    out.writeUTF(name);
+    out.writeBoolean(storeTermVector);
+    out.writeBoolean(storeOffsetWithTermVector);
+    out.writeBoolean(storePositionWithTermVector);
+    out.writeBoolean(omitNorms);
+    out.writeBoolean(isStored);
+    out.writeBoolean(isIndexed);
+    out.writeBoolean(isTokenized);
+    out.writeBoolean(isBinary);
+    out.writeBoolean(isCompressed);
+    out.writeBoolean(lazy);
+    out.writeBoolean(omitTf);
+    out.writeFloat(boost);
+    SerializeUtils.writeVInt(out, binaryLength);
+    SerializeUtils.writeVInt(out, binaryOffset);
+    out.writeObject(fieldsData);
+  }
+  
+  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    long svuid = SerializeUtils.readVLong(in);
+    name = in.readUTF().intern();
+    storeTermVector = in.readBoolean();
+    storeOffsetWithTermVector = in.readBoolean();
+    storePositionWithTermVector = in.readBoolean();
+    omitNorms = in.readBoolean();
+    isStored = in.readBoolean();
+    isIndexed = in.readBoolean();
+    isTokenized = in.readBoolean();
+    isBinary = in.readBoolean();
+    isCompressed = in.readBoolean();
+    lazy = in.readBoolean();
+    omitTf = in.readBoolean();
+    boost = in.readFloat();
+    binaryLength = SerializeUtils.readVInt(in);
+    binaryOffset = SerializeUtils.readVInt(in);
+    fieldsData = in.readObject();
+  }
+  
   /** Prints a Field for human consumption. */
   public final String toString() {
     StringBuffer result = new StringBuffer();
Index: src/java/org/apache/lucene/document/Document.java
===================================================================
--- src/java/org/apache/lucene/document/Document.java	(revision 723418)
+++ src/java/org/apache/lucene/document/Document.java	(working copy)
@@ -18,8 +18,14 @@
  */
 
 import java.util.*;             // for javadoc
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
 import org.apache.lucene.search.ScoreDoc; // for javadoc
 import org.apache.lucene.search.Searcher;  // for javadoc
+import org.apache.lucene.util.SerializeUtils;
 import org.apache.lucene.index.IndexReader;  // for javadoc
 
 /** Documents are the unit of indexing and search.
@@ -36,14 +42,14 @@
  * IndexReader#document(int)}.
  */
 
-public final class Document implements java.io.Serializable {
+public final class Document implements Externalizable {
+  private static final long serialVersionUID = 10L;
   List fields = new ArrayList();
   private float boost = 1.0f;
 
   /** Constructs a new document with no fields. */
   public Document() {}
-
-
+  
   /** Sets a boost factor for hits on any field of this document.  This value
    * will be multiplied into the score of all hits on this document.
    *
@@ -315,6 +321,28 @@
     return null;
   }
   
+  public void writeExternal(ObjectOutput out) throws IOException {
+    SerializeUtils.writeVLong(out, serialVersionUID);
+    SerializeUtils.writeVInt(out, fields.size());
+    for (int x=0; x < fields.size(); x++) {
+      out.writeObject(fields.get(x));
+    }
+  }
+  
+  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    long svuid = SerializeUtils.readVLong(in);
+    int fsize = SerializeUtils.readVInt(in);
+    for (int x=0; x < fsize; x++) {
+      fields.add(in.readObject());
+    }
+  }
+  
+  public boolean equals(Object o) {
+    Document other = (Document)o;
+    return (boost == other.boost
+        && fields.equals(other.fields));
+  }
+  
   /** Prints the fields of a document for human consumption. */
   public final String toString() {
     StringBuffer buffer = new StringBuffer();
