Index: src/java/org/apache/lucene/search/BooleanQuery.java
===================================================================
--- src/java/org/apache/lucene/search/BooleanQuery.java	(revision 541956)
+++ src/java/org/apache/lucene/search/BooleanQuery.java	(working copy)
@@ -219,40 +219,14 @@
       }
     }
 
-    /** @return A good old 1.4 Scorer */
+    /** @return Returns BooleanScorer2 that uses and provides skipTo(),
+     *          and scores documents in document number order.
+     */
     public Scorer scorer(IndexReader reader) throws IOException {
-      // First see if the (faster) ConjunctionScorer will work.  This can be
-      // used when all clauses are required.  Also, at this point a
-      // BooleanScorer cannot be embedded in a ConjunctionScorer, as the hits
-      // from a BooleanScorer are not always sorted by document number (sigh)
-      // and hence BooleanScorer cannot implement skipTo() correctly, which is
-      // required by ConjunctionScorer.
-      boolean allRequired = true;
-      boolean noneBoolean = true;
-      for (int i = 0 ; i < weights.size(); i++) {
-        BooleanClause c = (BooleanClause)clauses.get(i);
-        if (!c.isRequired())
-          allRequired = false;
-        if (c.getQuery() instanceof BooleanQuery)
-          noneBoolean = false;
-      }
+      BooleanScorer2 result = new BooleanScorer2(similarity,
+                                                 minNrShouldMatch,
+                                                 useScorer14);
 
-      if (allRequired && noneBoolean) {           // ConjunctionScorer is okay
-        ConjunctionScorer result =
-          new ConjunctionScorer(similarity);
-        for (int i = 0 ; i < weights.size(); i++) {
-          Weight w = (Weight)weights.elementAt(i);
-          Scorer subScorer = w.scorer(reader);
-          if (subScorer == null)
-            return null;
-          result.add(subScorer);
-        }
-        return result;
-      }
-
-      // Use good-old BooleanScorer instead.
-      BooleanScorer result = new BooleanScorer(similarity);
-
       for (int i = 0 ; i < weights.size(); i++) {
         BooleanClause c = (BooleanClause)clauses.get(i);
         Weight w = (Weight)weights.elementAt(i);
@@ -335,54 +309,33 @@
     }
   }
 
-  private class BooleanWeight2 extends BooleanWeight {
-    /* Merge into BooleanWeight in case the 1.4 BooleanScorer is dropped */
-    public BooleanWeight2(Searcher searcher)
-      throws IOException {
-        super(searcher);
-    }
-
-    /** @return An alternative Scorer that uses and provides skipTo(),
-     *          and scores documents in document number order.
-     */
-    public Scorer scorer(IndexReader reader) throws IOException {
-      BooleanScorer2 result = new BooleanScorer2(similarity,
-                                                 minNrShouldMatch);
-
-      for (int i = 0 ; i < weights.size(); i++) {
-        BooleanClause c = (BooleanClause)clauses.get(i);
-        Weight w = (Weight)weights.elementAt(i);
-        Scorer subScorer = w.scorer(reader);
-        if (subScorer != null)
-          result.add(subScorer, c.isRequired(), c.isProhibited());
-        else if (c.isRequired())
-          return null;
-      }
-
-      return result;
-    }
-  }
-
   /** Indicates whether to use good old 1.4 BooleanScorer. */
   private static boolean useScorer14 = false;
 
+  /**
+   * Indicates that 1.4 BooleanScorer should be used.
+   * Being static, this setting is system wide.
+   * Scoring in 1.4 mode may be faster.
+   * But note that unlike the default behavior, it does 
+   * not guarantee that docs are collected in docid
+   * order. In other words, with this setting, 
+   * {@link HitCollector#collect(int,float)} might be
+   * invoked first for docid N and only later for docid N-1. 
+   */
   public static void setUseScorer14(boolean use14) {
     useScorer14 = use14;
   }
 
