You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by si...@apache.org on 2012/09/21 19:22:27 UTC

svn commit: r1388574 [42/45] - in /lucene/dev/branches/LUCENE-2878: ./ dev-tools/ dev-tools/eclipse/ dev-tools/eclipse/dot.settings/ dev-tools/idea/ dev-tools/idea/.idea/ dev-tools/idea/.idea/libraries/ dev-tools/idea/lucene/ dev-tools/idea/lucene/anal...

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/spelling/SpellCheckCollatorTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/spelling/SpellCheckCollatorTest.java?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/spelling/SpellCheckCollatorTest.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/spelling/SpellCheckCollatorTest.java Fri Sep 21 17:21:34 2012
@@ -40,30 +40,30 @@ import org.junit.Test;
 
 @Slow
 public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
-	@BeforeClass
-	public static void beforeClass() throws Exception {
- 		initCore("solrconfig-spellcheckcomponent.xml", "schema.xml");
-		assertNull(h.validateUpdate(adoc("id", "0", "lowerfilt", "faith hope and love")));
-		assertNull(h.validateUpdate(adoc("id", "1", "lowerfilt", "faith hope and loaves")));
-		assertNull(h.validateUpdate(adoc("id", "2", "lowerfilt", "fat hops and loaves")));
-		assertNull(h.validateUpdate(adoc("id", "3", "lowerfilt", "faith of homer")));
-		assertNull(h.validateUpdate(adoc("id", "4", "lowerfilt", "fat of homer")));
-		assertNull(h.validateUpdate(adoc("id", "5", "lowerfilt1", "peace")));
-		assertNull(h.validateUpdate(adoc("id", "6", "lowerfilt", "hyphenated word")));
- 		assertNull(h.validateUpdate(adoc("id", "7", "teststop", "Jane filled out a form at Charles De Gaulle")));
- 		assertNull(h.validateUpdate(adoc("id", "8", "teststop", "Dick flew from Heathrow")));
- 		assertNull(h.validateUpdate(adoc("id", "9", "teststop", "Jane is stuck in customs because Spot chewed up the form")));
- 		assertNull(h.validateUpdate(adoc("id", "10", "teststop", "Once in Paris Dick built a fire on the hearth")));
- 		assertNull(h.validateUpdate(adoc("id", "11", "teststop", "Dick waited for Jane as he watched the sparks flow upward")));
- 		assertNull(h.validateUpdate(adoc("id", "12", "teststop", "This June parisian rendez-vous is ruined because of a customs snafu")));
- 		assertNull(h.validateUpdate(adoc("id", "13", "teststop", "partisan political machine")));
-		assertNull(h.validateUpdate(commit()));
-	}
-
-	@Test
-	public void testCollationWithHypens() throws Exception
-	{
-	  SolrCore core = h.getCore();
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+     initCore("solrconfig-spellcheckcomponent.xml", "schema.xml");
+    assertNull(h.validateUpdate(adoc("id", "0", "lowerfilt", "faith hope and love")));
+    assertNull(h.validateUpdate(adoc("id", "1", "lowerfilt", "faith hope and loaves")));
+    assertNull(h.validateUpdate(adoc("id", "2", "lowerfilt", "fat hops and loaves")));
+    assertNull(h.validateUpdate(adoc("id", "3", "lowerfilt", "faith of homer")));
+    assertNull(h.validateUpdate(adoc("id", "4", "lowerfilt", "fat of homer")));
+    assertNull(h.validateUpdate(adoc("id", "5", "lowerfilt1", "peace")));
+    assertNull(h.validateUpdate(adoc("id", "6", "lowerfilt", "hyphenated word")));
+     assertNull(h.validateUpdate(adoc("id", "7", "teststop", "Jane filled out a form at Charles De Gaulle")));
+     assertNull(h.validateUpdate(adoc("id", "8", "teststop", "Dick flew from Heathrow")));
+     assertNull(h.validateUpdate(adoc("id", "9", "teststop", "Jane is stuck in customs because Spot chewed up the form")));
+     assertNull(h.validateUpdate(adoc("id", "10", "teststop", "Once in Paris Dick built a fire on the hearth")));
+     assertNull(h.validateUpdate(adoc("id", "11", "teststop", "Dick waited for Jane as he watched the sparks flow upward")));
+     assertNull(h.validateUpdate(adoc("id", "12", "teststop", "This June parisian rendez-vous is ruined because of a customs snafu")));
+     assertNull(h.validateUpdate(adoc("id", "13", "teststop", "partisan political machine")));
+    assertNull(h.validateUpdate(commit()));
+  }
+
+  @Test
+  public void testCollationWithHypens() throws Exception
+  {
+    SolrCore core = h.getCore();
     SearchComponent speller = core.getSearchComponent("spellcheck");
     assertTrue("speller is null and it shouldn't be", speller != null);
     
@@ -111,12 +111,12 @@ public class SpellCheckCollatorTest exte
     }
 
   }
