You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2015/06/18 09:14:07 UTC

svn commit: r1686145 [1/8] - in /lucene/dev/trunk: lucene/ lucene/analysis/common/src/test/org/apache/lucene/analysis/shingle/ lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/ lucene/benchmark/src/java/org/apache/lucene/benchmark/qua...

Author: jpountz
Date: Thu Jun 18 07:14:05 2015
New Revision: 1686145

URL: http://svn.apache.org/r1686145
Log:
LUCENE-6570: Make BooleanQuery immutable.

Added:
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/ScorerIndexSearcher.java   (with props)
Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/analysis/shingle/ShingleAnalyzerWrapperTest.java
    lucene/dev/trunk/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleQueryMaker.java
    lucene/dev/trunk/lucene/benchmark/src/java/org/apache/lucene/benchmark/quality/utils/SimpleQQParser.java
    lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/BooleanPerceptronClassifier.java
    lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/CachingNaiveBayesClassifier.java
    lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/KNearestNeighborClassifier.java
    lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/SimpleNaiveBayesClassifier.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanClause.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanWeight.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MinShouldMatchSumScorer.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/ScoringRewrite.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/TermCollectingRewrite.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/TopTermsRewrite.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/util/QueryBuilder.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/TestSearch.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/TestSearchForDuplicates.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexableField.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestOmitTf.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestParallelLeafReader.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestApproximationSearchEquivalence.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestBooleanCoord.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestBooleanMinShouldMatch.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestBooleanOr.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestBooleanScorer.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestCachingWrapperQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestComplexExplanations.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestConjunctions.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestCustomSearcherSort.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestElevationComparator.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFieldValueQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFilteredSearch.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFuzzyQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestMatchAllDocsQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestMinShouldMatch2.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestMultiPhraseQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestNeedsScores.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestNot.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestPrefixInBooleanQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSearchAfter.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSimilarity.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSimpleExplanations.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSimpleSearchEquivalence.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSubScorerFreqs.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestTimeLimitingCollector.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestWildcard.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/similarities/TestSimilarity2.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/spans/TestBasics.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanSearchEquivalence.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/spans/TestSpansAdvanced.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/spans/TestSpansAdvanced2.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/util/TestQueryBuilder.java
    lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java
    lucene/dev/trunk/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSorts.java
    lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/DrillDownQuery.java
    lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/DrillSideways.java
    lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysQuery.java
    lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/TestDrillDownQuery.java
    lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java
    lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/highlight/QueryTermExtractor.java
    lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/highlight/WeightedSpanTermExtractor.java
    lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/postingshighlight/MultiTermHighlighting.java
    lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldQuery.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/highlight/MissesTest.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/postingshighlight/TestMultiTermHighlighting.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/postingshighlight/TestPostingsHighlighter.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/postingshighlight/TestPostingsHighlighterRanking.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FastVectorHighlighterTest.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldPhraseListTest.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldQueryTest.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldTermStackTest.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/IndexTimeSynonymTest.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/ScoreOrderFragmentsBuilderTest.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/SimpleFragListBuilderTest.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/SimpleFragmentsBuilderTest.java
    lucene/dev/trunk/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/WeightedFragListBuilderTest.java
    lucene/dev/trunk/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
    lucene/dev/trunk/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoinValidation.java
    lucene/dev/trunk/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
    lucene/dev/trunk/lucene/misc/src/test/org/apache/lucene/search/TestDiversifiedTopDocsCollector.java
    lucene/dev/trunk/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSort.java
    lucene/dev/trunk/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSortRandom.java
    lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/BoostingQuery.java
    lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java
    lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/TermsQuery.java
    lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThis.java
    lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThisQuery.java
    lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/CommonTermsQueryTest.java
    lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/TermsQueryTest.java
    lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/TestCustomScoreExplanations.java
    lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/TestCustomScoreQuery.java
    lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/mlt/TestMoreLikeThis.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/MultiFieldQueryParser.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParserBase.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/QueryParserUtil.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/AnyQueryNodeBuilder.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/BooleanQueryNodeBuilder.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/MatchNoDocsQueryNodeBuilder.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/StandardBooleanQueryNodeBuilder.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/simple/SimpleQueryParser.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/DistanceQuery.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/NotQuery.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/RewriteQuery.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SimpleTermRewriteQuery.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SpanNearClauseFactory.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SrndBooleanQuery.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SrndQuery.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/BooleanQueryBuilder.java
    lucene/dev/trunk/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/TermsQueryBuilder.java
    lucene/dev/trunk/lucene/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiFieldQueryParser.java
    lucene/dev/trunk/lucene/queryparser/src/test/org/apache/lucene/queryparser/classic/TestQueryParser.java
    lucene/dev/trunk/lucene/queryparser/src/test/org/apache/lucene/queryparser/ext/TestExtendableQueryParser.java
    lucene/dev/trunk/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java
    lucene/dev/trunk/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java
    lucene/dev/trunk/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestStandardQP.java
    lucene/dev/trunk/lucene/queryparser/src/test/org/apache/lucene/queryparser/simple/TestSimpleQueryParser.java
    lucene/dev/trunk/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
    lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/bkdtree/BKDPointInBBoxQuery.java
    lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/FuzzyLikeThisQuery.java
    lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestDocValuesNumbersQuery.java
    lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestDocValuesRangeQuery.java
    lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestDocValuesTermsQuery.java
    lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
    lucene/dev/trunk/lucene/suggest/src/java/org/apache/lucene/search/spell/SpellChecker.java
    lucene/dev/trunk/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java
    lucene/dev/trunk/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggesterTest.java
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/analysis/CollationTestBase.java
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/index/BaseDocValuesFormatTestCase.java
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/BaseExplanationTestCase.java
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/SearchEquivalenceTestBase.java
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestHierarchicalDocBuilder.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/MoreLikeThisHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/CurrencyField.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/LatLonType.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/PointType.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/DisMaxQParser.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParser.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/LuceneQueryOptimizer.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/MaxScoreQParser.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/QueryUtils.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SimpleQParserPlugin.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/TermsQParserPlugin.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/facet/FacetRequest.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/SolrPluginUtils.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/QueryResultKeyTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/PolyFieldTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestExtendedDismaxParser.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestMaxScoreQueryParser.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestQueryUtils.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestSearchPerf.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/SolrPluginUtilsTest.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Thu Jun 18 07:14:05 2015
@@ -35,6 +35,9 @@ API Changes
 * LUCENE-6531: PhraseQuery is now immutable and can be built using the
   PhraseQuery.Builder class. (Adrien Grand)
 
+* LUCENE-6570: BooleanQuery is now immutable and can be built using the
+  BooleanQuery.Builder class. (Adrien Grand)
+
 ======================= Lucene 5.3.0 =======================
 
 New Features

Modified: lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/analysis/shingle/ShingleAnalyzerWrapperTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/analysis/shingle/ShingleAnalyzerWrapperTest.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/analysis/shingle/ShingleAnalyzerWrapperTest.java (original)
+++ lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/analysis/shingle/ShingleAnalyzerWrapperTest.java Thu Jun 18 07:14:05 2015
@@ -131,7 +131,7 @@ public class ShingleAnalyzerWrapperTest
    * in the right order and adjacent to each other.
    */
   public void testShingleAnalyzerWrapperBooleanQuery() throws Exception {
-    BooleanQuery q = new BooleanQuery();
+    BooleanQuery.Builder q = new BooleanQuery.Builder();
 
     try (TokenStream ts = analyzer.tokenStream("content", "test sentence")) {
       CharTermAttribute termAtt = ts.addAttribute(CharTermAttribute.class);
@@ -145,7 +145,7 @@ public class ShingleAnalyzerWrapperTest
       ts.end();
     }
 
-    ScoreDoc[] hits = searcher.search(q, 1000).scoreDocs;
+    ScoreDoc[] hits = searcher.search(q.build(), 1000).scoreDocs;
     int[] ranks = new int[] { 1, 2, 0 };
     compareRanks(hits, ranks);
   }

Modified: lucene/dev/trunk/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleQueryMaker.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleQueryMaker.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleQueryMaker.java (original)
+++ lucene/dev/trunk/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleQueryMaker.java Thu Jun 18 07:14:05 2015
@@ -53,10 +53,10 @@ public class SimpleQueryMaker extends Ab
     qq.add(q1);
     Query q2 = new TermQuery(new Term(DocMaker.BODY_FIELD,"simple"));
     qq.add(q2);