+  /**
+   * Whether 1.4 BooleanScorer should be used.
+   * @see #setUseScorer14(boolean)
+   */
   public static boolean getUseScorer14() {
     return useScorer14;
   }
 
   protected Weight createWeight(Searcher searcher) throws IOException {
-
-    if (0 < minNrShouldMatch) {
-      // :TODO: should we throw an exception if getUseScorer14 ?
-      return new BooleanWeight2(searcher);
-    }
-
-    return getUseScorer14() ? (Weight) new BooleanWeight(searcher)
-                            : (Weight) new BooleanWeight2(searcher);
+    return new BooleanWeight(searcher);
   }
 
   public Query rewrite(IndexReader reader) throws IOException {
Index: src/java/org/apache/lucene/search/BooleanScorer2.java
===================================================================
--- src/java/org/apache/lucene/search/BooleanScorer2.java	(revision 541956)
+++ src/java/org/apache/lucene/search/BooleanScorer2.java	(working copy)
@@ -32,7 +32,6 @@
   private ArrayList optionalScorers = new ArrayList();
   private ArrayList prohibitedScorers = new ArrayList();
 
-
   private class Coordinator {
     int maxCoord = 0; // to be increased for each non prohibited scorer
     
@@ -66,7 +65,13 @@
 
   /** The number of optionalScorers that need to match (if there are any) */
   private final int minNrShouldMatch;
+  
+  /** Whether it is allowed to return documents out of order.
+   *  This can accelerate the scoring of disjunction queries.  
+   */  
+  private boolean allowDocsOutOfOrder;
 
+
   /** Create a BooleanScorer2.
    * @param similarity The similarity to be used.
    * @param minNrShouldMatch The minimum number of optional added scorers
@@ -74,23 +79,40 @@
    *                         In case no required scorers are added,
    *                         at least one of the optional scorers will have to
    *                         match during the search.
+   * @param allowDocsOutOfOrder Whether it is allowed to return documents out of order.
+   *                            This can accelerate the scoring of disjunction queries.                         
    */
-  public BooleanScorer2(Similarity similarity, int minNrShouldMatch) {
+  public BooleanScorer2(Similarity similarity, int minNrShouldMatch, boolean allowDocsOutOfOrder) {
     super(similarity);
     if (minNrShouldMatch < 0) {
       throw new IllegalArgumentException("Minimum number of optional scorers should not be negative");
     }
     coordinator = new Coordinator();
     this.minNrShouldMatch = minNrShouldMatch;
+    this.allowDocsOutOfOrder = allowDocsOutOfOrder;
   }
 
   /** Create a BooleanScorer2.
    *  In no required scorers are added,
    *  at least one of the optional scorers will have to match during the search.
    * @param similarity The similarity to be used.
+   * @param minNrShouldMatch The minimum number of optional added scorers
+   *                         that should match during the search.
+   *                         In case no required scorers are added,
+   *                         at least one of the optional scorers will have to
+   *                         match during the search.
    */
+  public BooleanScorer2(Similarity similarity, int minNrShouldMatch) {
+    this(similarity, minNrShouldMatch, false);
+  }
+  
+  /** Create a BooleanScorer2.
+   *  In no required scorers are added,
+   *  at least one of the optional scorers will have to match during the search.
+   * @param similarity The similarity to be used.
+   */
   public BooleanScorer2(Similarity similarity) {
-    this(similarity, 0);
+    this(similarity, 0, false);
   }
 
   public void add(final Scorer scorer, boolean required, boolean prohibited) {
@@ -285,8 +307,8 @@
    * <br>When this method is used the {@link #explain(int)} method should not be used.
    */
   public void score(HitCollector hc) throws IOException {
-    if ((requiredScorers.size() == 0) &&
-        prohibitedScorers.size() < 32) {
+    if (allowDocsOutOfOrder && requiredScorers.size() == 0
+            && prohibitedScorers.size() < 32) {
       // fall back to BooleanScorer, scores documents somewhat out of order
       BooleanScorer bs = new BooleanScorer(getSimilarity(), minNrShouldMatch);
       Iterator si = optionalScorers.iterator();
Index: src/test/org/apache/lucene/search/QueryUtils.java
===================================================================
--- src/test/org/apache/lucene/search/QueryUtils.java	(revision 541956)
+++ src/test/org/apache/lucene/search/QueryUtils.java	(working copy)
@@ -106,10 +106,6 @@
       final Weight w = q.weight(s);
       final Scorer scorer = w.scorer(s.getIndexReader());
       
-      if (scorer instanceof BooleanScorer || scorer instanceof BooleanScorer2) {
-        return; // TODO change this if BooleanScorers would once again guarantee docs in order. 
-      }
-
       // FUTURE: ensure scorer.doc()==-1
 
       final int[] sdoc = new int[] {-1};