-	
-	public void testCollateWithOverride() throws Exception
-	{
-	  assertQ(
+
+  public void testCollateWithOverride() throws Exception
+  {
+    assertQ(
       req(
-    	  SpellCheckComponent.COMPONENT_NAME, "true",
+        SpellCheckComponent.COMPONENT_NAME, "true",
         SpellCheckComponent.SPELLCHECK_DICT, "direct",
         SpellingParams.SPELLCHECK_COUNT, "10",   
         SpellingParams.SPELLCHECK_COLLATE, "true",
@@ -130,303 +130,303 @@ public class SpellCheckCollatorTest exte
       ),
       "//lst[@name='spellcheck']/lst[@name='suggestions']/str[@name='collation']='parisian political machine'"
     );
-	  assertQ(
-	      req(
-	        SpellCheckComponent.COMPONENT_NAME, "true",
-	        SpellCheckComponent.SPELLCHECK_DICT, "direct",
-	        SpellingParams.SPELLCHECK_COUNT, "10",   
-	        SpellingParams.SPELLCHECK_COLLATE, "true",
-	        SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "10",
-	        SpellingParams.SPELLCHECK_MAX_COLLATIONS, "10",
-	        "qt", "spellCheckCompRH",
-	        "defType", "edismax",
-	        "qf", "teststop",
-	        "mm", "1",
-	        SpellingParams.SPELLCHECK_COLLATE_PARAM_OVERRIDE + "mm", "100%",
-	        CommonParams.Q, "partisian politcal mashine"
-	      ),
-	     "//lst[@name='spellcheck']/lst[@name='suggestions']/str[@name='collation']='partisan political machine'"
-	   );
+    assertQ(
+        req(
+          SpellCheckComponent.COMPONENT_NAME, "true",
+          SpellCheckComponent.SPELLCHECK_DICT, "direct",
+          SpellingParams.SPELLCHECK_COUNT, "10",
+          SpellingParams.SPELLCHECK_COLLATE, "true",
+          SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "10",
+          SpellingParams.SPELLCHECK_MAX_COLLATIONS, "10",
+          "qt", "spellCheckCompRH",
+          "defType", "edismax",
+          "qf", "teststop",
+          "mm", "1",
+          SpellingParams.SPELLCHECK_COLLATE_PARAM_OVERRIDE + "mm", "100%",
+          CommonParams.Q, "partisian politcal mashine"
+        ),
+       "//lst[@name='spellcheck']/lst[@name='suggestions']/str[@name='collation']='partisan political machine'"
+     );
     
-	}
+  }
+
+  @Test
+  public void testCollateWithFilter() throws Exception
+  {
+    SolrCore core = h.getCore();
+    SearchComponent speller = core.getSearchComponent("spellcheck");
+    assertTrue("speller is null and it shouldn't be", speller != null);
+
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.add(SpellCheckComponent.COMPONENT_NAME, "true");
+    params.add(SpellingParams.SPELLCHECK_BUILD, "true");
+    params.add(SpellingParams.SPELLCHECK_COUNT, "10");
+    params.add(SpellingParams.SPELLCHECK_COLLATE, "true");
+    params.add(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "10");
+    params.add(SpellingParams.SPELLCHECK_MAX_COLLATIONS, "10");
+    params.add(CommonParams.Q, "lowerfilt:(+fauth +home +loane)");
+    params.add(CommonParams.FQ, "NOT(id:1)");
+
+    //Because a FilterQuery is applied which removes doc id#1 from possible hits, we would
+    //not want the collations to return us "lowerfilt:(+faith +hope +loaves)" as this only matches doc id#1.
+    SolrRequestHandler handler = core.getRequestHandler("spellCheckCompRH");
+    SolrQueryResponse rsp = new SolrQueryResponse();
+    rsp.add("responseHeader", new SimpleOrderedMap());
+    SolrQueryRequest req = new LocalSolrQueryRequest(core, params);
+    handler.handleRequest(req, rsp);
+    req.close();
+    NamedList values = rsp.getValues();
+    NamedList spellCheck = (NamedList) values.get("spellcheck");
+    NamedList suggestions = (NamedList) spellCheck.get("suggestions");
+    List<String> collations = suggestions.getAll("collation");
+    assertTrue(collations.size() > 0);
+    for(String collation : collations) {
+      assertTrue(!collation.equals("lowerfilt:(+faith +hope +loaves)"));
+    }
+  }
+
+  @Test
+  public void testCollateWithMultipleRequestHandlers() throws Exception
+  {
+    SolrCore core = h.getCore();
+    SearchComponent speller = core.getSearchComponent("spellcheck");
+    assertTrue("speller is null and it shouldn't be", speller != null);
+
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.add(SpellCheckComponent.COMPONENT_NAME, "true");
+    params.add(SpellingParams.SPELLCHECK_DICT, "multipleFields");
+    params.add(SpellingParams.SPELLCHECK_BUILD, "true");
+    params.add(SpellingParams.SPELLCHECK_COUNT, "10");
+    params.add(SpellingParams.SPELLCHECK_COLLATE, "true");
+    params.add(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "1");
+    params.add(SpellingParams.SPELLCHECK_MAX_COLLATIONS, "1");
+    params.add(CommonParams.Q, "peac");
+
+    //SpellCheckCompRH has no "qf" defined.  It will not find "peace" from "peac" despite it being in the dictionary
+    //because requrying against this Request Handler results in 0 hits.
+    SolrRequestHandler handler = core.getRequestHandler("spellCheckCompRH");
+    SolrQueryResponse rsp = new SolrQueryResponse();
+    rsp.add("responseHeader", new SimpleOrderedMap());
+    SolrQueryRequest req = new LocalSolrQueryRequest(core, params);
+    handler.handleRequest(req, rsp);
+    req.close();
+    NamedList values = rsp.getValues();
+    NamedList spellCheck = (NamedList) values.get("spellcheck");
+    NamedList suggestions = (NamedList) spellCheck.get("suggestions");
+    String singleCollation = (String) suggestions.get("collation");
+    assertNull(singleCollation);
+
+    //SpellCheckCompRH1 has "lowerfilt1" defined in the "qf" param.  It will find "peace" from "peac" because
+    //requrying field "lowerfilt1" returns the hit.
+    params.remove(SpellingParams.SPELLCHECK_BUILD);
+    handler = core.getRequestHandler("spellCheckCompRH1");
+    rsp = new SolrQueryResponse();
+    rsp.add("responseHeader", new SimpleOrderedMap());
+    req = new LocalSolrQueryRequest(core, params);
+    handler.handleRequest(req, rsp);
+    req.close();
+    values = rsp.getValues();
+    spellCheck = (NamedList) values.get("spellcheck");
+    suggestions = (NamedList) spellCheck.get("suggestions");
+    singleCollation = (String) suggestions.get("collation");
+    assertEquals(singleCollation, "peace");
+  }
+
+  @Test
+  public void testExtendedCollate() throws Exception {
+    SolrCore core = h.getCore();
+    SearchComponent speller = core.getSearchComponent("spellcheck");
+    assertTrue("speller is null and it shouldn't be", speller != null);
 
-	@Test
-	public void testCollateWithFilter() throws Exception
-	{
-		SolrCore core = h.getCore();
-		SearchComponent speller = core.getSearchComponent("spellcheck");
-		assertTrue("speller is null and it shouldn't be", speller != null);
-		
-		ModifiableSolrParams params = new ModifiableSolrParams();		
-		params.add(SpellCheckComponent.COMPONENT_NAME, "true");
-		params.add(SpellingParams.SPELLCHECK_BUILD, "true");
-		params.add(SpellingParams.SPELLCHECK_COUNT, "10");		
-		params.add(SpellingParams.SPELLCHECK_COLLATE, "true");
-		params.add(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "10");
-		params.add(SpellingParams.SPELLCHECK_MAX_COLLATIONS, "10");
-		params.add(CommonParams.Q, "lowerfilt:(+fauth +home +loane)");
-		params.add(CommonParams.FQ, "NOT(id:1)");
-		
-		//Because a FilterQuery is applied which removes doc id#1 from possible hits, we would
-		//not want the collations to return us "lowerfilt:(+faith +hope +loaves)" as this only matches doc id#1.
-		SolrRequestHandler handler = core.getRequestHandler("spellCheckCompRH");
-		SolrQueryResponse rsp = new SolrQueryResponse();
-		rsp.add("responseHeader", new SimpleOrderedMap());
-		SolrQueryRequest req = new LocalSolrQueryRequest(core, params);
-		handler.handleRequest(req, rsp);
-		req.close();
-		NamedList values = rsp.getValues();
-		NamedList spellCheck = (NamedList) values.get("spellcheck");
-		NamedList suggestions = (NamedList) spellCheck.get("suggestions");
-		List<String> collations = suggestions.getAll("collation");
-		assertTrue(collations.size() > 0);
-		for(String collation : collations) {
-			assertTrue(!collation.equals("lowerfilt:(+faith +hope +loaves)"));	
-		}
-	}
-	
-	@Test
-	public void testCollateWithMultipleRequestHandlers() throws Exception
-	{
-		SolrCore core = h.getCore();
-		SearchComponent speller = core.getSearchComponent("spellcheck");
-		assertTrue("speller is null and it shouldn't be", speller != null);
-		
-		ModifiableSolrParams params = new ModifiableSolrParams();		
-		params.add(SpellCheckComponent.COMPONENT_NAME, "true");
-		params.add(SpellingParams.SPELLCHECK_DICT, "multipleFields");
-		params.add(SpellingParams.SPELLCHECK_BUILD, "true");
-		params.add(SpellingParams.SPELLCHECK_COUNT, "10");		
-		params.add(SpellingParams.SPELLCHECK_COLLATE, "true");
-		params.add(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "1");
-		params.add(SpellingParams.SPELLCHECK_MAX_COLLATIONS, "1");
-		params.add(CommonParams.Q, "peac");	
-		
-		//SpellCheckCompRH has no "qf" defined.  It will not find "peace" from "peac" despite it being in the dictionary
-		//because requrying against this Request Handler results in 0 hits.	
-		SolrRequestHandler handler = core.getRequestHandler("spellCheckCompRH");
-		SolrQueryResponse rsp = new SolrQueryResponse();
-		rsp.add("responseHeader", new SimpleOrderedMap());
-		SolrQueryRequest req = new LocalSolrQueryRequest(core, params);
-		handler.handleRequest(req, rsp);
-		req.close();
-		NamedList values = rsp.getValues();
-		NamedList spellCheck = (NamedList) values.get("spellcheck");
-		NamedList suggestions = (NamedList) spellCheck.get("suggestions");
-		String singleCollation = (String) suggestions.get("collation");
-		assertNull(singleCollation);
-		
-		//SpellCheckCompRH1 has "lowerfilt1" defined in the "qf" param.  It will find "peace" from "peac" because
-		//requrying field "lowerfilt1" returns the hit.
-		params.remove(SpellingParams.SPELLCHECK_BUILD);
-		handler = core.getRequestHandler("spellCheckCompRH1");
-		rsp = new SolrQueryResponse();
-		rsp.add("responseHeader", new SimpleOrderedMap());
-		req = new LocalSolrQueryRequest(core, params);
-		handler.handleRequest(req, rsp);
-		req.close();
-		values = rsp.getValues();
-		spellCheck = (NamedList) values.get("spellcheck");
-		suggestions = (NamedList) spellCheck.get("suggestions");
-		singleCollation = (String) suggestions.get("collation");
-		assertEquals(singleCollation, "peace");		
-	}
-
-	@Test
-	public void testExtendedCollate() throws Exception {
-		SolrCore core = h.getCore();
-		SearchComponent speller = core.getSearchComponent("spellcheck");
-		assertTrue("speller is null and it shouldn't be", speller != null);
-
-		ModifiableSolrParams params = new ModifiableSolrParams();
-		params.add(CommonParams.QT, "spellCheckCompRH");
-		params.add(CommonParams.Q, "lowerfilt:(+fauth +home +loane)");
-		params.add(SpellingParams.SPELLCHECK_EXTENDED_RESULTS, "true");
-		params.add(SpellCheckComponent.COMPONENT_NAME, "true");
-		params.add(SpellingParams.SPELLCHECK_BUILD, "true");
-		params.add(SpellingParams.SPELLCHECK_COUNT, "10");
-		params.add(SpellingParams.SPELLCHECK_COLLATE, "true");
-
-		// Testing backwards-compatible behavior.
-		// Returns 1 collation as a single string.
-		// All words are "correct" per the dictionary, but this collation would
-		// return no results if tried.
-		SolrRequestHandler handler = core.getRequestHandler("spellCheckCompRH");
-		SolrQueryResponse rsp = new SolrQueryResponse();
-		rsp.add("responseHeader", new SimpleOrderedMap());
-		SolrQueryRequest req = new LocalSolrQueryRequest(core, params);
-		handler.handleRequest(req, rsp);
-		req.close();
-		NamedList values = rsp.getValues();
-		NamedList spellCheck = (NamedList) values.get("spellcheck");
-		NamedList suggestions = (NamedList) spellCheck.get("suggestions");
-		String singleCollation = (String) suggestions.get("collation");
-		assertEquals("lowerfilt:(+faith +homer +loaves)", singleCollation);
-
-		// Testing backwards-compatible response format but will only return a
-		// collation that would return results.
-		params.remove(SpellingParams.SPELLCHECK_BUILD);
-		params.add(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "5");
-		params.add(SpellingParams.SPELLCHECK_MAX_COLLATIONS, "1");
-		handler = core.getRequestHandler("spellCheckCompRH");
-		rsp = new SolrQueryResponse();
-		rsp.add("responseHeader", new SimpleOrderedMap());
-		req = new LocalSolrQueryRequest(core, params);
-		handler.handleRequest(req, rsp);
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.add(CommonParams.QT, "spellCheckCompRH");
+    params.add(CommonParams.Q, "lowerfilt:(+fauth +home +loane)");
+    params.add(SpellingParams.SPELLCHECK_EXTENDED_RESULTS, "true");
+    params.add(SpellCheckComponent.COMPONENT_NAME, "true");
+    params.add(SpellingParams.SPELLCHECK_BUILD, "true");
+    params.add(SpellingParams.SPELLCHECK_COUNT, "10");
+    params.add(SpellingParams.SPELLCHECK_COLLATE, "true");
+
+    // Testing backwards-compatible behavior.
+    // Returns 1 collation as a single string.
+    // All words are "correct" per the dictionary, but this collation would
+    // return no results if tried.
+    SolrRequestHandler handler = core.getRequestHandler("spellCheckCompRH");
+    SolrQueryResponse rsp = new SolrQueryResponse();
+    rsp.add("responseHeader", new SimpleOrderedMap());
+    SolrQueryRequest req = new LocalSolrQueryRequest(core, params);
+    handler.handleRequest(req, rsp);
+    req.close();
+    NamedList values = rsp.getValues();
+    NamedList spellCheck = (NamedList) values.get("spellcheck");
+    NamedList suggestions = (NamedList) spellCheck.get("suggestions");
+    String singleCollation = (String) suggestions.get("collation");
+    assertEquals("lowerfilt:(+faith +homer +loaves)", singleCollation);
+
+    // Testing backwards-compatible response format but will only return a
+    // collation that would return results.
+    params.remove(SpellingParams.SPELLCHECK_BUILD);
+    params.add(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "5");
+    params.add(SpellingParams.SPELLCHECK_MAX_COLLATIONS, "1");
+    handler = core.getRequestHandler("spellCheckCompRH");
+    rsp = new SolrQueryResponse();
+    rsp.add("responseHeader", new SimpleOrderedMap());
+    req = new LocalSolrQueryRequest(core, params);
+    handler.handleRequest(req, rsp);
     req.close();
-		values = rsp.getValues();
-		spellCheck = (NamedList) values.get("spellcheck");
-		suggestions = (NamedList) spellCheck.get("suggestions");
-		singleCollation = (String) suggestions.get("collation");
-		assertEquals("lowerfilt:(+faith +hope +loaves)", singleCollation);
-
-		// Testing returning multiple collations if more than one valid
-		// combination exists.
-		params.remove(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES);
-		params.remove(SpellingParams.SPELLCHECK_MAX_COLLATIONS);
-		params.add(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "10");
-		params.add(SpellingParams.SPELLCHECK_MAX_COLLATIONS, "2");
-		handler = core.getRequestHandler("spellCheckCompRH");
-		rsp = new SolrQueryResponse();
-		rsp.add("responseHeader", new SimpleOrderedMap());
-		req = new LocalSolrQueryRequest(core, params);
-		handler.handleRequest(req, rsp);
-		req.close();
-		values = rsp.getValues();
-		spellCheck = (NamedList) values.get("spellcheck");
-		suggestions = (NamedList) spellCheck.get("suggestions");
-		List<String> collations = suggestions.getAll("collation");
-		assertTrue(collations.size() == 2);
-		for (String multipleCollation : collations) {
-			assertTrue(multipleCollation.equals("lowerfilt:(+faith +hope +love)")
-					|| multipleCollation.equals("lowerfilt:(+faith +hope +loaves)"));
-		}
-
-		// Testing return multiple collations with expanded collation response
-		// format.
-		params.add(SpellingParams.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true");
-		handler = core.getRequestHandler("spellCheckCompRH");
-		rsp = new SolrQueryResponse();
-		rsp.add("responseHeader", new SimpleOrderedMap());
-		req = new LocalSolrQueryRequest(core, params);
-		handler.handleRequest(req, rsp);
-		req.close();
-		values = rsp.getValues();
-		spellCheck = (NamedList) values.get("spellcheck");
-		suggestions = (NamedList) spellCheck.get("suggestions");
-		List<NamedList> expandedCollationList = suggestions.getAll("collation");
-		Set<String> usedcollations = new HashSet<String>();
-		assertTrue(expandedCollationList.size() == 2);
-		for (NamedList expandedCollation : expandedCollationList) {
-			String multipleCollation = (String) expandedCollation.get("collationQuery");
-			assertTrue(multipleCollation.equals("lowerfilt:(+faith +hope +love)")
-					|| multipleCollation.equals("lowerfilt:(+faith +hope +loaves)"));
-			assertTrue(!usedcollations.contains(multipleCollation));
-			usedcollations.add(multipleCollation);
-
-			int hits = (Integer) expandedCollation.get("hits");
-			assertTrue(hits == 1);
-
-			NamedList misspellingsAndCorrections = (NamedList) expandedCollation.get("misspellingsAndCorrections");
-			assertTrue(misspellingsAndCorrections.size() == 3);
-
-			String correctionForFauth = (String) misspellingsAndCorrections.get("fauth");
-			String correctionForHome = (String) misspellingsAndCorrections.get("home");
-			String correctionForLoane = (String) misspellingsAndCorrections.get("loane");
-			assertTrue(correctionForFauth.equals("faith"));
-			assertTrue(correctionForHome.equals("hope"));
-			assertTrue(correctionForLoane.equals("love") || correctionForLoane.equals("loaves"));
-		}
-	}
-	
-	@Test
-	public void testCollateWithGrouping() throws Exception
-	{
-		SolrCore core = h.getCore();
-		SearchComponent speller = core.getSearchComponent("spellcheck");
-		assertTrue("speller is null and it shouldn't be", speller != null);
-		
-		ModifiableSolrParams params = new ModifiableSolrParams();		
-		params.add(SpellCheckComponent.COMPONENT_NAME, "true");
-		params.add(SpellingParams.SPELLCHECK_BUILD, "true");
-		params.add(SpellingParams.SPELLCHECK_COUNT, "10");		
-		params.add(SpellingParams.SPELLCHECK_COLLATE, "true");
-		params.add(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "5");
-		params.add(SpellingParams.SPELLCHECK_MAX_COLLATIONS, "1");
-		params.add(CommonParams.Q, "lowerfilt:(+fauth)");
-		params.add(GroupParams.GROUP, "true");
-		params.add(GroupParams.GROUP_FIELD, "id");
-		
-		//Because a FilterQuery is applied which removes doc id#1 from possible hits, we would
-		//not want the collations to return us "lowerfilt:(+faith +hope +loaves)" as this only matches doc id#1.
-		SolrRequestHandler handler = core.getRequestHandler("spellCheckCompRH");
-		SolrQueryResponse rsp = new SolrQueryResponse();
-		rsp.add("responseHeader", new SimpleOrderedMap());
-		SolrQueryRequest req = new LocalSolrQueryRequest(core, params);
-		handler.handleRequest(req, rsp);
-		req.close();
-		NamedList values = rsp.getValues();
-		NamedList spellCheck = (NamedList) values.get("spellcheck");
-		NamedList suggestions = (NamedList) spellCheck.get("suggestions");
-		List<String> collations = suggestions.getAll("collation");
-		assertTrue(collations.size() == 1);
-	}
-	
-	@Test
-	public void testContextSensitiveCollate() throws Exception {
-		//                     DirectSolrSpellChecker   IndexBasedSpellChecker
-		String[] dictionary = {"direct",                "default_teststop" };
-		for(int i=0 ; i<1 ; i++) {		
-			assertQ(
-				req(
-					"q", "teststop:(flew AND form AND heathrow)", 
-					"qt", "spellCheckCompRH",
-					"indent", "true",
-					SpellCheckComponent.COMPONENT_NAME, "true",
-					SpellCheckComponent.SPELLCHECK_DICT, dictionary[i],
-					SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true", 
-					SpellCheckComponent.SPELLCHECK_COUNT, "10",
-					SpellCheckComponent.SPELLCHECK_ALTERNATIVE_TERM_COUNT, "5",
-					SpellCheckComponent.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST, "0",
-					SpellCheckComponent.SPELLCHECK_COLLATE, "true",
-					SpellCheckComponent.SPELLCHECK_MAX_COLLATION_TRIES, "10",
-					SpellCheckComponent.SPELLCHECK_MAX_COLLATIONS, "1",
-					SpellCheckComponent.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true"
-				),
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='flew']/arr[@name='suggestion']/lst/str[@name='word']='flow'",
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='form']/arr[@name='suggestion']/lst/str[@name='word']='from'",
+    values = rsp.getValues();
+    spellCheck = (NamedList) values.get("spellcheck");
+    suggestions = (NamedList) spellCheck.get("suggestions");
+    singleCollation = (String) suggestions.get("collation");
+    assertEquals("lowerfilt:(+faith +hope +loaves)", singleCollation);
+
+    // Testing returning multiple collations if more than one valid
+    // combination exists.
+    params.remove(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES);
+    params.remove(SpellingParams.SPELLCHECK_MAX_COLLATIONS);
+    params.add(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "10");
+    params.add(SpellingParams.SPELLCHECK_MAX_COLLATIONS, "2");
+    handler = core.getRequestHandler("spellCheckCompRH");
+    rsp = new SolrQueryResponse();
+    rsp.add("responseHeader", new SimpleOrderedMap());
+    req = new LocalSolrQueryRequest(core, params);
+    handler.handleRequest(req, rsp);
+    req.close();
+    values = rsp.getValues();
+    spellCheck = (NamedList) values.get("spellcheck");
+    suggestions = (NamedList) spellCheck.get("suggestions");
+    List<String> collations = suggestions.getAll("collation");
+    assertTrue(collations.size() == 2);
+    for (String multipleCollation : collations) {
+      assertTrue(multipleCollation.equals("lowerfilt:(+faith +hope +love)")
+          || multipleCollation.equals("lowerfilt:(+faith +hope +loaves)"));
+    }
+
+    // Testing return multiple collations with expanded collation response
+    // format.
+    params.add(SpellingParams.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true");
+    handler = core.getRequestHandler("spellCheckCompRH");
+    rsp = new SolrQueryResponse();
+    rsp.add("responseHeader", new SimpleOrderedMap());
+    req = new LocalSolrQueryRequest(core, params);
+    handler.handleRequest(req, rsp);
+    req.close();
+    values = rsp.getValues();
+    spellCheck = (NamedList) values.get("spellcheck");
+    suggestions = (NamedList) spellCheck.get("suggestions");
+    List<NamedList> expandedCollationList = suggestions.getAll("collation");
+    Set<String> usedcollations = new HashSet<String>();
+    assertTrue(expandedCollationList.size() == 2);
+    for (NamedList expandedCollation : expandedCollationList) {
+      String multipleCollation = (String) expandedCollation.get("collationQuery");
+      assertTrue(multipleCollation.equals("lowerfilt:(+faith +hope +love)")
+          || multipleCollation.equals("lowerfilt:(+faith +hope +loaves)"));
+      assertTrue(!usedcollations.contains(multipleCollation));
+      usedcollations.add(multipleCollation);
+
+      int hits = (Integer) expandedCollation.get("hits");
+      assertTrue(hits == 1);
+
+      NamedList misspellingsAndCorrections = (NamedList) expandedCollation.get("misspellingsAndCorrections");
+      assertTrue(misspellingsAndCorrections.size() == 3);
+
+      String correctionForFauth = (String) misspellingsAndCorrections.get("fauth");
+      String correctionForHome = (String) misspellingsAndCorrections.get("home");
+      String correctionForLoane = (String) misspellingsAndCorrections.get("loane");
+      assertTrue(correctionForFauth.equals("faith"));
+      assertTrue(correctionForHome.equals("hope"));
+      assertTrue(correctionForLoane.equals("love") || correctionForLoane.equals("loaves"));
+    }
+  }
+
+  @Test
+  public void testCollateWithGrouping() throws Exception
+  {
+    SolrCore core = h.getCore();
+    SearchComponent speller = core.getSearchComponent("spellcheck");
+    assertTrue("speller is null and it shouldn't be", speller != null);
+
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.add(SpellCheckComponent.COMPONENT_NAME, "true");
+    params.add(SpellingParams.SPELLCHECK_BUILD, "true");
+    params.add(SpellingParams.SPELLCHECK_COUNT, "10");
+    params.add(SpellingParams.SPELLCHECK_COLLATE, "true");
+    params.add(SpellingParams.SPELLCHECK_MAX_COLLATION_TRIES, "5");
+    params.add(SpellingParams.SPELLCHECK_MAX_COLLATIONS, "1");
+    params.add(CommonParams.Q, "lowerfilt:(+fauth)");
+    params.add(GroupParams.GROUP, "true");
+    params.add(GroupParams.GROUP_FIELD, "id");
+
+    //Because a FilterQuery is applied which removes doc id#1 from possible hits, we would
+    //not want the collations to return us "lowerfilt:(+faith +hope +loaves)" as this only matches doc id#1.
+    SolrRequestHandler handler = core.getRequestHandler("spellCheckCompRH");
+    SolrQueryResponse rsp = new SolrQueryResponse();
+    rsp.add("responseHeader", new SimpleOrderedMap());
+    SolrQueryRequest req = new LocalSolrQueryRequest(core, params);
+    handler.handleRequest(req, rsp);
+    req.close();
+    NamedList values = rsp.getValues();
+    NamedList spellCheck = (NamedList) values.get("spellcheck");
+    NamedList suggestions = (NamedList) spellCheck.get("suggestions");
+    List<String> collations = suggestions.getAll("collation");
+    assertTrue(collations.size() == 1);
+  }
+
+  @Test
+  public void testContextSensitiveCollate() throws Exception {
+    //                     DirectSolrSpellChecker   IndexBasedSpellChecker
+    String[] dictionary = {"direct",                "default_teststop" };
+    for(int i=0 ; i<1 ; i++) {
+      assertQ(
+        req(
+          "q", "teststop:(flew AND form AND heathrow)",
+          "qt", "spellCheckCompRH",
+          "indent", "true",
+          SpellCheckComponent.COMPONENT_NAME, "true",
+          SpellCheckComponent.SPELLCHECK_DICT, dictionary[i],
+          SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true",
+          SpellCheckComponent.SPELLCHECK_COUNT, "10",
+          SpellCheckComponent.SPELLCHECK_ALTERNATIVE_TERM_COUNT, "5",
+          SpellCheckComponent.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST, "0",
+          SpellCheckComponent.SPELLCHECK_COLLATE, "true",
+          SpellCheckComponent.SPELLCHECK_MAX_COLLATION_TRIES, "10",
+          SpellCheckComponent.SPELLCHECK_MAX_COLLATIONS, "1",
+          SpellCheckComponent.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true"
+        ),
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='flew']/arr[@name='suggestion']/lst/str[@name='word']='flow'",
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='form']/arr[@name='suggestion']/lst/str[@name='word']='from'",
 /* DirectSolrSpellChecker won't suggest if the edit distance > 2, so we can't test for this one...
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='heathrow']/arr[@name='suggestion']/lst/str[@name='word']='hearth'",
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='heathrow']/arr[@name='suggestion']/lst/str[@name='word']='hearth'",
 */
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/bool[@name='correctlySpelled']='false'",
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/str[@name='collationQuery']='teststop:(flew AND from AND heathrow)'",
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/int[@name='hits']=1",
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/lst[@name='misspellingsAndCorrections']/str[@name='form']='from'"		
-			);
-			
-			assertQ(
-				req(
-					"q", "teststop:(june AND customs)", 
-					"qt", "spellCheckCompRH",
-					"indent", "true",
-					SpellCheckComponent.COMPONENT_NAME, "true",
-					SpellCheckComponent.SPELLCHECK_DICT, dictionary[i],
-					SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true", 
-					SpellCheckComponent.SPELLCHECK_COUNT, "10",
-					SpellCheckComponent.SPELLCHECK_ALTERNATIVE_TERM_COUNT, "5",
-					SpellCheckComponent.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST, "1",
-					SpellCheckComponent.SPELLCHECK_COLLATE, "true",
-					SpellCheckComponent.SPELLCHECK_MAX_COLLATION_TRIES, "10",
-					SpellCheckComponent.SPELLCHECK_MAX_COLLATIONS, "1",
-					SpellCheckComponent.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true"
-				),
-				"//result[@numFound=1]",
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='june']/arr[@name='suggestion']/lst/str[@name='word']='jane'",
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/bool[@name='correctlySpelled']='false'",
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/str[@name='collationQuery']='teststop:(jane AND customs)'",
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/int[@name='hits']=1",
-				"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/lst[@name='misspellingsAndCorrections']/str[@name='june']='jane'"
-			);
-		}				
-	}
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/bool[@name='correctlySpelled']='false'",
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/str[@name='collationQuery']='teststop:(flew AND from AND heathrow)'",
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/int[@name='hits']=1",
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/lst[@name='misspellingsAndCorrections']/str[@name='form']='from'"
+      );
+
+      assertQ(
+        req(
+          "q", "teststop:(june AND customs)",
+          "qt", "spellCheckCompRH",
+          "indent", "true",
+          SpellCheckComponent.COMPONENT_NAME, "true",
+          SpellCheckComponent.SPELLCHECK_DICT, dictionary[i],
+          SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true",
+          SpellCheckComponent.SPELLCHECK_COUNT, "10",
+          SpellCheckComponent.SPELLCHECK_ALTERNATIVE_TERM_COUNT, "5",
+          SpellCheckComponent.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST, "1",
+          SpellCheckComponent.SPELLCHECK_COLLATE, "true",
+          SpellCheckComponent.SPELLCHECK_MAX_COLLATION_TRIES, "10",
+          SpellCheckComponent.SPELLCHECK_MAX_COLLATIONS, "1",
+          SpellCheckComponent.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true"
+        ),
+        "//result[@numFound=1]",
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='june']/arr[@name='suggestion']/lst/str[@name='word']='jane'",
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/bool[@name='correctlySpelled']='false'",
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/str[@name='collationQuery']='teststop:(jane AND customs)'",
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/int[@name='hits']=1",
+        "//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/lst[@name='misspellingsAndCorrections']/str[@name='june']='jane'"
+      );
+    }
+  }
 }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/spelling/SpellPossibilityIteratorTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/spelling/SpellPossibilityIteratorTest.java?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/spelling/SpellPossibilityIteratorTest.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/spelling/SpellPossibilityIteratorTest.java Fri Sep 21 17:21:34 2012