-    BooleanQuery bq = new BooleanQuery();
+    BooleanQuery.Builder bq = new BooleanQuery.Builder();
     bq.add(q1,Occur.MUST);
     bq.add(q2,Occur.MUST);
-    qq.add(bq);
+    qq.add(bq.build());
     qq.add(qp.parse("synthetic body"));
     qq.add(qp.parse("\"synthetic body\""));
     qq.add(qp.parse("synthetic text"));

Modified: lucene/dev/trunk/lucene/benchmark/src/java/org/apache/lucene/benchmark/quality/utils/SimpleQQParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/benchmark/src/java/org/apache/lucene/benchmark/quality/utils/SimpleQQParser.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/benchmark/src/java/org/apache/lucene/benchmark/quality/utils/SimpleQQParser.java (original)
+++ lucene/dev/trunk/lucene/benchmark/src/java/org/apache/lucene/benchmark/quality/utils/SimpleQQParser.java Thu Jun 18 07:14:05 2015
@@ -66,11 +66,11 @@ public class SimpleQQParser implements Q
       qp = new QueryParser(indexField, new StandardAnalyzer());
       queryParser.set(qp);
     }
-    BooleanQuery bq = new BooleanQuery();
+    BooleanQuery.Builder bq = new BooleanQuery.Builder();
     for (int i = 0; i < qqNames.length; i++)
       bq.add(qp.parse(QueryParserBase.escape(qq.getValue(qqNames[i]))), BooleanClause.Occur.SHOULD);
     
-    return bq;
+    return bq.build();
   }
 
 }

Modified: lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/BooleanPerceptronClassifier.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/BooleanPerceptronClassifier.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/BooleanPerceptronClassifier.java (original)
+++ lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/BooleanPerceptronClassifier.java Thu Jun 18 07:14:05 2015
@@ -117,13 +117,13 @@ public class BooleanPerceptronClassifier
 
     int batchCount = 0;
 
-    BooleanQuery q = new BooleanQuery();
+    BooleanQuery.Builder q = new BooleanQuery.Builder();
     q.add(new BooleanClause(new WildcardQuery(new Term(classFieldName, "*")), BooleanClause.Occur.MUST));
     if (query != null) {
       q.add(new BooleanClause(query, BooleanClause.Occur.MUST));
     }
     // run the search and use stored field values
