Index: branch-0.7/src/java/org/apache/nutch/searcher/LuceneQueryOptimizer.java
===================================================================
--- branch-0.7/src/java/org/apache/nutch/searcher/LuceneQueryOptimizer.java	(revision 354477)
+++ branch-0.7/src/java/org/apache/nutch/searcher/LuceneQueryOptimizer.java	(working copy)
@@ -54,7 +54,7 @@
 
   public TopDocs optimize(BooleanQuery original,
                           Searcher searcher, int numHits,
-                          String sortField, boolean reverse)
+                          SortField[] sortFields)
     throws IOException {
 
     BooleanQuery query = new BooleanQuery();
@@ -124,11 +124,11 @@
       }        
     }
 
-    if (sortField == null && !reverse) {
+    if (sortFields == null) {
       return searcher.search(query, filter, numHits);
     } else {
       return searcher.search(query, filter, numHits,
-                             new Sort(sortField, reverse));
+                             new Sort(sortFields));
     }
   }
 }
Index: branch-0.7/src/java/org/apache/nutch/searcher/NutchBean.java
===================================================================
--- branch-0.7/src/java/org/apache/nutch/searcher/NutchBean.java	(revision 354477)
+++ branch-0.7/src/java/org/apache/nutch/searcher/NutchBean.java	(working copy)
@@ -27,6 +27,8 @@
 import org.apache.nutch.parse.*;
 import org.apache.nutch.indexer.*;
 
+import org.apache.lucene.search.SortField;
+
 /** 
  * One stop shopping for search-related functionality.
  * @version $Id: NutchBean.java,v 1.19 2005/02/07 19:10:08 cutting Exp $
@@ -142,6 +144,12 @@
     return searcher.search(query, numHits, dedupField, sortField, reverse);
   }
   
+	public Hits search(Query query, int numHits,
+                     String dedupField, SortField[] sortFields)
+		throws IOException {
+    return searcher.search(query, numHits, dedupField, sortFields);
+	}
+  
   private class DupHits extends ArrayList {
     private boolean maxSizeExceeded;
   }
Index: branch-0.7/src/java/org/apache/nutch/searcher/DistributedSearch.java
===================================================================
--- branch-0.7/src/java/org/apache/nutch/searcher/DistributedSearch.java	(revision 354477)
+++ branch-0.7/src/java/org/apache/nutch/searcher/DistributedSearch.java	(working copy)
@@ -28,6 +28,8 @@
 import org.apache.nutch.io.*;
 import org.apache.nutch.ipc.RPC;
 
+import org.apache.lucene.search.SortField;
+
 /** Implements the search API over IPC connnections. */
 public class DistributedSearch {
   public static final Logger LOG =
@@ -180,7 +182,14 @@
         segmentToAddress.keySet().toArray(new String[segmentToAddress.size()]);
     }
 
-    public Hits search(final Query query, final int numHits,
+   	public Hits search(Query query, int numHits,
+                     String dedupField, SortField[] sortFields)
+			throws IOException {
+			//oy, punting for now
+			return null;
+		}
+
+   public Hits search(final Query query, final int numHits,
                        final String dedupField, final String sortField,
                        final boolean reverse) throws IOException {
       long totalHits = 0;
Index: branch-0.7/src/java/org/apache/nutch/searcher/IndexSearcher.java
===================================================================
--- branch-0.7/src/java/org/apache/nutch/searcher/IndexSearcher.java	(revision 354477)
+++ branch-0.7/src/java/org/apache/nutch/searcher/IndexSearcher.java	(working copy)
@@ -30,6 +30,7 @@
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.FieldDoc;
 import org.apache.lucene.search.FieldCache;
+import org.apache.lucene.search.SortField;
 
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
@@ -76,17 +77,27 @@
   }
 
   public Hits search(Query query, int numHits,
-                     String dedupField, String sortField, boolean reverse)
-
+                     String dedupField, SortField[] sortFields)
     throws IOException {
 
     org.apache.lucene.search.BooleanQuery luceneQuery =
       QueryFilters.filter(query);
     
-    return translateHits
-      (optimizer.optimize(luceneQuery, luceneSearcher, numHits,
-                          sortField, reverse),
-       dedupField, sortField);
+		TopDocs topDocs = optimizer.optimize(luceneQuery, luceneSearcher,
+																					numHits, sortFields);
+
+    return translateHits(topDocs, dedupField, sortFields);
+	}
+
+  public Hits search(Query query, int numHits,
+                     String dedupField, String sortField, boolean reverse)
+    throws IOException {
+		
+		SortField tmp;
+		tmp = (sortField == null) ? SortField.FIELD_SCORE :
+						new SortField(sortField, reverse);
+		SortField[] sortFields = {tmp};
+		return search(query, numHits, dedupField, sortFields);
   }
 
   public String getExplanation(Query query, Hit hit) throws IOException {
@@ -118,10 +129,63 @@
     return results;
   }
 