@@ -28,71 +28,71 @@ import org.junit.Before;
 import org.junit.Test;
 
 public class SpellPossibilityIteratorTest extends SolrTestCaseJ4 {
-	private static final Token TOKEN_AYE = new Token("AYE", 0, 3);
-	private static final Token TOKEN_BEE = new Token("BEE", 4, 7);
-	private static final Token TOKEN_AYE_BEE = new Token("AYE BEE", 0, 7);
-	private static final Token TOKEN_CEE = new Token("CEE", 8, 11);
-	
-	private LinkedHashMap<String, Integer> AYE;
-	private LinkedHashMap<String, Integer> BEE;
-	private LinkedHashMap<String, Integer> AYE_BEE;
-	private LinkedHashMap<String, Integer> CEE;
-	
-	@Override
+  private static final Token TOKEN_AYE = new Token("AYE", 0, 3);
+  private static final Token TOKEN_BEE = new Token("BEE", 4, 7);
+  private static final Token TOKEN_AYE_BEE = new Token("AYE BEE", 0, 7);
+  private static final Token TOKEN_CEE = new Token("CEE", 8, 11);
+
+  private LinkedHashMap<String, Integer> AYE;
+  private LinkedHashMap<String, Integer> BEE;
+  private LinkedHashMap<String, Integer> AYE_BEE;
+  private LinkedHashMap<String, Integer> CEE;
+
+  @Override
   @Before
-	public void setUp() throws Exception {
-	  super.setUp();
+  public void setUp() throws Exception {
+    super.setUp();
+
+    AYE = new LinkedHashMap<String, Integer>();
+    AYE.put("I", 0);
+    AYE.put("II", 0);
+    AYE.put("III", 0);
+    AYE.put("IV", 0);
+    AYE.put("V", 0);
+    AYE.put("VI", 0);
+    AYE.put("VII", 0);
+    AYE.put("VIII", 0);
+
+    BEE = new LinkedHashMap<String, Integer>();
+    BEE.put("alpha", 0);
+    BEE.put("beta", 0);
+    BEE.put("gamma", 0);
+    BEE.put("delta", 0);
+    BEE.put("epsilon", 0);
+    BEE.put("zeta", 0);
+    BEE.put("eta", 0);
+    BEE.put("theta", 0);
+    BEE.put("iota", 0);
+
+    AYE_BEE = new LinkedHashMap<String, Integer>();
+    AYE_BEE.put("one-alpha", 0);
+    AYE_BEE.put("two-beta", 0);
+    AYE_BEE.put("three-gamma", 0);
+    AYE_BEE.put("four-delta", 0);
+    AYE_BEE.put("five-epsilon", 0);
+    AYE_BEE.put("six-zeta", 0);
+    AYE_BEE.put("seven-eta", 0);
+    AYE_BEE.put("eight-theta", 0);
+    AYE_BEE.put("nine-iota", 0);
+
+
+    CEE = new LinkedHashMap<String, Integer>();
+    CEE.put("one", 0);
+    CEE.put("two", 0);
+    CEE.put("three", 0);
+    CEE.put("four", 0);
+    CEE.put("five", 0);
+    CEE.put("six", 0);
+    CEE.put("seven", 0);
+    CEE.put("eight", 0);
+    CEE.put("nine", 0);
+    CEE.put("ten", 0);
+  }
 
-		AYE = new LinkedHashMap<String, Integer>();
-		AYE.put("I", 0);
-		AYE.put("II", 0);
-		AYE.put("III", 0);
-		AYE.put("IV", 0);
-		AYE.put("V", 0);
-		AYE.put("VI", 0);
-		AYE.put("VII", 0);
-		AYE.put("VIII", 0);
-		
-		BEE = new LinkedHashMap<String, Integer>();
-		BEE.put("alpha", 0);
-		BEE.put("beta", 0);
-		BEE.put("gamma", 0);
-		BEE.put("delta", 0);
-		BEE.put("epsilon", 0);
-		BEE.put("zeta", 0);
-		BEE.put("eta", 0);
-		BEE.put("theta", 0);
-		BEE.put("iota", 0);
-		
-		AYE_BEE = new LinkedHashMap<String, Integer>();
-		AYE_BEE.put("one-alpha", 0);
-		AYE_BEE.put("two-beta", 0);
-		AYE_BEE.put("three-gamma", 0);
-		AYE_BEE.put("four-delta", 0);
-		AYE_BEE.put("five-epsilon", 0);
-		AYE_BEE.put("six-zeta", 0);
-		AYE_BEE.put("seven-eta", 0);
-		AYE_BEE.put("eight-theta", 0);
-		AYE_BEE.put("nine-iota", 0);
-		
-
-		CEE = new LinkedHashMap<String, Integer>();
-		CEE.put("one", 0);
-		CEE.put("two", 0);
-		CEE.put("three", 0);
-		CEE.put("four", 0);
-		CEE.put("five", 0);
-		CEE.put("six", 0);
-		CEE.put("seven", 0);
-		CEE.put("eight", 0);
-		CEE.put("nine", 0);
-		CEE.put("ten", 0);
-	}
-	
-	@Test
-	public void testScalability() throws Exception {
-	  Map<Token, LinkedHashMap<String, Integer>> lotsaSuggestions = new LinkedHashMap<Token, LinkedHashMap<String, Integer>>();
-	  lotsaSuggestions.put(TOKEN_AYE , AYE);
+  @Test
+  public void testScalability() throws Exception {
+    Map<Token, LinkedHashMap<String, Integer>> lotsaSuggestions = new LinkedHashMap<Token, LinkedHashMap<String, Integer>>();
+    lotsaSuggestions.put(TOKEN_AYE , AYE);
     lotsaSuggestions.put(TOKEN_BEE , BEE);
     lotsaSuggestions.put(TOKEN_CEE , CEE);
     
@@ -112,15 +112,15 @@ public class SpellPossibilityIteratorTes
     lotsaSuggestions.put(new Token("BEE4", 4, 7),  BEE);
     lotsaSuggestions.put(new Token("CEE4", 8, 11), CEE);
     
-		PossibilityIterator iter = new PossibilityIterator(lotsaSuggestions, 1000, 10000, false);
-		int count = 0;
-		while (iter.hasNext()) {			
-			PossibilityIterator.RankedSpellPossibility rsp = iter.next();
-			count++;
-		}
-		assertTrue(count==1000);
-		
-		lotsaSuggestions.put(new Token("AYE_BEE1", 0, 7), AYE_BEE);
+    PossibilityIterator iter = new PossibilityIterator(lotsaSuggestions, 1000, 10000, false);
+    int count = 0;
+    while (iter.hasNext()) {
+      PossibilityIterator.RankedSpellPossibility rsp = iter.next();
+      count++;
+    }
+    assertTrue(count==1000);
+
+    lotsaSuggestions.put(new Token("AYE_BEE1", 0, 7), AYE_BEE);
     lotsaSuggestions.put(new Token("AYE_BEE2", 0, 7), AYE_BEE);
     lotsaSuggestions.put(new Token("AYE_BEE3", 0, 7), AYE_BEE);
     lotsaSuggestions.put(new Token("AYE_BEE4", 0, 7), AYE_BEE);
@@ -131,62 +131,62 @@ public class SpellPossibilityIteratorTes
       count++;
     }
     assertTrue(count<100);
-	}
-	
-	@Test
-	public void testSpellPossibilityIterator() throws Exception {
-	  Map<Token, LinkedHashMap<String, Integer>> suggestions = new LinkedHashMap<Token, LinkedHashMap<String, Integer>>();
-	  suggestions.put(TOKEN_AYE , AYE);
+  }
+
+  @Test
+  public void testSpellPossibilityIterator() throws Exception {
+    Map<Token, LinkedHashMap<String, Integer>> suggestions = new LinkedHashMap<Token, LinkedHashMap<String, Integer>>();
+    suggestions.put(TOKEN_AYE , AYE);
     suggestions.put(TOKEN_BEE , BEE);
     suggestions.put(TOKEN_CEE , CEE);
     
-		PossibilityIterator iter = new PossibilityIterator(suggestions, 1000, 10000, false);
-		int count = 0;
-		while (iter.hasNext()) {
-			
-		  PossibilityIterator.RankedSpellPossibility rsp = iter.next();
-			if(count==0) {
-				assertTrue("I".equals(rsp.corrections.get(0).getCorrection()));
-				assertTrue("alpha".equals(rsp.corrections.get(1).getCorrection()));
-				assertTrue("one".equals(rsp.corrections.get(2).getCorrection()));
-			}
-			count++;
-		}
-		assertTrue(("Three maps (8*9*10) should return 720 iterations but instead returned " + count), count == 720);
-
-		suggestions.remove(TOKEN_CEE);
-		iter = new PossibilityIterator(suggestions, 100, 10000, false);
-		count = 0;
-		while (iter.hasNext()) {
-			iter.next();
-			count++;
-		}
-		assertTrue(("Two maps (8*9) should return 72 iterations but instead returned " + count), count == 72);
-
-		suggestions.remove(TOKEN_BEE);
-		iter = new PossibilityIterator(suggestions, 5, 10000, false);
-		count = 0;
-		while (iter.hasNext()) {
-			iter.next();
-			count++;
-		}
-		assertTrue(("We requested 5 suggestions but got " + count), count == 5);
-
-		suggestions.remove(TOKEN_AYE);
-		iter = new PossibilityIterator(suggestions, Integer.MAX_VALUE, 10000, false);
-		count = 0;
-		while (iter.hasNext()) {
-			iter.next();
-			count++;
-		}
-		assertTrue(("No maps should return 0 iterations but instead returned " + count), count == 0);
-
-	}
-	
-	@Test
+    PossibilityIterator iter = new PossibilityIterator(suggestions, 1000, 10000, false);
+    int count = 0;
+    while (iter.hasNext()) {
+
+      PossibilityIterator.RankedSpellPossibility rsp = iter.next();
+      if(count==0) {
+        assertTrue("I".equals(rsp.corrections.get(0).getCorrection()));
+        assertTrue("alpha".equals(rsp.corrections.get(1).getCorrection()));
+        assertTrue("one".equals(rsp.corrections.get(2).getCorrection()));
+      }
+      count++;
+    }
+    assertTrue(("Three maps (8*9*10) should return 720 iterations but instead returned " + count), count == 720);
+
+    suggestions.remove(TOKEN_CEE);
+    iter = new PossibilityIterator(suggestions, 100, 10000, false);
+    count = 0;
+    while (iter.hasNext()) {
+      iter.next();
+      count++;
+    }
+    assertTrue(("Two maps (8*9) should return 72 iterations but instead returned " + count), count == 72);
+
+    suggestions.remove(TOKEN_BEE);
+    iter = new PossibilityIterator(suggestions, 5, 10000, false);
+    count = 0;
+    while (iter.hasNext()) {
+      iter.next();
+      count++;
+    }
+    assertTrue(("We requested 5 suggestions but got " + count), count == 5);
+
+    suggestions.remove(TOKEN_AYE);
+    iter = new PossibilityIterator(suggestions, Integer.MAX_VALUE, 10000, false);
+    count = 0;
+    while (iter.hasNext()) {
+      iter.next();
+      count++;
+    }
+    assertTrue(("No maps should return 0 iterations but instead returned " + count), count == 0);
+
+  }
+
+  @Test
   public void testOverlappingTokens() throws Exception {
-	  Map<Token, LinkedHashMap<String, Integer>> overlappingSuggestions = new LinkedHashMap<Token, LinkedHashMap<String, Integer>>();
-	  overlappingSuggestions.put(TOKEN_AYE, AYE);
+    Map<Token, LinkedHashMap<String, Integer>> overlappingSuggestions = new LinkedHashMap<Token, LinkedHashMap<String, Integer>>();
+    overlappingSuggestions.put(TOKEN_AYE, AYE);
     overlappingSuggestions.put(TOKEN_BEE, BEE);
     overlappingSuggestions.put(TOKEN_AYE_BEE, AYE_BEE);
     overlappingSuggestions.put(TOKEN_CEE, CEE);

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java Fri Sep 21 17:21:34 2012
@@ -21,6 +21,9 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.solr.BaseDistributedSearchTestCase;
 import org.apache.solr.client.solrj.SolrQuery;
@@ -33,20 +36,21 @@ import org.apache.solr.common.cloud.ZkCo
 import org.apache.solr.common.cloud.ZkNodeProps;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.update.SolrCmdDistributor.Node;
 import org.apache.solr.update.SolrCmdDistributor.Response;
 import org.apache.solr.update.SolrCmdDistributor.StdNode;
+import org.apache.solr.util.DefaultSolrThreadFactory;
 
 public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase {
-  
+  private static ThreadPoolExecutor executor;
   
   public SolrCmdDistributorTest() {
     fixShardCount = true;
     shardCount = 4;
     stress = 0;
   }
-  
 
   public static String getSchemaFile() {
     return "schema.xml";
@@ -73,7 +77,7 @@ public class SolrCmdDistributorTest exte
           getSchemaFile());
       jettys.add(j);
       clients.add(createNewSolrServer(j.getLocalPort()));
-      String shardStr = "localhost:" + j.getLocalPort() + context;
+      String shardStr = "127.0.0.1:" + j.getLocalPort() + context;
       shardsArr[i] = shardStr;
       sb.append(shardStr);
     }
@@ -85,7 +89,7 @@ public class SolrCmdDistributorTest exte
   public void doTest() throws Exception {
     del("*:*");
     
-    SolrCmdDistributor cmdDistrib = new SolrCmdDistributor(8);
+    SolrCmdDistributor cmdDistrib = new SolrCmdDistributor(5, executor);
     
     ModifiableSolrParams params = new ModifiableSolrParams();
     List<Node> nodes = new ArrayList<Node>();
@@ -119,7 +123,7 @@ public class SolrCmdDistributorTest exte
     nodes.add(new StdNode(new ZkCoreNodeProps(nodeProps)));
     
     // add another 2 docs to control and 3 to client
-    cmdDistrib = new SolrCmdDistributor(8);
+    cmdDistrib = new SolrCmdDistributor(5, executor);
     cmd.solrDoc = sdoc("id", 2);
     cmdDistrib.distribAdd(cmd, nodes, params);
     
@@ -152,7 +156,7 @@ public class SolrCmdDistributorTest exte
     DeleteUpdateCommand dcmd = new DeleteUpdateCommand(null);
     dcmd.id = "2";
     
-    cmdDistrib = new SolrCmdDistributor(8);
+    cmdDistrib = new SolrCmdDistributor(5, executor);
     cmdDistrib.distribDelete(dcmd, nodes, params);
     
     cmdDistrib.distribCommit(ccmd, nodes, params);
@@ -171,19 +175,16 @@ public class SolrCmdDistributorTest exte
         .getNumFound();
     assertEquals(results.toString(), 2, numFound);
     
-    // debug stuff
     for (SolrServer c : clients) {
       c.optimize();
-      // distrib optimize is not working right yet, so call it on each client
       //System.out.println(clients.get(0).request(new LukeRequest()));
     }
     
     int id = 5;
     
-    cmdDistrib = new SolrCmdDistributor(8);
+    cmdDistrib = new SolrCmdDistributor(5, executor);
     
-    nodes.clear();
-    int cnt = atLeast(200);
+    int cnt = atLeast(201);
     for (int i = 0; i < cnt; i++) {
       nodes.clear();
       for (SolrServer c : clients) {
@@ -193,25 +194,52 @@ public class SolrCmdDistributorTest exte
         HttpSolrServer httpClient = (HttpSolrServer) c;
         nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP,
             httpClient.getBaseURL(), ZkStateReader.CORE_NAME_PROP, "");
+        System.out.println("node props:" + nodeProps);
         nodes.add(new StdNode(new ZkCoreNodeProps(nodeProps)));
 
       }
+      AddUpdateCommand c = new AddUpdateCommand(null);
+      c.solrDoc = sdoc("id", id++);
+      if (nodes.size() > 0) {
+        cmdDistrib.distribAdd(c, nodes, params);
+      }
+    }
+    
+    nodes.clear();
+    
+    for (SolrServer c : clients) {
+      HttpSolrServer httpClient = (HttpSolrServer) c;
+      nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP,
+          httpClient.getBaseURL(), ZkStateReader.CORE_NAME_PROP, "");
       
-      cmd.solrDoc = sdoc("id", id++);
-      cmdDistrib.distribAdd(cmd, nodes, params);
+      nodes.add(new StdNode(new ZkCoreNodeProps(nodeProps)));
     }
 