-    for (ScoreDoc scoreDoc : indexSearcher.search(q,
+    for (ScoreDoc scoreDoc : indexSearcher.search(q.build(),
             Integer.MAX_VALUE).scoreDocs) {
       StoredDocument doc = indexSearcher.doc(scoreDoc.doc);
 

Modified: lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/CachingNaiveBayesClassifier.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/CachingNaiveBayesClassifier.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/CachingNaiveBayesClassifier.java (original)
+++ lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/CachingNaiveBayesClassifier.java Thu Jun 18 07:14:05 2015
@@ -181,18 +181,18 @@ public class CachingNaiveBayesClassifier
     // if we dont get the answer, but it's relevant we must search it and insert to the cache
     if (insertPoint != null || !justCachedTerms) {
       for (BytesRef cclass : cclasses) {
-        BooleanQuery booleanQuery = new BooleanQuery();
-        BooleanQuery subQuery = new BooleanQuery();
+        BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
+        BooleanQuery.Builder subQuery = new BooleanQuery.Builder();
         for (String textFieldName : textFieldNames) {
           subQuery.add(new BooleanClause(new TermQuery(new Term(textFieldName, word)), BooleanClause.Occur.SHOULD));
         }
-        booleanQuery.add(new BooleanClause(subQuery, BooleanClause.Occur.MUST));
+        booleanQuery.add(new BooleanClause(subQuery.build(), BooleanClause.Occur.MUST));
         booleanQuery.add(new BooleanClause(new TermQuery(new Term(classFieldName, cclass)), BooleanClause.Occur.MUST));
         if (query != null) {
           booleanQuery.add(query, BooleanClause.Occur.MUST);
         }
         TotalHitCountCollector totalHitCountCollector = new TotalHitCountCollector();
-        indexSearcher.search(booleanQuery, totalHitCountCollector);
+        indexSearcher.search(booleanQuery.build(), totalHitCountCollector);
 
         int ret = totalHitCountCollector.getTotalHits();
         if (ret != 0) {

Modified: lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/KNearestNeighborClassifier.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/KNearestNeighborClassifier.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/KNearestNeighborClassifier.java (original)
+++ lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/KNearestNeighborClassifier.java Thu Jun 18 07:14:05 2015
@@ -126,7 +126,7 @@ public class KNearestNeighborClassifier
   }
 
   private TopDocs knnSearch(String text) throws IOException {
-    BooleanQuery mltQuery = new BooleanQuery();
+    BooleanQuery.Builder mltQuery = new BooleanQuery.Builder();
     for (String textFieldName : textFieldNames) {
       mltQuery.add(new BooleanClause(mlt.like(textFieldName, new StringReader(text)), BooleanClause.Occur.SHOULD));
     }
@@ -135,7 +135,7 @@ public class KNearestNeighborClassifier
     if (query != null) {
       mltQuery.add(query, BooleanClause.Occur.MUST);
     }
-    return indexSearcher.search(mltQuery, k);
+    return indexSearcher.search(mltQuery.build(), k);
   }
 
   private List<ClassificationResult<BytesRef>> buildListFromTopDocs(TopDocs topDocs) throws IOException {

Modified: lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/SimpleNaiveBayesClassifier.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/SimpleNaiveBayesClassifier.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/SimpleNaiveBayesClassifier.java (original)
+++ lucene/dev/trunk/lucene/classification/src/java/org/apache/lucene/classification/SimpleNaiveBayesClassifier.java Thu Jun 18 07:14:05 2015
@@ -183,12 +183,12 @@ public class SimpleNaiveBayesClassifier
     int docCount = MultiFields.getTerms(this.leafReader, this.classFieldName).getDocCount();
     if (docCount == -1) { // in case codec doesn't support getDocCount
       TotalHitCountCollector totalHitCountCollector = new TotalHitCountCollector();
-      BooleanQuery q = new BooleanQuery();
+      BooleanQuery.Builder q = new BooleanQuery.Builder();
       q.add(new BooleanClause(new WildcardQuery(new Term(classFieldName, String.valueOf(WildcardQuery.WILDCARD_STRING))), BooleanClause.Occur.MUST));
       if (query != null) {
         q.add(query, BooleanClause.Occur.MUST);
       }
-      indexSearcher.search(q,
+      indexSearcher.search(q.build(),
               totalHitCountCollector);
       docCount = totalHitCountCollector.getTotalHits();
     }
@@ -251,18 +251,18 @@ public class SimpleNaiveBayesClassifier
   }
 
   private int getWordFreqForClass(String word, BytesRef c) throws IOException {
-    BooleanQuery booleanQuery = new BooleanQuery();
-    BooleanQuery subQuery = new BooleanQuery();
+    BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
+    BooleanQuery.Builder subQuery = new BooleanQuery.Builder();
     for (String textFieldName : textFieldNames) {
       subQuery.add(new BooleanClause(new TermQuery(new Term(textFieldName, word)), BooleanClause.Occur.SHOULD));
     }
-    booleanQuery.add(new BooleanClause(subQuery, BooleanClause.Occur.MUST));
+    booleanQuery.add(new BooleanClause(subQuery.build(), BooleanClause.Occur.MUST));
     booleanQuery.add(new BooleanClause(new TermQuery(new Term(classFieldName, c)), BooleanClause.Occur.MUST));
     if (query != null) {
       booleanQuery.add(query, BooleanClause.Occur.MUST);
     }
     TotalHitCountCollector totalHitCountCollector = new TotalHitCountCollector();
-    indexSearcher.search(booleanQuery, totalHitCountCollector);
+    indexSearcher.search(booleanQuery.build(), totalHitCountCollector);
     return totalHitCountCollector.getTotalHits();
   }
 

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanClause.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanClause.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanClause.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanClause.java Thu Jun 18 07:14:05 2015
@@ -20,7 +20,7 @@ package org.apache.lucene.search;
 import java.util.Objects;
 
 /** A clause in a BooleanQuery. */
-public class BooleanClause {
+public final class BooleanClause {
   
   /** Specifies how clauses are to occur in matching documents. */
   public static enum Occur {
@@ -35,7 +35,7 @@ public class BooleanClause {
      * matching documents. For a BooleanQuery with no <code>MUST</code> 
      * clauses one or more <code>SHOULD</code> clauses must match a document 
      * for the BooleanQuery to match.
-     * @see BooleanQuery#setMinimumNumberShouldMatch
+     * @see BooleanQuery.Builder#setMinimumNumberShouldMatch
      */
     SHOULD   { @Override public String toString() { return "";  } },
 
@@ -49,9 +49,9 @@ public class BooleanClause {
 
   /** The query whose matching documents are combined by the boolean query.
    */
-  private Query query;
+  private final Query query;
 
-  private Occur occur;
+  private final Occur occur;
 
 
   /** Constructs a BooleanClause.
@@ -66,18 +66,9 @@ public class BooleanClause {
     return occur;
   }
 
-  public void setOccur(Occur occur) {
-    this.occur = Objects.requireNonNull(occur, "Occur must not be null");
-
-  }
-
   public Query getQuery() {
     return query;
   }
-
-  public void setQuery(Query query) {
-    this.query = Objects.requireNonNull(query, "Query must not be null");
-  }
   
   public boolean isProhibited() {
     return Occur.MUST_NOT == occur;

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java Thu Jun 18 07:14:05 2015
@@ -19,6 +19,8 @@ package org.apache.lucene.search;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
@@ -65,126 +67,139 @@ public class BooleanQuery extends Query
     BooleanQuery.maxClauseCount = maxClauseCount;
   }
 
-  private ArrayList<BooleanClause> clauses = new ArrayList<>();
-  private final boolean disableCoord;
+  /** A builder for boolean queries. */
+  public static class Builder {
+
+    private boolean disableCoord;
+    private int minimumNumberShouldMatch;
+    private final List<BooleanClause> clauses = new ArrayList<>();
+
+    /** Sole constructor. */
+    public Builder() {}
+
+    /**
+     * {@link Similarity#coord(int,int)} may be disabled in scoring, as
+     * appropriate. For example, this score factor does not make sense for most
+     * automatically generated queries, like {@link WildcardQuery} and {@link
+     * FuzzyQuery}.
+     */
+    public Builder setDisableCoord(boolean disableCoord) {
+      this.disableCoord = disableCoord;
+      return this;
+    }
+
+    /**
+     * Specifies a minimum number of the optional BooleanClauses
+     * which must be satisfied.
+     *
+     * <p>
+     * By default no optional clauses are necessary for a match
+     * (unless there are no required clauses).  If this method is used,
+     * then the specified number of clauses is required.
+     * </p>
+     * <p>
+     * Use of this method is totally independent of specifying that
+     * any specific clauses are required (or prohibited).  This number will
+     * only be compared against the number of matching optional clauses.
+     * </p>
+     *
+     * @param min the number of optional clauses that must match
+     */
+    public Builder setMinimumNumberShouldMatch(int min) {
+      this.minimumNumberShouldMatch = min;
+      return this;
+    }
+
+    public Builder add(BooleanClause clause) {
+      add(clause.getQuery(), clause.getOccur());
+      return this;
+    }
+
+    /**
+     * @throws TooManyClauses if the new number of clauses exceeds the maximum clause number
+     */
+    public void add(Query query, Occur occur) {
+      if (clauses.size() >= maxClauseCount) {
+        throw new TooManyClauses();
+      }
+      query = query.clone(); // be defensive
+      clauses.add(new BooleanClause(query, occur));
+    }
+
+    /** Create a new {@link BooleanQuery} based on the parameters that have
+     *  been set on this builder. */
+    public BooleanQuery build() {
+      return new BooleanQuery(disableCoord, minimumNumberShouldMatch, clauses.toArray(new BooleanClause[0]));
+    }
 
-  /** Constructs an empty boolean query. */
-  public BooleanQuery() {
-    disableCoord = false;
   }
 
-  /** Constructs an empty boolean query.
-   *
-   * {@link Similarity#coord(int,int)} may be disabled in scoring, as
-   * appropriate. For example, this score factor does not make sense for most
-   * automatically generated queries, like {@link WildcardQuery} and {@link
-   * FuzzyQuery}.
-   *
-   * @param disableCoord disables {@link Similarity#coord(int,int)} in scoring.
-   */
-  public BooleanQuery(boolean disableCoord) {
+  private final boolean disableCoord;
+  private final int minimumNumberShouldMatch;
+  private final List<BooleanClause> clauses;
+
+  private BooleanQuery(boolean disableCoord, int minimumNumberShouldMatch,
+      BooleanClause[] clauses) {
     this.disableCoord = disableCoord;
+    this.minimumNumberShouldMatch = minimumNumberShouldMatch;
+    this.clauses = Collections.unmodifiableList(Arrays.asList(clauses));
   }
 
-  /** Returns true iff {@link Similarity#coord(int,int)} is disabled in
-   * scoring for this query instance.
-   * @see #BooleanQuery(boolean)
-   */
-  public boolean isCoordDisabled() { return disableCoord; }
-
   /**
-   * Specifies a minimum number of the optional BooleanClauses
-   * which must be satisfied.
-   *
-   * <p>
-   * By default no optional clauses are necessary for a match
-   * (unless there are no required clauses).  If this method is used,
-   * then the specified number of clauses is required.
-   * </p>
-   * <p>
-   * Use of this method is totally independent of specifying that
-   * any specific clauses are required (or prohibited).  This number will
-   * only be compared against the number of matching optional clauses.
-   * </p>
-   *
-   * @param min the number of optional clauses that must match
+   * Return whether the coord factor is disabled.
    */
-  public void setMinimumNumberShouldMatch(int min) {
-    this.minNrShouldMatch = min;
+  public boolean isCoordDisabled() {
+    return disableCoord;
   }
-  protected int minNrShouldMatch = 0;
 
   /**
    * Gets the minimum number of the optional BooleanClauses
    * which must be satisfied.
    */
   public int getMinimumNumberShouldMatch() {
-    return minNrShouldMatch;
-  }
-
-  /** Adds a clause to a boolean query.
-   *
-   * @throws TooManyClauses if the new number of clauses exceeds the maximum clause number
-   * @see #getMaxClauseCount()
-   */
-  public void add(Query query, BooleanClause.Occur occur) {
-    add(new BooleanClause(query, occur));
+    return minimumNumberShouldMatch;
   }
 
-  /** Adds a clause to a boolean query.
-   * @throws TooManyClauses if the new number of clauses exceeds the maximum clause number
-   * @see #getMaxClauseCount()
-   */
-  public void add(BooleanClause clause) {
-    Objects.requireNonNull(clause, "BooleanClause must not be null");
-    if (clauses.size() >= maxClauseCount) {
-      throw new TooManyClauses();
-    }
-
-    clauses.add(clause);
+  /** Return a list of the clauses of this {@link BooleanQuery}. */
+  public List<BooleanClause> clauses() {
+    return clauses;
   }
 
-  /** Returns the set of clauses in this query. */
-  public BooleanClause[] getClauses() {
-    return clauses.toArray(new BooleanClause[clauses.size()]);
-  }
-
-  /** Returns the list of clauses in this query. */
-  public List<BooleanClause> clauses() { return clauses; }
-
   /** Returns an iterator on the clauses in this query. It implements the {@link Iterable} interface to
    * make it possible to do:
    * <pre class="prettyprint">for (BooleanClause clause : booleanQuery) {}</pre>
    */
   @Override
-  public final Iterator<BooleanClause> iterator() { return clauses().iterator(); }
+  public final Iterator<BooleanClause> iterator() {
+    return clauses.iterator();
+  }
 
-  private static BooleanQuery downgradeMustClauseToFilter(BooleanQuery bq) {
-    BooleanQuery clone = bq.clone();
-    clone.clauses.clear();
-    for (BooleanClause clause : bq.clauses()) {
+  private BooleanQuery rewriteNoScoring() {
+    BooleanQuery.Builder newQuery = new BooleanQuery.Builder();
+    // ignore disableCoord, which only matters for scores
+    newQuery.setMinimumNumberShouldMatch(getMinimumNumberShouldMatch());
+    for (BooleanClause clause : clauses) {
       if (clause.getOccur() == Occur.MUST) {
-        clone.add(clause.getQuery(), Occur.FILTER);
+        newQuery.add(clause.getQuery(), Occur.FILTER);
       } else {
-        clone.add(clause);
+        newQuery.add(clause);
       }
     }
-    return clone;
+    return newQuery.build();
   }
 
   @Override
   public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
     BooleanQuery query = this;
     if (needsScores == false) {
-      // we rewrite MUST clauses to FILTER for caching
-      query = downgradeMustClauseToFilter(query);
+      query = rewriteNoScoring();
     }
     return new BooleanWeight(query, searcher, needsScores, disableCoord);
   }
 
   @Override
   public Query rewrite(IndexReader reader) throws IOException {
-    if (minNrShouldMatch == 0 && clauses.size() == 1) {                    // optimize 1-clause queries
+    if (minimumNumberShouldMatch == 0 && clauses.size() == 1) {// optimize 1-clause queries
       BooleanClause c = clauses.get(0);
       if (!c.isProhibited()) {  // just return clause
 
@@ -210,32 +225,24 @@ public class BooleanQuery extends Query
       }
     }
 
-    BooleanQuery clone = null;                    // recursively rewrite
-    for (int i = 0 ; i < clauses.size(); i++) {
-      BooleanClause c = clauses.get(i);
-      Query query = c.getQuery().rewrite(reader);
-      if (query != c.getQuery()) {                     // clause rewrote: must clone
-        if (clone == null) {
-          // The BooleanQuery clone is lazily initialized so only initialize
-          // it if a rewritten clause differs from the original clause (and hasn't been
-          // initialized already).  If nothing differs, the clone isn't needlessly created
-          clone = this.clone();
-        }
-        clone.clauses.set(i, new BooleanClause(query, c.getOccur()));
+    BooleanQuery.Builder builder = new BooleanQuery.Builder();
+    builder.setDisableCoord(isCoordDisabled());
+    builder.setMinimumNumberShouldMatch(getMinimumNumberShouldMatch());
+    boolean actuallyRewritten = false;
+    for (BooleanClause clause : this) {
+      Query query = clause.getQuery();
+      Query rewritten = query.rewrite(reader);
+      if (rewritten != query) {
+        actuallyRewritten = true;
       }
+      builder.add(rewritten, clause.getOccur());
     }
-    if (clone != null) {
-      return clone;                               // some clauses rewrote
-    } else {
-      return this;                                // no clauses rewrote
+    if (actuallyRewritten) {
+      BooleanQuery rewritten = builder.build();
+      rewritten.setBoost(getBoost());
+      return rewritten;
     }
-  }
-
-  @Override @SuppressWarnings("unchecked")
-  public BooleanQuery clone() {
-    BooleanQuery clone = (BooleanQuery)super.clone();
-    clone.clauses = new ArrayList<>(clauses);
-    return clone;
+    return super.rewrite(reader);
   }
 
   /** Prints a user-readable version of this query. */
@@ -247,26 +254,23 @@ public class BooleanQuery extends Query
       buffer.append("(");
     }
 
-    for (int i = 0 ; i < clauses.size(); i++) {
-      BooleanClause c = clauses.get(i);
+    int i = 0;
+    for (BooleanClause c : this) {
       buffer.append(c.getOccur().toString());
 
       Query subQuery = c.getQuery();
-      if (subQuery != null) {
-        if (subQuery instanceof BooleanQuery) {  // wrap sub-bools in parens
-          buffer.append("(");
-          buffer.append(subQuery.toString(field));
-          buffer.append(")");
-        } else {
-          buffer.append(subQuery.toString(field));
-        }
+      if (subQuery instanceof BooleanQuery) {  // wrap sub-bools in parens
+        buffer.append("(");
+        buffer.append(subQuery.toString(field));
+        buffer.append(")");
       } else {
-        buffer.append("null");
+        buffer.append(subQuery.toString(field));
       }
 
-      if (i != clauses.size()-1) {
+      if (i != clauses.size() - 1) {
         buffer.append(" ");
       }
+      i += 1;
     }
 
     if (needParens) {
@@ -285,24 +289,20 @@ public class BooleanQuery extends Query
     return buffer.toString();
   }
 
-  /** Returns true iff <code>o</code> is equal to this. */
   @Override
   public boolean equals(Object o) {
-    if (!(o instanceof BooleanQuery)) {
+    if (super.equals(o) == false) {
       return false;
     }
-    BooleanQuery other = (BooleanQuery)o;
-    return super.equals(o)
-        && this.clauses.equals(other.clauses)
-        && this.getMinimumNumberShouldMatch() == other.getMinimumNumberShouldMatch()
-        && this.disableCoord == other.disableCoord;
+    BooleanQuery that = (BooleanQuery)o;
+    return this.getMinimumNumberShouldMatch() == that.getMinimumNumberShouldMatch()
+        && this.disableCoord == that.disableCoord
+        && clauses.equals(that.clauses);
   }
 
-  /** Returns a hash code value for this object.*/
   @Override
   public int hashCode() {
-    return super.hashCode() ^ clauses.hashCode()
-      + getMinimumNumberShouldMatch() + (disableCoord ? 17:0);
+    return 31 * super.hashCode() + Objects.hash(disableCoord, minimumNumberShouldMatch, clauses);
   }
-  
+
 }

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java Thu Jun 18 07:14:05 2015
@@ -26,7 +26,7 @@ import org.apache.lucene.util.PriorityQu
 
 /**
  * {@link BulkScorer} that is used for pure disjunctions and disjunctions
- * that have low values of {@link BooleanQuery#setMinimumNumberShouldMatch(int)}
+ * that have low values of {@link BooleanQuery.Builder#setMinimumNumberShouldMatch(int)}
  * and dense clauses. This scorer scores documents by batches of 2048 docs.
  */
 final class BooleanScorer extends BulkScorer {

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanWeight.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanWeight.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanWeight.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/BooleanWeight.java Thu Jun 18 07:14:05 2015
@@ -33,33 +33,35 @@ import org.apache.lucene.util.Bits;
 /**
  * Expert: the Weight for BooleanQuery, used to
  * normalize, score and explain these queries.
- *
- * @lucene.experimental
  */
-public class BooleanWeight extends Weight {
+final class BooleanWeight extends Weight {
   /** The Similarity implementation. */
-  protected Similarity similarity;
-  protected final BooleanQuery query;
-  protected ArrayList<Weight> weights;
-  protected int maxCoord;  // num optional + num required
-  private final boolean disableCoord;
-  private final boolean needsScores;
-  private final float coords[];
+  final Similarity similarity;
+  final BooleanQuery query;
+  
+  final ArrayList<Weight> weights;
+  final int maxCoord;  // num optional + num required
+  final boolean disableCoord;
+  final boolean needsScores;
+  final float coords[];
 
-  public BooleanWeight(BooleanQuery query, IndexSearcher searcher, boolean needsScores, boolean disableCoord) throws IOException {
+  BooleanWeight(BooleanQuery query, IndexSearcher searcher, boolean needsScores, boolean disableCoord) throws IOException {
     super(query);
     this.query = query;
     this.needsScores = needsScores;
     this.similarity = searcher.getSimilarity(needsScores);
-    weights = new ArrayList<>(query.clauses().size());
-    for (int i = 0 ; i < query.clauses().size(); i++) {
-      BooleanClause c = query.clauses().get(i);
+    weights = new ArrayList<>();
+    int i = 0;
+    int maxCoord = 0;
+    for (BooleanClause c : query) {
       Weight w = searcher.createWeight(c.getQuery(), needsScores && c.isScoring());
       weights.add(w);
       if (c.isScoring()) {
         maxCoord++;
       }
+      i += 1;
     }
+    this.maxCoord = maxCoord;
     
     // precompute coords (0..N, N).
     // set disableCoord when its explicit, scores are not needed, no scoring clauses, or the sim doesn't use it.
@@ -69,7 +71,7 @@ public class BooleanWeight extends Weigh
     if (maxCoord > 0 && needsScores && disableCoord == false) {
       // compute coords from the similarity, look for any actual ones.
       boolean seenActualCoord = false;
-      for (int i = 1; i < coords.length; i++) {
+      for (i = 1; i < coords.length; i++) {
         coords[i] = coord(i, maxCoord);
         seenActualCoord |= (coords[i] != 1F);
       }
@@ -82,7 +84,7 @@ public class BooleanWeight extends Weigh
   @Override
   public void extractTerms(Set<Term> terms) {
     int i = 0;
-    for (BooleanClause clause : query.clauses()) {
+    for (BooleanClause clause : query) {
       if (clause.isScoring() || (needsScores == false && clause.isProhibited() == false)) {
         weights.get(i).extractTerms(terms);
       }
@@ -93,13 +95,15 @@ public class BooleanWeight extends Weigh
   @Override
   public float getValueForNormalization() throws IOException {
     float sum = 0.0f;
-    for (int i = 0 ; i < weights.size(); i++) {
+    int i = 0;
+    for (BooleanClause clause : query) {
       // call sumOfSquaredWeights for all clauses in case of side effects
       float s = weights.get(i).getValueForNormalization();         // sum sub weights
-      if (query.clauses().get(i).isScoring()) {
+      if (clause.isScoring()) {
         // only add to sum for scoring clauses
         sum += s;
       }
+      i += 1;
     }
 
     sum *= query.getBoost() * query.getBoost();             // boost each sub-weight
@@ -141,7 +145,7 @@ public class BooleanWeight extends Weigh
     boolean fail = false;
     int matchCount = 0;
     int shouldMatchCount = 0;
-    Iterator<BooleanClause> cIter = query.clauses().iterator();
+    Iterator<BooleanClause> cIter = query.iterator();
     for (Iterator<Weight> wIter = weights.iterator(); wIter.hasNext();) {
       Weight w = wIter.next();
       BooleanClause c = cIter.next();
@@ -192,7 +196,7 @@ public class BooleanWeight extends Weigh
   // pkg-private for forcing use of BooleanScorer in tests
   BooleanScorer booleanScorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
     List<BulkScorer> optional = new ArrayList<BulkScorer>();
-    Iterator<BooleanClause> cIter = query.clauses().iterator();
+    Iterator<BooleanClause> cIter = query.iterator();
     for (Weight w  : weights) {
       BooleanClause c =  cIter.next();
       BulkScorer subScorer = w.bulkScorer(context, acceptDocs);
@@ -218,11 +222,11 @@ public class BooleanWeight extends Weigh
       return null;
     }
 
-    if (query.minNrShouldMatch > optional.size()) {
+    if (query.getMinimumNumberShouldMatch() > optional.size()) {
       return null;
     }
 
-    return new BooleanScorer(this, disableCoord, maxCoord, optional, Math.max(1, query.minNrShouldMatch), needsScores);
+    return new BooleanScorer(this, disableCoord, maxCoord, optional, Math.max(1, query.getMinimumNumberShouldMatch()), needsScores);
   }
 
   @Override
@@ -231,7 +235,7 @@ public class BooleanWeight extends Weigh
     if (bulkScorer != null) { // BooleanScorer is applicable
       // TODO: what is the right heuristic here?
       final long costThreshold;
-      if (query.minNrShouldMatch <= 1) {
+      if (query.getMinimumNumberShouldMatch() <= 1) {
         // when all clauses are optional, use BooleanScorer aggressively
         // TODO: is there actually a threshold under which we should rather
         // use the regular scorer?
@@ -258,14 +262,14 @@ public class BooleanWeight extends Weigh
     // initially the user provided value,
     // but if minNrShouldMatch == optional.size(),
     // we will optimize and move these to required, making this 0
-    int minShouldMatch = query.minNrShouldMatch;
+    int minShouldMatch = query.getMinimumNumberShouldMatch();
 
     List<Scorer> required = new ArrayList<>();
     // clauses that are required AND participate in scoring, subset of 'required'
     List<Scorer> requiredScoring = new ArrayList<>();
     List<Scorer> prohibited = new ArrayList<>();
     List<Scorer> optional = new ArrayList<>();
-    Iterator<BooleanClause> cIter = query.clauses().iterator();
+    Iterator<BooleanClause> cIter = query.iterator();
     for (Weight w  : weights) {
       BooleanClause c =  cIter.next();
       Scorer subScorer = w.scorer(context, acceptDocs);

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java Thu Jun 18 07:14:05 2015
@@ -339,9 +339,10 @@ public class FilteredQuery extends Query
       } else {
         // In that case the filter does not implement random-access anyway so
         // we want to take advantage of approximations
-        BooleanQuery rewritten = new BooleanQuery();
-        rewritten.add(queryRewritten, Occur.MUST);
-        rewritten.add(filterRewritten, Occur.FILTER);
+        BooleanQuery.Builder builder = new BooleanQuery.Builder();
+        builder.add(queryRewritten, Occur.MUST);
+        builder.add(filterRewritten, Occur.FILTER);
+        BooleanQuery rewritten = builder.build();
         rewritten.setBoost(getBoost());
         return rewritten;
       }

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java Thu Jun 18 07:14:05 2015
@@ -18,12 +18,8 @@ package org.apache.lucene.search;
  */
 
 import java.io.IOException;
-import java.util.Set;
 
 import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.ToStringUtils;
 
 /**
@@ -34,13 +30,16 @@ public class MatchNoDocsQuery extends Qu
     @Override
     public Query rewrite(IndexReader reader) throws IOException {
         // Rewrite to an empty BooleanQuery so no Scorer or Weight is required
-        return new BooleanQuery();
+        BooleanQuery.Builder builder = new BooleanQuery.Builder();
+        Query rewritten = builder.build();
+        rewritten.setBoost(getBoost());
+        return rewritten;
     }
 
     @Override
     public String toString(String field) {
         StringBuilder buffer = new StringBuilder();
-        buffer.append("_none_");
+        buffer.append("");
         buffer.append(ToStringUtils.boost(getBoost()));
         return buffer.toString();
     }

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MinShouldMatchSumScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MinShouldMatchSumScorer.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MinShouldMatchSumScorer.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MinShouldMatchSumScorer.java Thu Jun 18 07:14:05 2015
@@ -31,7 +31,7 @@ import static org.apache.lucene.search.D
 
 /**
  * A {@link Scorer} for {@link BooleanQuery} when
- * {@link BooleanQuery#setMinimumNumberShouldMatch(int) minShouldMatch} is
+ * {@link BooleanQuery.Builder#setMinimumNumberShouldMatch(int) minShouldMatch} is
  * between 2 and the total number of clauses.
  *
  * This implementation keeps sub scorers in 3 different places:

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java Thu Jun 18 07:14:05 2015
@@ -255,15 +255,17 @@ public class MultiPhraseQuery extends Qu
   @Override
   public Query rewrite(IndexReader reader) {
     if (termArrays.isEmpty()) {
-      BooleanQuery bq = new BooleanQuery();
-      bq.setBoost(getBoost());
-      return bq;
+      MatchNoDocsQuery rewritten = new MatchNoDocsQuery();
+      rewritten.setBoost(getBoost());
+      return rewritten;
     } else if (termArrays.size() == 1) {                 // optimize one-term case
       Term[] terms = termArrays.get(0);
-      BooleanQuery boq = new BooleanQuery(true);
+      BooleanQuery.Builder builder = new BooleanQuery.Builder();
+      builder.setDisableCoord(true);
       for (int i=0; i<terms.length; i++) {
-        boq.add(new TermQuery(terms[i]), BooleanClause.Occur.SHOULD);
+        builder.add(new TermQuery(terms[i]), BooleanClause.Occur.SHOULD);
       }
+      BooleanQuery boq = builder.build();
       boq.setBoost(getBoost());
       return boq;
     } else {

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java Thu Jun 18 07:14:05 2015
@@ -30,6 +30,7 @@ import org.apache.lucene.index.TermConte
 import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.search.BooleanQuery.Builder;
 import org.apache.lucene.util.AttributeSource;
 
 /**
@@ -141,7 +142,7 @@ public abstract class MultiTermQuery ext
    * 
    * @see #setRewriteMethod
    */
-  public static final class TopTermsScoringBooleanQueryRewrite extends TopTermsRewrite<BooleanQuery> {
+  public static final class TopTermsScoringBooleanQueryRewrite extends TopTermsRewrite<BooleanQuery.Builder> {
 
     /** 
      * Create a TopTermsScoringBooleanQueryRewrite for 
@@ -160,12 +161,19 @@ public abstract class MultiTermQuery ext
     }
     
     @Override
-    protected BooleanQuery getTopLevelQuery() {
-      return new BooleanQuery(true);
+    protected BooleanQuery.Builder getTopLevelBuilder() {
+      BooleanQuery.Builder builder = new BooleanQuery.Builder();
+      builder.setDisableCoord(true);
+      return builder;
     }
     
     @Override
-    protected void addClause(BooleanQuery topLevel, Term term, int docCount, float boost, TermContext states) {
+    protected Query build(Builder builder) {
+      return builder.build();
+    }
+    
+    @Override
+    protected void addClause(BooleanQuery.Builder topLevel, Term term, int docCount, float boost, TermContext states) {
       final TermQuery tq = new TermQuery(term, states);
       tq.setBoost(boost);
       topLevel.add(tq, BooleanClause.Occur.SHOULD);
@@ -186,7 +194,7 @@ public abstract class MultiTermQuery ext
    * @see #setRewriteMethod
    */
   public static final class TopTermsBlendedFreqScoringRewrite extends
-      TopTermsRewrite<BooleanQuery> {
+      TopTermsRewrite<BooleanQuery.Builder> {
 
     /**
      * Create a TopTermsBlendedScoringBooleanQueryRewrite for at most
@@ -205,12 +213,19 @@ public abstract class MultiTermQuery ext
     }
 
     @Override
-    protected BooleanQuery getTopLevelQuery() {
-      return new BooleanQuery(true);
+    protected BooleanQuery.Builder getTopLevelBuilder() {
+      BooleanQuery.Builder builder = new BooleanQuery.Builder();
+      builder.setDisableCoord(true);
+      return builder;
     }
 
     @Override
-    protected void addClause(BooleanQuery topLevel, Term term, int docCount,
+    protected Query build(Builder builder) {
+      return builder.build();
+    }
+
+    @Override
+    protected void addClause(BooleanQuery.Builder topLevel, Term term, int docCount,
         float boost, TermContext states) {
       final TermQuery tq = new TermQuery(term, states);
       tq.setBoost(boost);
@@ -222,7 +237,6 @@ public abstract class MultiTermQuery ext
       if (scoreTerms.length <= 1) {
         return;
       }
-      int maxDoc = reader.maxDoc();
       int maxDf = 0;
       long maxTtf = 0;
       for (ScoreTerm scoreTerm : scoreTerms) {
@@ -282,7 +296,7 @@ public abstract class MultiTermQuery ext
    * 
    * @see #setRewriteMethod
    */
-  public static final class TopTermsBoostOnlyBooleanQueryRewrite extends TopTermsRewrite<BooleanQuery> {
+  public static final class TopTermsBoostOnlyBooleanQueryRewrite extends TopTermsRewrite<BooleanQuery.Builder> {
     
     /** 
      * Create a TopTermsBoostOnlyBooleanQueryRewrite for 
@@ -301,12 +315,19 @@ public abstract class MultiTermQuery ext
     }
     
     @Override
-    protected BooleanQuery getTopLevelQuery() {
-      return new BooleanQuery(true);
+    protected BooleanQuery.Builder getTopLevelBuilder() {
+      BooleanQuery.Builder builder = new BooleanQuery.Builder();
+      builder.setDisableCoord(true);
+      return builder;
+    }
+    
+    @Override
+    protected Query build(BooleanQuery.Builder builder) {
+      return builder.build();
     }
     
     @Override
-    protected void addClause(BooleanQuery topLevel, Term term, int docFreq, float boost, TermContext states) {
+    protected void addClause(BooleanQuery.Builder topLevel, Term term, int docFreq, float boost, TermContext states) {
       final Query q = new ConstantScoreQuery(new TermQuery(term, states));
       q.setBoost(boost);
       topLevel.add(q, BooleanClause.Occur.SHOULD);

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java Thu Jun 18 07:14:05 2015
@@ -151,13 +151,13 @@ final class MultiTermQueryConstantScoreW
         final List<TermAndState> collectedTerms = new ArrayList<>();
         if (collectTerms(context, termsEnum, collectedTerms)) {
           // build a boolean query
-          BooleanQuery bq = new BooleanQuery();
+          BooleanQuery.Builder bq = new BooleanQuery.Builder();
           for (TermAndState t : collectedTerms) {
             final TermContext termContext = new TermContext(searcher.getTopReaderContext());
             termContext.register(t.state, context.ord, t.docFreq, t.totalTermFreq);
             bq.add(new TermQuery(new Term(query.field, t.term), termContext), Occur.SHOULD);
           }
-          Query q = new ConstantScoreQuery(bq);
+          Query q = new ConstantScoreQuery(bq.build());
           q.setBoost(score());
           return new WeightOrBitSet(searcher.rewrite(q).createWeight(searcher, needsScores));
         }

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java Thu Jun 18 07:14:05 2015
@@ -264,9 +264,9 @@ public class PhraseQuery extends Query {
   @Override
   public Query rewrite(IndexReader reader) throws IOException {
     if (terms.length == 0) {
-      BooleanQuery bq = new BooleanQuery();
-      bq.setBoost(getBoost());
-      return bq;
+      MatchNoDocsQuery q = new MatchNoDocsQuery();
+      q.setBoost(getBoost());
+      return q;
     } else if (terms.length == 1) {
       TermQuery tq = new TermQuery(terms[0]);
       tq.setBoost(getBoost());

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/ScoringRewrite.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/ScoringRewrite.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/ScoringRewrite.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/ScoringRewrite.java Thu Jun 18 07:14:05 2015
@@ -37,7 +37,7 @@ import org.apache.lucene.util.RamUsageEs
  * the scores as computed by the query.
  * <p>
  * @lucene.internal Only public to be accessible by spans package. */
-public abstract class ScoringRewrite<Q extends Query> extends TermCollectingRewrite<Q> {
+public abstract class ScoringRewrite<B> extends TermCollectingRewrite<B> {
 
   /** A rewrite method that first translates each term into
    *  {@link BooleanClause.Occur#SHOULD} clause in a
@@ -52,14 +52,20 @@ public abstract class ScoringRewrite<Q e
    *  exceeds {@link BooleanQuery#getMaxClauseCount}.
    *
    *  @see MultiTermQuery#setRewriteMethod */
-  public final static ScoringRewrite<BooleanQuery> SCORING_BOOLEAN_REWRITE = new ScoringRewrite<BooleanQuery>() {
+  public final static ScoringRewrite<BooleanQuery.Builder> SCORING_BOOLEAN_REWRITE = new ScoringRewrite<BooleanQuery.Builder>() {
     @Override
-    protected BooleanQuery getTopLevelQuery() {
-      return new BooleanQuery(true);
+    protected BooleanQuery.Builder getTopLevelBuilder() {
+      BooleanQuery.Builder builder = new BooleanQuery.Builder();
+      builder.setDisableCoord(true);
+      return builder;
+    }
+    
+    protected Query build(BooleanQuery.Builder builder) {
+      return builder.build();
     }
     
     @Override
-    protected void addClause(BooleanQuery topLevel, Term term, int docCount,
+    protected void addClause(BooleanQuery.Builder topLevel, Term term, int docCount,
         float boost, TermContext states) {
       final TermQuery tq = new TermQuery(term, states);
       tq.setBoost(boost);
@@ -86,7 +92,7 @@ public abstract class ScoringRewrite<Q e
   public final static RewriteMethod CONSTANT_SCORE_BOOLEAN_REWRITE = new RewriteMethod() {
     @Override
     public Query rewrite(IndexReader reader, MultiTermQuery query) throws IOException {
-      final BooleanQuery bq = SCORING_BOOLEAN_REWRITE.rewrite(reader, query);
+      final Query bq = SCORING_BOOLEAN_REWRITE.rewrite(reader, query);
       // strip the scores off
       final Query result = new ConstantScoreQuery(bq);
       result.setBoost(query.getBoost());
@@ -99,8 +105,8 @@ public abstract class ScoringRewrite<Q e
   protected abstract void checkMaxClauseCount(int count) throws IOException;
   
   @Override
-  public final Q rewrite(final IndexReader reader, final MultiTermQuery query) throws IOException {
-    final Q result = getTopLevelQuery();
+  public final Query rewrite(final IndexReader reader, final MultiTermQuery query) throws IOException {
+    final B builder = getTopLevelBuilder();
     final ParallelArraysTermCollector col = new ParallelArraysTermCollector();
     collectTerms(reader, query, col);
     
@@ -113,10 +119,10 @@ public abstract class ScoringRewrite<Q e
         final int pos = sort[i];
         final Term term = new Term(query.getField(), col.terms.get(pos, new BytesRef()));
         assert termStates[pos].hasOnlyRealTerms() == false || reader.docFreq(term) == termStates[pos].docFreq();
-        addClause(result, term, termStates[pos].docFreq(), query.getBoost() * boost[pos], termStates[pos]);
+        addClause(builder, term, termStates[pos].docFreq(), query.getBoost() * boost[pos], termStates[pos]);
       }
     }
-    return result;
+    return build(builder);
   }
 
   final class ParallelArraysTermCollector extends TermCollector {

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/TermCollectingRewrite.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/TermCollectingRewrite.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/TermCollectingRewrite.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/TermCollectingRewrite.java Thu Jun 18 07:14:05 2015
@@ -20,7 +20,6 @@ package org.apache.lucene.search;
 import java.io.IOException;
 
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Fields;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexReaderContext;
 import org.apache.lucene.index.Term;
@@ -30,18 +29,21 @@ import org.apache.lucene.index.TermsEnum
 import org.apache.lucene.util.AttributeSource;
 import org.apache.lucene.util.BytesRef;
 
-abstract class TermCollectingRewrite<Q extends Query> extends MultiTermQuery.RewriteMethod {
+abstract class TermCollectingRewrite<B> extends MultiTermQuery.RewriteMethod {
   
   
-  /** Return a suitable top-level Query for holding all expanded terms. */
-  protected abstract Q getTopLevelQuery() throws IOException;
-  
-  /** Add a MultiTermQuery term to the top-level query */
-  protected final void addClause(Q topLevel, Term term, int docCount, float boost) throws IOException {
+  /** Return a suitable builder for the top-level Query for holding all expanded terms. */
+  protected abstract B getTopLevelBuilder() throws IOException;
+
+  /** Finalize the creation of the query from the builder. */
+  protected abstract Query build(B builder);
+
+  /** Add a MultiTermQuery term to the top-level query builder. */
+  protected final void addClause(B topLevel, Term term, int docCount, float boost) throws IOException {
     addClause(topLevel, term, docCount, boost, null);
   }
   
-  protected abstract void addClause(Q topLevel, Term term, int docCount, float boost, TermContext states) throws IOException;
+  protected abstract void addClause(B topLevel, Term term, int docCount, float boost, TermContext states) throws IOException;
 
   
   final void collectTerms(IndexReader reader, MultiTermQuery query, TermCollector collector) throws IOException {

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/TopTermsRewrite.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/TopTermsRewrite.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/TopTermsRewrite.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/TopTermsRewrite.java Thu Jun 18 07:14:05 2015
@@ -37,7 +37,7 @@ import org.apache.lucene.util.BytesRefBu
  * via a priority queue.
  * @lucene.internal Only public to be accessible by spans package.
  */
-public abstract class TopTermsRewrite<Q extends Query> extends TermCollectingRewrite<Q> {
+public abstract class TopTermsRewrite<B> extends TermCollectingRewrite<B> {
 
   private final int size;
   
@@ -61,7 +61,7 @@ public abstract class TopTermsRewrite<Q
   protected abstract int getMaxSize();
   
   @Override
-  public final Q rewrite(final IndexReader reader, final MultiTermQuery query) throws IOException {
+  public final Query rewrite(final IndexReader reader, final MultiTermQuery query) throws IOException {
     final int maxSize = Math.min(size, getMaxSize());
     final PriorityQueue<ScoreTerm> stQueue = new PriorityQueue<>();
     collectTerms(reader, query, new TermCollector() {
@@ -154,7 +154,7 @@ public abstract class TopTermsRewrite<Q
       }
     });
     
-    final Q q = getTopLevelQuery();
+    final B b = getTopLevelBuilder();
     final ScoreTerm[] scoreTerms = stQueue.toArray(new ScoreTerm[stQueue.size()]);
     ArrayUtil.timSort(scoreTerms, scoreTermSortByTermComp);
     
@@ -162,9 +162,9 @@ public abstract class TopTermsRewrite<Q
 
     for (final ScoreTerm st : scoreTerms) {
       final Term term = new Term(query.field, st.bytes.toBytesRef());
-      addClause(q, term, st.termState.docFreq(), query.getBoost() * st.boost, st.termState); // add to query
+      addClause(b, term, st.termState.docFreq(), query.getBoost() * st.boost, st.termState); // add to query
     }
-    return q;
+    return build(b);
   }
 
   void adjustScoreTerms(IndexReader reader, ScoreTerm[] scoreTerms) {

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java Thu Jun 18 07:14:05 2015
@@ -80,11 +80,9 @@ public class PayloadSpanUtil {
   private void queryToSpanQuery(Query query, Collection<byte[]> payloads)
       throws IOException {
     if (query instanceof BooleanQuery) {
-      BooleanClause[] queryClauses = ((BooleanQuery) query).getClauses();
-
-      for (int i = 0; i < queryClauses.length; i++) {
-        if (!queryClauses[i].isProhibited()) {
-          queryToSpanQuery(queryClauses[i].getQuery(), payloads);
+      for (BooleanClause clause : (BooleanQuery) query) {
+        if (!clause.isProhibited()) {
+          queryToSpanQuery(clause.getQuery(), payloads);
         }
       }
 

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java Thu Jun 18 07:14:05 2015
@@ -163,10 +163,14 @@ public class SpanMultiTermQueryWrapper<Q
   public final static SpanRewriteMethod SCORING_SPAN_QUERY_REWRITE = new SpanRewriteMethod() {
     private final ScoringRewrite<SpanOrQuery> delegate = new ScoringRewrite<SpanOrQuery>() {
       @Override
-      protected SpanOrQuery getTopLevelQuery() {
+      protected SpanOrQuery getTopLevelBuilder() {
         return new SpanOrQuery();
       }
 
+      protected Query build(SpanOrQuery builder) {
+        return builder;
+      }
+
       @Override
       protected void checkMaxClauseCount(int count) {
         // we accept all terms as SpanOrQuery has no limits
@@ -182,7 +186,7 @@ public class SpanMultiTermQueryWrapper<Q
     
     @Override
     public SpanQuery rewrite(IndexReader reader, MultiTermQuery query) throws IOException {
-      return delegate.rewrite(reader, query);
+      return (SpanQuery) delegate.rewrite(reader, query);
     }
   };
   
@@ -212,11 +216,16 @@ public class SpanMultiTermQueryWrapper<Q
         }
     
         @Override
-        protected SpanOrQuery getTopLevelQuery() {
+        protected SpanOrQuery getTopLevelBuilder() {
           return new SpanOrQuery();
         }
 
         @Override
+        protected Query build(SpanOrQuery builder) {
+          return builder;
+        }
+
+        @Override
         protected void addClause(SpanOrQuery topLevel, Term term, int docFreq, float boost, TermContext states) {
           final SpanTermQuery q = new SpanTermQuery(term, states);
           q.setBoost(boost);
@@ -232,7 +241,7 @@ public class SpanMultiTermQueryWrapper<Q
 
     @Override
     public SpanQuery rewrite(IndexReader reader, MultiTermQuery query) throws IOException {
-      return delegate.rewrite(reader, query);
+      return (SpanQuery) delegate.rewrite(reader, query);
     }
   
     @Override

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/util/QueryBuilder.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/util/QueryBuilder.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/util/QueryBuilder.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/util/QueryBuilder.java Thu Jun 18 07:14:05 2015
@@ -135,7 +135,13 @@ public class QueryBuilder {
     Query query = createFieldQuery(analyzer, BooleanClause.Occur.SHOULD, field, queryText, false, 0);
     if (query instanceof BooleanQuery) {
       BooleanQuery bq = (BooleanQuery) query;
-      bq.setMinimumNumberShouldMatch((int) (fraction * bq.clauses().size()));
+      BooleanQuery.Builder builder = new BooleanQuery.Builder();
+      builder.setDisableCoord(bq.isCoordDisabled());
+      builder.setMinimumNumberShouldMatch((int) (fraction * bq.clauses().size()));
+      for (BooleanClause clause : bq) {
+        builder.add(clause);
+      }
+      query = builder.build();
     }
     return query;
   }
@@ -276,7 +282,8 @@ public class QueryBuilder {
    * Creates simple boolean query from the cached tokenstream contents 
    */
   private Query analyzeBoolean(String field, TokenStream stream) throws IOException {
-    BooleanQuery q = newBooleanQuery(true);
+    BooleanQuery.Builder q = new BooleanQuery.Builder();
+    q.setDisableCoord(true);
 
     TermToBytesRefAttribute termAtt = stream.getAttribute(TermToBytesRefAttribute.class);
     BytesRef bytes = termAtt.getBytesRef();
@@ -288,15 +295,26 @@ public class QueryBuilder {
       q.add(currentQuery, BooleanClause.Occur.SHOULD);
     }
     
-    return q;
+    return q.build();
   }
-  
+
+  private void add(BooleanQuery.Builder q, BooleanQuery current, BooleanClause.Occur operator) {
+    if (current.clauses().isEmpty()) {
+      return;
+    }
+    if (current.clauses().size() == 1) {
+      q.add(current.clauses().iterator().next().getQuery(), operator);
+    } else {
+      q.add(current, operator);
+    }
+  }
+
   /** 
    * Creates complex boolean query from the cached tokenstream contents 
    */
   private Query analyzeMultiBoolean(String field, TokenStream stream, BooleanClause.Occur operator) throws IOException {
-    BooleanQuery q = newBooleanQuery(false);
-    Query currentQuery = null;
+    BooleanQuery.Builder q = newBooleanQuery(false);
+    BooleanQuery.Builder currentQuery = newBooleanQuery(true);
     
     TermToBytesRefAttribute termAtt = stream.getAttribute(TermToBytesRefAttribute.class);
     BytesRef bytes = termAtt.getBytesRef();
@@ -306,23 +324,15 @@ public class QueryBuilder {
     stream.reset();
     while (stream.incrementToken()) {
       termAtt.fillBytesRef();
-      if (posIncrAtt.getPositionIncrement() == 0) {
-        if (!(currentQuery instanceof BooleanQuery)) {
-          Query t = currentQuery;
-          currentQuery = newBooleanQuery(true);
-          ((BooleanQuery)currentQuery).add(t, BooleanClause.Occur.SHOULD);
-        }
-        ((BooleanQuery)currentQuery).add(newTermQuery(new Term(field, BytesRef.deepCopyOf(bytes))), BooleanClause.Occur.SHOULD);
-      } else {
-        if (currentQuery != null) {
-          q.add(currentQuery, operator);
-        }
-        currentQuery = newTermQuery(new Term(field, BytesRef.deepCopyOf(bytes)));
+      if (posIncrAtt.getPositionIncrement() != 0) {
+        add(q, currentQuery.build(), operator);
+        currentQuery = newBooleanQuery(true);
       }
+      currentQuery.add(newTermQuery(new Term(field, BytesRef.deepCopyOf(bytes))), BooleanClause.Occur.SHOULD);
     }
-    q.add(currentQuery, operator);
+    add(q, currentQuery.build(), operator);
     
-    return q;
+    return q.build();
   }
   
   /** 
@@ -399,8 +409,10 @@ public class QueryBuilder {
    * @param disableCoord disable coord
    * @return new BooleanQuery instance
    */
-  protected BooleanQuery newBooleanQuery(boolean disableCoord) {
-    return new BooleanQuery(disableCoord);
+  protected BooleanQuery.Builder newBooleanQuery(boolean disableCoord) {
+    BooleanQuery.Builder builder = new BooleanQuery.Builder();
+    builder.setDisableCoord(disableCoord);
+    return builder;
   }
   
   /**

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/TestSearch.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/TestSearch.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/TestSearch.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/TestSearch.java Thu Jun 18 07:14:05 2015
@@ -24,7 +24,6 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 
 import org.apache.lucene.util.LuceneTestCase;
-
 import org.apache.lucene.store.*;
 import org.apache.lucene.document.*;
 import org.apache.lucene.analysis.*;
@@ -162,10 +161,10 @@ public class TestSearch extends LuceneTe
   private List<Query> buildQueries() {
     List<Query> queries = new ArrayList<>();
 
-    BooleanQuery booleanAB = new BooleanQuery();
+    BooleanQuery.Builder booleanAB = new BooleanQuery.Builder();
     booleanAB.add(new TermQuery(new Term("contents", "a")), BooleanClause.Occur.SHOULD);
     booleanAB.add(new TermQuery(new Term("contents", "b")), BooleanClause.Occur.SHOULD);
-    queries.add(booleanAB);
+    queries.add(booleanAB.build());
 
     PhraseQuery phraseAB = new PhraseQuery("contents", "a", "b");
     queries.add(phraseAB);
@@ -173,10 +172,10 @@ public class TestSearch extends LuceneTe
     PhraseQuery phraseABC = new PhraseQuery("contents", "a", "b", "c");
     queries.add(phraseABC);
 
-    BooleanQuery booleanAC = new BooleanQuery();
+    BooleanQuery.Builder booleanAC = new BooleanQuery.Builder();
     booleanAC.add(new TermQuery(new Term("contents", "a")), BooleanClause.Occur.SHOULD);
     booleanAC.add(new TermQuery(new Term("contents", "c")), BooleanClause.Occur.SHOULD);
-    queries.add(booleanAC);
+    queries.add(booleanAC.build());
 
     PhraseQuery phraseAC = new PhraseQuery("contents", "a", "c");
     queries.add(phraseAC);

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/TestSearchForDuplicates.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/TestSearchForDuplicates.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/TestSearchForDuplicates.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/TestSearchForDuplicates.java Thu Jun 18 07:14:05 2015
@@ -125,12 +125,12 @@ public class TestSearchForDuplicates ext
       searcher = newSearcher(reader);
       hits = null;
 
-      BooleanQuery booleanQuery = new BooleanQuery();
+      BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
       booleanQuery.add(new TermQuery(new Term(PRIORITY_FIELD, HIGH_PRIORITY)), BooleanClause.Occur.SHOULD);
       booleanQuery.add(new TermQuery(new Term(PRIORITY_FIELD, MED_PRIORITY)), BooleanClause.Occur.SHOULD);
-      out.println("Query: " + booleanQuery.toString(PRIORITY_FIELD));
+      out.println("Query: " + booleanQuery.build().toString(PRIORITY_FIELD));
 
-      hits = searcher.search(booleanQuery, MAX_DOCS, sort).scoreDocs;
+      hits = searcher.search(booleanQuery.build(), MAX_DOCS, sort).scoreDocs;
       printHits(out, hits, searcher);
       checkHits(hits, MAX_DOCS, searcher);
 

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexableField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexableField.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexableField.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexableField.java Thu Jun 18 07:14:05 2015
@@ -353,17 +353,17 @@ public class TestIndexableField extends
             assertTrue(vectors == null || vectors.terms(name) == null);
           }
 
-          BooleanQuery bq = new BooleanQuery();
+          BooleanQuery.Builder bq = new BooleanQuery.Builder();
           bq.add(new TermQuery(new Term("id", ""+id)), BooleanClause.Occur.MUST);
           bq.add(new TermQuery(new Term(name, "text")), BooleanClause.Occur.MUST);
-          final TopDocs hits2 = s.search(bq, 1);
+          final TopDocs hits2 = s.search(bq.build(), 1);
           assertEquals(1, hits2.totalHits);
           assertEquals(docID, hits2.scoreDocs[0].doc);
 
-          bq = new BooleanQuery();
+          bq = new BooleanQuery.Builder();
           bq.add(new TermQuery(new Term("id", ""+id)), BooleanClause.Occur.MUST);
           bq.add(new TermQuery(new Term(name, ""+counter)), BooleanClause.Occur.MUST);
-          final TopDocs hits3 = s.search(bq, 1);
+          final TopDocs hits3 = s.search(bq.build(), 1);
           assertEquals(1, hits3.totalHits);
           assertEquals(docID, hits3.scoreDocs[0].doc);
         }

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestOmitTf.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestOmitTf.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestOmitTf.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestOmitTf.java Thu Jun 18 07:14:05 2015
@@ -415,11 +415,11 @@ public class TestOmitTf extends LuceneTe
         
         
         
-    BooleanQuery bq = new BooleanQuery();
+    BooleanQuery.Builder bq = new BooleanQuery.Builder();
     bq.add(q1,Occur.MUST);
     bq.add(q4,Occur.MUST);
         
-    searcher.search(bq,
+    searcher.search(bq.build(),
                     new CountingHitCollector() {
                       @Override
                       public final void collect(int doc) throws IOException {

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java?rev=1686145&r1=1686144&r2=1686145&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java Thu Jun 18 07:14:05 2015
@@ -74,10 +74,10 @@ public class TestParallelCompositeReader
     queryTest(new TermQuery(new Term("f4", "v1")));
     queryTest(new TermQuery(new Term("f4", "v2")));
 
-    BooleanQuery bq1 = new BooleanQuery();
+    BooleanQuery.Builder bq1 = new BooleanQuery.Builder();
     bq1.add(new TermQuery(new Term("f1", "v1")), Occur.MUST);
     bq1.add(new TermQuery(new Term("f4", "v1")), Occur.MUST);
-    queryTest(bq1);
+    queryTest(bq1.build());
   }
 
   public void testRefCounts1() throws IOException {