+	private WritableComparable getSortValue(FieldDoc doc, int fieldNum) {
+		WritableComparable sortValue;
+
+		Object raw = doc.fields[fieldNum];
+		if (raw instanceof Integer) {
+			sortValue = new IntWritable(((Integer)raw).intValue());
+		} else if (raw instanceof Float) {
+			sortValue = new FloatWritable(((Float)raw).floatValue());
+		} else if (raw instanceof String) {
+			sortValue = new UTF8((String)raw);
+		} else {
+			throw new RuntimeException("Unknown sort value type!");
+		}
+		return sortValue;	
+	}
+
+	private WritableComparable getSortValue(FieldDoc doc,
+																					SortField[] sortFields) {
+		WritableComparable sortValue;
+		if (sortFields.length == 1) {
+			if (sortFields[0].getType() == SortField.SCORE)
+				sortValue = new FloatWritable(doc.score);
+			else
+				sortValue = getSortValue(doc, 0);
+		}
+		else {
+			SortValueWritable sortValueWriteable;
+			sortValueWriteable = new SortValueWritable(sortFields.length);
+			for (int i = 0; i < sortFields.length; i++) {
+			if (sortFields[i].getType() == SortField.SCORE)
+				sortValueWriteable.put(new FloatWritable(doc.score), i);
+			else if (sortFields[i].getType() == SortField.DOC)
+				sortValueWriteable.put(new IntWritable(doc.doc), i);
+			else
+				sortValueWriteable.put(getSortValue(doc, i), i);
+			}
+			sortValue = sortValueWriteable;
+		}
+		return sortValue;
+	}
+
   private Hits translateHits(TopDocs topDocs,
                              String dedupField, String sortField)
     throws IOException {
 
+		SortField[] sortFields = new SortField[1];
+		if (sortField == null)
+			sortFields[0] = SortField.FIELD_SCORE;
+		else
+			sortFields[0] = new SortField(sortField);
+		return translateHits(topDocs, dedupField, sortFields);
+	}
+
+  private Hits translateHits(TopDocs topDocs,
+                             String dedupField, SortField[] sortFields)
+    throws IOException {
+
     String[] dedupValues = null;
     if (dedupField != null) 
       dedupValues = FieldCache.DEFAULT.getStrings(reader, dedupField);
@@ -134,20 +198,7 @@
       int doc = scoreDocs[i].doc;
       
       WritableComparable sortValue;               // convert value to writable
-      if (sortField == null) {
-        sortValue = new FloatWritable(scoreDocs[i].score);
-      } else {
-        Object raw = ((FieldDoc)scoreDocs[i]).fields[0];
-        if (raw instanceof Integer) {
-          sortValue = new IntWritable(((Integer)raw).intValue());
-        } else if (raw instanceof Float) {
-          sortValue = new FloatWritable(((Float)raw).floatValue());
-        } else if (raw instanceof String) {
-          sortValue = new UTF8((String)raw);
-        } else {
-          throw new RuntimeException("Unknown sort value type!");
-        }
-      }
+			sortValue = getSortValue((FieldDoc)scoreDocs[i], sortFields);
 
       String dedupValue = dedupValues == null ? null : dedupValues[doc];
 
Index: branch-0.7/src/java/org/apache/nutch/searcher/Searcher.java
===================================================================
--- branch-0.7/src/java/org/apache/nutch/searcher/Searcher.java	(revision 354477)
+++ branch-0.7/src/java/org/apache/nutch/searcher/Searcher.java	(working copy)
@@ -16,6 +16,8 @@
 
 package org.apache.nutch.searcher;
 
+import org.apache.lucene.search.SortField;
+
 import java.io.IOException;
 
 /** Service that searches. */
@@ -25,6 +27,11 @@
               String dedupField, String sortField, boolean reverse)
     throws IOException;
 
+  /** Return the top-scoring hits for a query. */
+  Hits search(Query query, int numHits,
+                     String dedupField, SortField[] sortFields)
+		throws IOException;
+
   /** Return an HTML-formatted explanation of how a query scored. */
   String getExplanation(Query query, Hit hit) throws IOException;
 }