-    cmdDistrib.finish();
-    
     cmdDistrib.distribCommit(ccmd, nodes, params);
     
+    
+    cmdDistrib.finish();
+    
     for (SolrServer c : clients) {
       NamedList<Object> resp = c.request(new LukeRequest());
-      System.out.println(resp);
       assertEquals("SOLR-3428: We only did adds - there should be no deletes",
           ((NamedList<Object>) resp.get("index")).get("numDocs"),
           ((NamedList<Object>) resp.get("index")).get("maxDoc"));
     }
 
   }
+  
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 5,
+        TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
+        new DefaultSolrThreadFactory("cmdDistribExecutor"));
+  }
+  
+  @Override
+  public void tearDown() throws Exception {
+    ExecutorUtil.shutdownNowAndAwaitTermination(executor);
+    super.tearDown();
+  }
 }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/TestUpdate.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/TestUpdate.java?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/TestUpdate.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/TestUpdate.java Fri Sep 21 17:21:34 2012
@@ -68,7 +68,7 @@ public class TestUpdate extends SolrTest
     doUpdateTest(new Callable() {
       @Override
       public Object call() throws Exception {
-        commit("softCommit","false");
+        assertU(commit("softCommit","false"));
         return null;
       }
     });
@@ -82,15 +82,15 @@ public class TestUpdate extends SolrTest
 
     long version;
 
