Index: src/java/org/apache/lucene/search/ConstantScoreQuery.java
===================================================================
--- src/java/org/apache/lucene/search/ConstantScoreQuery.java	(revision 888200)
+++ src/java/org/apache/lucene/search/ConstantScoreQuery.java	(working copy)
@@ -28,11 +28,15 @@
  * query boost for every document in the filter.
  */
 public class ConstantScoreQuery extends Query {
-  protected final Filter filter;
+  protected Filter filter = null;
 
   public ConstantScoreQuery(Filter filter) {
     this.filter=filter;
   }
+  
+  ConstantScoreQuery() {
+
+  }
 
   /** Returns the encapsulated filter */
   public Filter getFilter() {
@@ -54,14 +58,23 @@
     private Similarity similarity;
     private float queryNorm;
     private float queryWeight;
+    private Query lateQuery = null;
     
+    public void setLateQuery(Query lateQuery) {
+      this.lateQuery = lateQuery;
+    }
+
     public ConstantWeight(Searcher searcher) {
       this.similarity = getSimilarity(searcher);
     }
 
     @Override
     public Query getQuery() {
-      return ConstantScoreQuery.this;
+      if(lateQuery == null) {
+        return ConstantScoreQuery.this;
+      } else {
+        return lateQuery;
+      }
     }
 
     @Override
Index: src/java/org/apache/lucene/search/IndexSearcher.java
===================================================================
--- src/java/org/apache/lucene/search/IndexSearcher.java	(revision 888200)
+++ src/java/org/apache/lucene/search/IndexSearcher.java	(working copy)
@@ -207,6 +207,9 @@
     
     if (filter == null) {
       for (int i = 0; i < subReaders.length; i++) { // search each subreader
+        if(weight.lateCnstRewrite()) {
+          weight = weight.getQuery().rewrite(subReaders[i]).createWeight(this);
+        }
         collector.setNextReader(subReaders[i], docStarts[i]);
         Scorer scorer = weight.scorer(subReaders[i], !collector.acceptsDocsOutOfOrder(), true);
         if (scorer != null) {
Index: src/java/org/apache/lucene/search/MultiTermQuery.java
===================================================================
--- src/java/org/apache/lucene/search/MultiTermQuery.java	(revision 888200)
+++ src/java/org/apache/lucene/search/MultiTermQuery.java	(working copy)
@@ -113,6 +113,10 @@
       ((BoostAttribute) target).setBoost(boost);
     }
   }
+  
+  public boolean lateCnstRewrite() {
+    return rewriteMethod == CONSTANT_SCORE_AUTO_REWRITE_DEFAULT || rewriteMethod == CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE || rewriteMethod == CONSTANT_SCORE_FILTER_REWRITE;
+  }
 
   /** Abstract class that defines how the query is rewritten. */
   public static abstract class RewriteMethod implements Serializable {
Index: src/java/org/apache/lucene/search/Query.java
===================================================================
--- src/java/org/apache/lucene/search/Query.java	(revision 888200)
+++ src/java/org/apache/lucene/search/Query.java	(working copy)
@@ -25,6 +25,7 @@
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.search.ConstantScoreQuery.ConstantWeight;
 
 /** The abstract base class for queries.
     <p>Instantiable subclasses are:
@@ -97,8 +98,19 @@
    * Expert: Constructs and initializes a Weight for a top-level query.
    */
   public Weight weight(Searcher searcher) throws IOException {
-    Query query = searcher.rewrite(this);
-    Weight weight = query.createWeight(searcher);
+    Weight weight;
+    if(!lateCnstRewrite()) {
+      Query query = searcher.rewrite(this);
+      weight = query.createWeight(searcher);
+    } else {
+      ConstantScoreQuery cnst = new ConstantScoreQuery();
+      cnst.setBoost(getBoost());
+      ConstantWeight w = (ConstantWeight) cnst.createWeight(searcher);
+      w.setLateQuery(this);
+      weight = w;
+      weight.setCnstLateRewrite(true);
+    }
+    
     float sum = weight.sumOfSquaredWeights();
     float norm = getSimilarity(searcher).queryNorm(sum);
     weight.normalize(norm);
@@ -114,6 +126,10 @@
     return this;
   }
   
+  public boolean lateCnstRewrite() {
+    return false;
+  }
+  
 
   /** Expert: called when re-writing queries under MultiSearcher.
    *
Index: src/java/org/apache/lucene/search/Weight.java
===================================================================
--- src/java/org/apache/lucene/search/Weight.java	(revision 888200)
+++ src/java/org/apache/lucene/search/Weight.java	(working copy)
@@ -47,6 +47,16 @@
  * @since 2.9
  */
 public abstract class Weight implements Serializable {
+  private boolean lateCnstRewrite = false;
+  private Weight lateWeight;
+  
+  public Weight getLateWeight() {
+    return lateWeight;
+  }
+
+  public void setLateWeight(Weight lateWeight) {
+    this.lateWeight = lateWeight;
+  }
 
   /**
    * An explanation of the score computation for the named document.
@@ -114,5 +124,13 @@
    * the <code>Scorer</code> scores documents in-order.
    */
   public boolean scoresDocsOutOfOrder() { return false; }
+  
+  public boolean lateCnstRewrite() {
+    return lateCnstRewrite;
+  }
+  
+  public void setCnstLateRewrite(boolean lateRewrite) {
+    this.lateCnstRewrite = lateRewrite;
+  }
 
 }