-    version = addAndGetVersion(sdoc("id","1", "val_i",5), null);
+    version = addAndGetVersion(sdoc("id","1", "val_i",5, "copyfield_source","a"), null);
     afterUpdate.call();
-    version = addAndGetVersion(sdoc("id","1", "val_is",map("add",10)), null);
+    version = addAndGetVersion(sdoc("id","1", "val_is",map("add",10), "copyfield_source",map("add","b")), null);
     afterUpdate.call();
     version = addAndGetVersion(sdoc("id","1", "val_is",map("add",5)), null);
     afterUpdate.call();
 
-    assertJQ(req("qt","/get", "id","1", "fl","id,*_i,*_is")
-        ,"=={'doc':{'id':'1', 'val_i':5, 'val_is':[10,5]}}"
+    assertJQ(req("qt","/get", "id","1", "fl","id,*_i,*_is,copyfield_*")
+        ,"=={'doc':{'id':'1', 'val_i':5, 'val_is':[10,5], 'copyfield_source':['a','b']}}"     // real-time get should not return stored copyfield targets
     );
 
     version = addAndGetVersion(sdoc("id","1", "val_is",map("add",-1), "val_i",map("set",100)), null);
@@ -101,6 +101,14 @@ public class TestUpdate extends SolrTest
     );
 
 
+    // Do a search to get all stored fields back and make sure that the stored copyfield target only
+    // has one copy of the source.  This may not be supported forever!
+    assertU(commit("softCommit","true"));
+    assertJQ(req("q","*:*", "fl","id,*_i,*_is,copyfield_*")
+        ,"/response/docs/[0]=={'id':'1', 'val_i':100, 'val_is':[10,5,-1], 'copyfield_source':['a','b'], 'copyfield_dest_ss':['a','b']}"
+    );
+
+
     long version2;
     try {
       // try bad version added as a field in the doc

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/UpdateParamsTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/UpdateParamsTest.java?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/UpdateParamsTest.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/UpdateParamsTest.java Fri Sep 21 17:21:34 2012
@@ -54,8 +54,8 @@ public class UpdateParamsTest extends Ab
     
     // First check that the old param behaves as it should
     try {
-    	handler.handleRequestBody(req, rsp);
-    	assertTrue("Old param update.processor should not have any effect anymore", true);
+      handler.handleRequestBody(req, rsp);
+      assertTrue("Old param update.processor should not have any effect anymore", true);
     } catch (Exception e) {
       assertFalse("Got wrong exception while testing update.chain", e.getMessage().equals("unknown UpdateRequestProcessorChain: nonexistant"));
     }
@@ -65,10 +65,10 @@ public class UpdateParamsTest extends Ab
     params.getMap().put(UpdateParams.UPDATE_CHAIN, "nonexistant");    
     req.setParams(params);
     try {
-    	handler.handleRequestBody(req, rsp);
-    	assertFalse("Faulty update.chain parameter not causing an error - i.e. it is not detected", true);
+      handler.handleRequestBody(req, rsp);
+      assertFalse("Faulty update.chain parameter not causing an error - i.e. it is not detected", true);
     } catch (Exception e) {
-    	assertEquals("Got wrong exception while testing update.chain", e.getMessage(), "unknown UpdateRequestProcessorChain: nonexistant");
+      assertEquals("Got wrong exception while testing update.chain", e.getMessage(), "unknown UpdateRequestProcessorChain: nonexistant");
     }
     
   }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/processor/FieldMutatingUpdateProcessorTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/processor/FieldMutatingUpdateProcessorTest.java?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/processor/FieldMutatingUpdateProcessorTest.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/update/processor/FieldMutatingUpdateProcessorTest.java Fri Sep 21 17:21:34 2012
@@ -721,6 +721,58 @@ public class FieldMutatingUpdateProcesso
 
   } 
 
+  public void testCountValues() throws Exception {
+
+    SolrInputDocument d = null;
+
+    // trivial 
+    d = processAdd("count",       
+                   doc(f("id", "1111"),
+                       f("count_field", "aaa", "bbb", "ccc")));
+
+    assertNotNull(d);
+    assertEquals(3, d.getFieldValue("count_field"));
+
+    // edge case: no values to count, means no count 
+    // (use default if you want one)
+    d = processAdd("count",       
+                   doc(f("id", "1111")));
+
+    assertNotNull(d);
+    assertFalse(d.containsKey("count_field"));
+
+    // typical usecase: clone and count 
+    d = processAdd("clone-then-count",       
+                   doc(f("id", "1111"),
+                       f("category", "scifi", "war", "space"),
+                       f("editors", "John W. Campbell"),
+                       f("list_price", 1000)));
+    assertNotNull(d);
+    assertEquals(Arrays.asList("scifi", "war", "space"),
+                 d.getFieldValues("category"));
+    assertEquals(3,
+                 d.getFieldValue("category_count"));
+    assertEquals(Arrays.asList("John W. Campbell"),
+                 d.getFieldValues("editors"));
+    assertEquals(1000,d.getFieldValue("list_price"));
+
+    // typical usecase: clone and count demonstrating default
+    d = processAdd("clone-then-count",       
+                   doc(f("id", "1111"),
+                       f("editors", "Anonymous"),
+                       f("list_price", 1000)));
+    assertNotNull(d);
+    assertEquals(0,
+                 d.getFieldValue("category_count"));
+    assertEquals(Arrays.asList("Anonymous"),
+                 d.getFieldValues("editors"));
+    assertEquals(1000,d.getFieldValue("list_price"));
+
+    
+
+
+  } 
+
   public void testCloneCombinations() throws Exception {
 
     SolrInputDocument d = null;

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/util/TestNumberUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/util/TestNumberUtils.java?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/util/TestNumberUtils.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/util/TestNumberUtils.java Fri Sep 21 17:21:34 2012
@@ -20,6 +20,7 @@ package org.apache.solr.util;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.solr.util.NumberUtils;
 import org.apache.solr.util.BCDUtils;
+import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 
@@ -36,10 +37,9 @@ public class TestNumberUtils extends Luc
     rng = random();
   }
 
-  private static String arrstr(char[] arr, int start, int end) {
-    String str="[";
-    for (int i=start; i<end; i++) str += arr[i]+"("+(int)arr[i]+"),";
-    return str+"]";
+  @AfterClass
+  public static void cleanup() {
+    rng = null;
   }
 
   static int[] special = {0,10,100,1000,10000,Integer.MAX_VALUE, Integer.MIN_VALUE};
@@ -84,8 +84,7 @@ public class TestNumberUtils extends Luc
     return dspecial[((int)j&0x7fffffff) % dspecial.length]* ((i & 0x20)==0?1:-1) + ((i&0x03)-1);
   }
 
-
-  public static void test(Comparable n1, Comparable n2, Converter conv) {
+  public static <T extends Comparable<T>> void test(T n1, T n2, Converter conv) {
     String s1=n1.toString();
     String s2=n2.toString();
     String v1 = conv.toInternal(s1);
@@ -125,8 +124,6 @@ public class TestNumberUtils extends Luc
   public void testConverters()
   {
     int iter=1000;
-    int arrsz=100000;
-    int num=12345;
 
     // INTEGERS
     List<Converter> converters = new ArrayList<Converter>();
@@ -137,9 +134,7 @@ public class TestNumberUtils extends Luc
     
     for( Converter c : converters ) {
       for (int i=0; i<iter; i++) {
-        Comparable n1 = getSpecial();
-        Comparable n2 = getSpecial();
-        test( n1, n2, c );
+        test(getSpecial(), getSpecial(), c );
       }
     }
 
@@ -150,9 +145,7 @@ public class TestNumberUtils extends Luc
     converters.add( new Base100S() );
     for( Converter c : converters ) {
       for (int i=0; i<iter; i++) {
-        Comparable n1 = getLongSpecial();
-        Comparable n2 = getLongSpecial();
-        test( n1, n2, c );
+        test(getLongSpecial(), getLongSpecial(), c );
       }
     }
 
@@ -162,9 +155,7 @@ public class TestNumberUtils extends Luc
     converters.add( new SortFloat() );
     for( Converter c : converters ) {
       for (int i=0; i<iter; i++) {
-        Comparable n1 = getFloatSpecial();
-        Comparable n2 = getFloatSpecial();
-        test( n1, n2, c );
+        test(getFloatSpecial(), getFloatSpecial(), c );
       }
     }
 
@@ -173,9 +164,7 @@ public class TestNumberUtils extends Luc
     converters.add( new SortDouble() );
     for( Converter c : converters ) {
       for (int i=0; i<iter; i++) {
-        Comparable n1 = getDoubleSpecial();
-        Comparable n2 = getDoubleSpecial();
-        test( n1, n2, c );
+        test(getDoubleSpecial(), getDoubleSpecial(), c );
       }
     }
   }

Modified: lucene/dev/branches/LUCENE-2878/solr/example/README.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/README.txt?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/README.txt (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/README.txt Fri Sep 21 17:21:34 2012
@@ -13,54 +13,70 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-Solr example configuration
---------------------------
+Solr example
+------------
+
+This directory contains an instance of the Jetty Servlet container setup to 
+run Solr using an example configuration.
 
-To run the default example configuration, use 
+To run this example:
 
   java -jar start.jar
 
 in this example directory, and when Solr is started connect to 
 
-  http://localhost:8983/solr/admin/
+  http://localhost:8983/solr/
 
 To add documents to the index, use the post.jar (or post.sh script) in
-the exampledocs subdirectory (while Solr is running), for example:
+the example/exampledocs subdirectory (while Solr is running), for example:
 
      cd exampledocs
      java -jar post.jar *.xml
 Or:  sh post.sh *.xml
 
-See also README.txt in the solr subdirectory, and check
-http://wiki.apache.org/solr/SolrResources for a list of tutorials and
-introductory articles.
-
-NOTE: This Solr example server references certain Solr jars outside of
-this server directory for non-core modules with <lib> statements in
-solrconfig.xml.  If you make a copy of this example server and wish
-to use the ExtractingRequestHandler (SolrCell), DataImportHandler (DIH),
-UIMA, the clustering component, or other modules in "contrib",
-you will need to copy the required jars into solr/lib or update the paths to
-the jars in your solrconfig.xml.
-
--SolrHome
-
-By default, start.jar starts Solr in Jetty using the default solr home
-directory of "./solr/" -- To run other example configurations, you can
-speciy the solr.solr.home system property when starting jetty...
+For more information about this example please read...
+
+ * example/solr/README.txt
+   For more information about the "Solr Home" and Solr specific configuration
+ * http://lucene.apache.org/solr/tutorial.html
+   For a Tutorial using this example configuration
+ * http://wiki.apache.org/solr/SolrResources 
+   For a list of other tutorials and introductory articles.
+
+Notes About These Examples
+--------------------------
+
+* SolrHome *
+
+By default, start.jar starts Solr in Jetty using the default Solr Home
+directory of "./solr/" (relative to the working directory of hte servlet 
+container).  To run other example configurations, you can specify the 
+solr.solr.home system property when starting jetty...
 
   java -Dsolr.solr.home=multicore -jar start.jar
-  java -Dsolr.solr.home=example-DIH -jar start.jar
+  java -Dsolr.solr.home=example-DIH/solr -jar start.jar
+
+* References to Jar Files Outside This Directory *
+
+Various example SolrHome dirs contained in this directory may use "<lib>"
+statements in the solrconfig.xml file to reference plugin jars outside of 
+this directory for loading "contrib" plugins via relative paths.  
+
+If you make a copy of this example server and wish to use the 
+ExtractingRequestHandler (SolrCell), DataImportHandler (DIH), UIMA, the 
+clustering component, or any other modules in "contrib", you will need to 
+copy the required jars or update the paths to those jars in your 
+solrconfig.xml.
 
--Logging
+* Logging *
 
-By default, Solr will log to the console. This can be convenient when first
-getting started, but eventually you will want to log to a file. To enable
-logging, you can just pass a system property to Jetty on startup:
+By default, Jetty & Solr will log to the console. This can be convenient when 
+first getting started, but eventually you will want to log to a file. To 
+configure logging, you can just pass a system property to Jetty on startup:
 
   java -Djava.util.logging.config.file=etc/logging.properties -jar start.jar
  
- This will use Java Util Logging to log to a file based on the config in
- etc/logging.properties. Logs will be written in the logs directory. It is
- also possible to setup log4j or other popular logging frameworks.
+This will use Java Util Logging to log to a file based on the config in
+etc/logging.properties. Logs will be written in the logs directory. It is
+also possible to setup log4j or other popular logging frameworks.
 

Modified: lucene/dev/branches/LUCENE-2878/solr/example/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/build.xml?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/build.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/build.xml Fri Sep 21 17:21:34 2012
@@ -33,6 +33,9 @@
   <target name="compile-core"/>
   <target name="compile-test"/>
 
+  <!-- nothing to cover -->
+  <target name="pitest"/>
+
   <target name="resolve" depends="ivy-availability-check,ivy-fail,ivy-configure">
     <sequential>
     <!-- jetty libs in lib/ -->

Modified: lucene/dev/branches/LUCENE-2878/solr/example/cloud-scripts/zkcli.bat
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/cloud-scripts/zkcli.bat?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/cloud-scripts/zkcli.bat (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/cloud-scripts/zkcli.bat Fri Sep 21 17:21:34 2012
@@ -1,12 +1,12 @@
-REM You can override pass the following parameters to this script:
-REM 
-
-set JVM=java
-
-REM  Find location of this script
-
-set SDIR=%~dp0
-if "%SDIR:~-1%"=="\" set SDIR=%SDIR:~0,-1%
-
-     
-"%JVM%" -classpath "%SDIR%\..\solr-webapp\webapp\WEB-INF\lib\*" org.apache.solr.cloud.ZkCLI %*
+REM You can override pass the following parameters to this script:
+REM 
+
+set JVM=java
+
+REM  Find location of this script
+
+set SDIR=%~dp0
+if "%SDIR:~-1%"=="\" set SDIR=%SDIR:~0,-1%
+
+     
+"%JVM%" -classpath "%SDIR%\..\solr-webapp\webapp\WEB-INF\lib\*" org.apache.solr.cloud.ZkCLI %*

Modified: lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/build.xml?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/build.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/build.xml Fri Sep 21 17:21:34 2012
@@ -35,4 +35,7 @@
   <target name="compile-core"/>
   <target name="compile-test"/>
 
+  <!-- nothing to cover -->
+  <target name="pitest"/>
+
 </project>

Modified: lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/db/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/db/conf/solrconfig.xml?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/db/conf/solrconfig.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/db/conf/solrconfig.xml Fri Sep 21 17:21:34 2012
@@ -414,6 +414,22 @@
   -->
   <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
   
+  <!-- ping/healthcheck -->
+  <requestHandler name="/admin/ping" class="solr.PingRequestHandler">
+    <lst name="invariants">
+      <str name="q">solrpingquery</str>
+    </lst>
+    <lst name="defaults">
+      <str name="echoParams">all</str>
+    </lst>
+    <!-- An optional feature of the PingRequestHandler is to configure the 
+         handler with a "healthcheckFile" which can be used to enable/disable 
+         the PingRequestHandler.
+         relative paths are resolved against the data dir 
+      -->
+    <!-- <str name="healthcheckFile">server-enabled.txt</str> -->
+  </requestHandler>
+  
   <!-- Echo the request contents back to the client -->
   <requestHandler name="/debug/dump" class="solr.DumpRequestHandler" >
     <lst name="defaults">

Modified: lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/mail/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/mail/conf/solrconfig.xml?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/mail/conf/solrconfig.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/mail/conf/solrconfig.xml Fri Sep 21 17:21:34 2012
@@ -26,6 +26,13 @@
   -->
   <luceneMatchVersion>LUCENE_50</luceneMatchVersion>
 
+  <!--
+      NOTE: In order to reduce Jar duplication, dataimporthandler-extras 
+      explicitly requires the deps from contrib/extraction.
+      See https://issues.apache.org/jira/browse/SOLR-3848
+  -->
+  <lib dir="../../../../contrib/extraction/lib" />
+
   <lib dir="../../../../contrib/dataimporthandler/lib/" regex=".*jar$" />
   <lib dir="../../../../dist/" regex="apache-solr-dataimporthandler-.*\.jar" />
   
@@ -521,17 +528,6 @@
     </arr>
   </requestHandler>
 
-<!--
-  <requestHandler name="/update/extract" class="org.apache.solr.handler.extraction.ExtractingRequestHandler">
-    <lst name="defaults">
-      <str name="ext.map.Last-Modified">last_modified</str>
-      <bool name="ext.ignore.und.fl">true</bool>
-    </lst>
-  </requestHandler>
--->
-
-
-
   <searchComponent name="termsComp" class="org.apache.solr.handler.component.TermsComponent"/>
 
   <requestHandler name="/autoSuggest" class="org.apache.solr.handler.component.SearchHandler">
@@ -572,6 +568,22 @@
   </requestHandler>
   -->
   <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
+  
+  <!-- ping/healthcheck -->
+  <requestHandler name="/admin/ping" class="solr.PingRequestHandler">
+    <lst name="invariants">
+      <str name="q">solrpingquery</str>
+    </lst>
+    <lst name="defaults">
+      <str name="echoParams">all</str>
+    </lst>
+    <!-- An optional feature of the PingRequestHandler is to configure the 
+         handler with a "healthcheckFile" which can be used to enable/disable 
+         the PingRequestHandler.
+         relative paths are resolved against the data dir 
+      -->
+    <!-- <str name="healthcheckFile">server-enabled.txt</str> -->
+  </requestHandler>
 
   <!-- Echo the request contents back to the client -->
   <requestHandler name="/debug/dump" class="solr.DumpRequestHandler" >

Modified: lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/rss/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/rss/conf/solrconfig.xml?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/rss/conf/solrconfig.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/rss/conf/solrconfig.xml Fri Sep 21 17:21:34 2012
@@ -413,6 +413,22 @@
   -->
   <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
   
+  <!-- ping/healthcheck -->
+  <requestHandler name="/admin/ping" class="solr.PingRequestHandler">
+    <lst name="invariants">
+      <str name="q">solrpingquery</str>
+    </lst>
+    <lst name="defaults">
+      <str name="echoParams">all</str>
+    </lst>
+    <!-- An optional feature of the PingRequestHandler is to configure the 
+         handler with a "healthcheckFile" which can be used to enable/disable 
+         the PingRequestHandler.
+         relative paths are resolved against the data dir 
+      -->
+    <!-- <str name="healthcheckFile">server-enabled.txt</str> -->
+  </requestHandler>
+  
   <!-- Echo the request contents back to the client -->
   <requestHandler name="/debug/dump" class="solr.DumpRequestHandler" >
     <lst name="defaults">

Modified: lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/solr/conf/solr-data-config.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/solr/conf/solr-data-config.xml?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/solr/conf/solr-data-config.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/solr/conf/solr-data-config.xml Fri Sep 21 17:21:34 2012
@@ -17,6 +17,6 @@
 
 <dataConfig>
   <document>
-    <entity name="sep" processor="SolrEntityProcessor" url="http://localhost:8983/solr/db " query="*:*"/>
+    <entity name="sep" processor="SolrEntityProcessor" url="http://127.0.0.1:8983/solr/db " query="*:*"/>
   </document>
 </dataConfig>

Modified: lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/solr/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/solr/conf/solrconfig.xml?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/solr/conf/solrconfig.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/solr/conf/solrconfig.xml Fri Sep 21 17:21:34 2012
@@ -412,6 +412,22 @@
   -->
   <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
   
+  <!-- ping/healthcheck -->
+  <requestHandler name="/admin/ping" class="solr.PingRequestHandler">
+    <lst name="invariants">
+      <str name="q">solrpingquery</str>
+    </lst>
+    <lst name="defaults">
+      <str name="echoParams">all</str>
+    </lst>
+    <!-- An optional feature of the PingRequestHandler is to configure the 
+         handler with a "healthcheckFile" which can be used to enable/disable 
+         the PingRequestHandler.
+         relative paths are resolved against the data dir 
+      -->
+    <!-- <str name="healthcheckFile">server-enabled.txt</str> -->
+  </requestHandler>
+  
   <!-- Echo the request contents back to the client -->
   <requestHandler name="/debug/dump" class="solr.DumpRequestHandler" >
     <lst name="defaults">

Modified: lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/tika/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/tika/conf/solrconfig.xml?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/tika/conf/solrconfig.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/example-DIH/solr/tika/conf/solrconfig.xml Fri Sep 21 17:21:34 2012
@@ -26,7 +26,14 @@
   -->
   <luceneMatchVersion>LUCENE_50</luceneMatchVersion>
 
+  <!--
+      NOTE: In order to reduce Jar duplication, dataimporthandler-extras 
+      explicitly requires the deps from contrib/extraction.
+      See https://issues.apache.org/jira/browse/SOLR-3848
+  -->
   <lib dir="../../../../contrib/extraction/lib" />
+
+  <lib dir="../../../../contrib/dataimporthandler/lib/" regex=".*jar$" />
   <lib dir="../../../../dist/" regex="apache-solr-dataimporthandler-.*\.jar" />
 
   <!-- <indexConfig> section could go here, but we want the defaults -->
@@ -308,6 +315,24 @@
     -->
   </requestHandler>
   
+  <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
+  
+  <!-- ping/healthcheck -->
+  <requestHandler name="/admin/ping" class="solr.PingRequestHandler">
+    <lst name="invariants">
+      <str name="q">solrpingquery</str>
+    </lst>
+    <lst name="defaults">
+      <str name="echoParams">all</str>
+    </lst>
+    <!-- An optional feature of the PingRequestHandler is to configure the 
+         handler with a "healthcheckFile" which can be used to enable/disable 
+         the PingRequestHandler.
+         relative paths are resolved against the data dir 
+      -->
+    <!-- <str name="healthcheckFile">server-enabled.txt</str> -->
+  </requestHandler>
+  
   <!-- config for the admin interface --> 
   <admin>
     <defaultQuery>*:*</defaultQuery>

Modified: lucene/dev/branches/LUCENE-2878/solr/example/solr/README.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/solr/README.txt?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/solr/README.txt (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/solr/README.txt Fri Sep 21 17:21:34 2012
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 
-Example "Solr Home" Directory
+Example Solr Home Directory
 =============================
 
 This directory is provided as an example of what a "Solr Home" directory
@@ -27,28 +27,37 @@ directory when setting up a new instance
 Basic Directory Structure
 -------------------------
 
-The Solr Home directory typically contains the following subdirectories...
+The Solr Home directory typically contains the following...
 
-   conf/
-        This directory is mandatory and must contain your solrconfig.xml
-        and schema.xml.  Any other optional configuration files would also 
-        be kept here.
-
-   data/
-        This directory is the default location where Solr will keep your
-        index, and is used by the replication scripts for dealing with
-        snapshots.  You can override this location in the solrconfig.xml
-        and scripts.conf files. Solr will create this directory if it
-        does not already exist.
-
-   lib/
-        This directory is optional.  If it exists, Solr will load any Jars
-        found in this directory and use them to resolve any "plugins"
-        specified in your solrconfig.xml or schema.xml (ie: Analyzers,
-        Request Handlers, etc...).  Alternatively you can use the <lib>
-        syntax in solrconfig.xml to direct Solr to your plugins.  See the
-        example solrconfig.xml file for details.
-
-   bin/
-        This directory is optional.  It is the default location used for
-        keeping the replication scripts.
+* solr.xml *
+
+This is the primary configuration file Solr looks for when starting.
+This file specifies the list of "SolrCores" it should load, and high 
+level configuration options that should be used for all SolrCores.
+
+Please see the comments in ./solr.xml for more details.
+
+If no solr.xml file is found, then Solr assumes that there should be
+a single SolrCore named "collection1" and that the "Instance Directory" 
+for collection1 should be the same as the Solr Home Directory.
+
+* Individual SolrCore Instance Directories *
+
+Although solr.xml can be configured to look for SolrCore Instance Directories 
+in any path, simple sub-directories of the Solr Home Dir using relative paths 
+are common for many installations.  In this directory you can see the 
+"./collection1" Instance Directory.
+
+* A Shared 'lib' Directory *
+
+Although solr.xml can be configured with an optional "sharedLib" attribute 
+that can point to any path, it is common to use a "./lib" sub-directory of the 
+Solr Home Directory.
+
+* ZooKeeper Files *
+
+When using SolrCloud using the embedded ZooKeeper option for Solr, it is 
+common to have a "zoo.cfg" file and "zoo_data" directories in the Solr Home 
+Directory.  Please see the SolrCloud wiki page for more details...
+
+https://wiki.apache.org/solr/SolrCloud

Modified: lucene/dev/branches/LUCENE-2878/solr/example/solr/collection1/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/example/solr/collection1/conf/schema.xml?rev=1388574&r1=1388573&r2=1388574&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/example/solr/collection1/conf/schema.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/example/solr/collection1/conf/schema.xml Fri Sep 21 17:21:34 2012
@@ -47,14 +47,20 @@
 
 <schema name="example" version="1.5">
   <!-- attribute "name" is the name of this schema and is only used for display purposes.
-       version="x.y" is Solr's version number for the schema syntax and semantics.  It should
-       not normally be changed by applications.
-       1.0: multiValued attribute did not exist, all fields are multiValued by nature
+       version="x.y" is Solr's version number for the schema syntax and 
+       semantics.  It should not normally be changed by applications.
+
+       1.0: multiValued attribute did not exist, all fields are multiValued 
+            by nature
        1.1: multiValued attribute introduced, false by default 
-       1.2: omitTermFreqAndPositions attribute introduced, true by default except for text fields.
+       1.2: omitTermFreqAndPositions attribute introduced, true by default 
+            except for text fields.
        1.3: removed optional field compress feature
-       1.4: default auto-phrase (QueryParser feature) to off
-       1.5: omitNorms defaults to true for primitive field types (int, float, boolean, string...)
+       1.4: autoGeneratePhraseQueries attribute introduced to drive QueryParser
+            behavior when a single string produces multiple tokens.  Defaults 
+            to off for version >= 1.4
+       1.5: omitNorms defaults to true for primitive field types 
+            (int, float, boolean, string...)
      -->
 
  <fields>
@@ -675,11 +681,12 @@
     <!-- A specialized field for geospatial search. If indexed, this fieldType must not be multivalued. -->
     <fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
 
-   <!--
-    A Geohash is a compact representation of a latitude longitude pair in a single field.
-    See http://wiki.apache.org/solr/SpatialSearch
-   -->
-    <fieldtype name="geohash" class="solr.GeoHashField"/>
+    <!-- An alternative geospatial field type new to Solr 4.  It supports multiValued and polygon shapes.
+      For more information about this and other Spatial fields new to Solr 4, see:
+      http://wiki.apache.org/solr/SolrAdaptersForLuceneSpatial4
+    -->
+    <fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
+        geo="true" distErrPct="0.025" maxDetailDist="0.000009" />
 
    <!-- Money/currency field type. See http://wiki.apache.org/solr/MoneyFieldType
         Parameters:
@@ -687,7 +694,7 @@
           precisionStep:   Specifies the precisionStep for the TrieLong field used for the amount
           providerClass:   Lets you plug in other exchange provider backend:
                            solr.FileExchangeRateProvider is the default and takes one parameter:
-                             currencyConfig: name of an xml file holding exhange rates
+                             currencyConfig: name of an xml file holding exchange rates
                            solr.OpenExchangeRatesOrgProvider uses rates from openexchangerates.org:
                              ratesFileLocation: URL or path to rates JSON file (default latest.json on the web)
                              refreshInterval: Number of minutes between each rates fetch (default: 1440, min: 60)