Index: TestComplexPhraseQuery.java
===================================================================
--- TestComplexPhraseQuery.java	(revision 796580)
+++ TestComplexPhraseQuery.java	(working copy)
@@ -35,109 +35,141 @@
 
 public class TestComplexPhraseQuery extends TestCase {
 
-  Analyzer analyzer = new StandardAnalyzer();
+	Analyzer analyzer = new StandardAnalyzer();
+
+	DocData docsContent[] = { new DocData("john smith", "1"),
+			new DocData("johathon smith", "2"),
+			new DocData("john percival smith", "3"),
+			new DocData("jackson waits tom", "4") };
 
-  DocData docsContent[] = { new DocData("john smith", "1"),
-      new DocData("johathon smith", "2"),
-      new DocData("john percival smith", "3"),
-      new DocData("jackson waits tom", "4") };
+	private IndexSearcher searcher;
 
-  private IndexSearcher searcher;
+	String defaultFieldName = "name";
 
-  String defaultFieldName = "name";
+	public void testPhraseWithDoubleQuotes() throws Exception {
+		QueryParser qp = new ComplexPhraseQueryParser(defaultFieldName,
+				analyzer);
 
-  public void testComplexPhrases() throws Exception {
-    checkMatches("\"john smith\"", "1"); // Simple multi-term still works
-    checkMatches("\"j*   smyth~\"", "1,2"); // wildcards and fuzzies are OK in
-    // phrases
-    checkMatches("\"(jo* -john)  smith\"", "2"); // boolean logic works
-    checkMatches("\"jo*  smith\"~2", "1,2,3"); // position logic works.
-    checkMatches("\"jo* [sma TO smZ]\" ", "1,2"); // range queries supported
-    checkMatches("\"john\"", "1,3"); // Simple single-term still works
-    checkMatches("\"(john OR johathon)  smith\"", "1,2"); // boolean logic with
-    // brackets works.
-    checkMatches("\"(jo* -john) smyth~\"", "2"); // boolean logic with
-    // brackets works.
+		// it should parse fine
+		qp.parse("\"lucene \\\"query parser\\\" \"");
+		
+	}
+	
+	public void testCorrectPositions() throws Exception {
+		QueryParser qp = new ComplexPhraseQueryParser(defaultFieldName,
+				analyzer);
+		
+		try {
+			qp.parse("apache software foundation \"query ) parser \"");
+			
+		} catch (ParseException e) {
+			
+			// expect the error message indicates the error is the close parenthesis at column 34 
+			assertTrue(e.toString().contains("line 1, column 34"));
+			
+		}
 
-    // checkMatches("\"john -percival\"", "1"); // not logic doesn't work
-    // currently :(.
+	}
 
-    checkMatches("\"john  nosuchword*\"", ""); // phrases with clauses producing
-    // empty sets
+	public void testComplexPhrases() throws Exception {
+		checkMatches("\"john smith\"", "1"); // Simple multi-term still works
+		checkMatches("\"j*   smyth~\"", "1,2"); // wildcards and fuzzies are OK
+												// in
+		// phrases
+		checkMatches("\"(jo* -john)  smith\"", "2"); // boolean logic works
+		checkMatches("\"jo*  smith\"~2", "1,2,3"); // position logic works.
+		checkMatches("\"jo* [sma TO smZ]\" ", "1,2"); // range queries supported
+		checkMatches("\"john\"", "1,3"); // Simple single-term still works
+		checkMatches("\"(john OR johathon)  smith\"", "1,2"); // boolean logic
+																// with
+		// brackets works.
+		checkMatches("\"(jo* -john) smyth~\"", "2"); // boolean logic with
+		// brackets works.
 
-    checkBadQuery("\"jo*  id:1 smith\""); // mixing fields in a phrase is bad
-    checkBadQuery("\"jo* \"smith\" \""); // phrases inside phrases is bad
-  }
+		// checkMatches("\"john -percival\"", "1"); // not logic doesn't work
+		// currently :(.
 
-  private void checkBadQuery(String qString) {
-    QueryParser qp = new ComplexPhraseQueryParser(defaultFieldName, analyzer);
-    Throwable expected = null;
-    try {
-      qp.parse(qString);
-    } catch (Throwable e) {
-      expected = e;
-    }
-    assertNotNull("Expected parse error in " + qString, expected);
+		checkMatches("\"john  nosuchword*\"", ""); // phrases with clauses
+													// producing
+		// empty sets
 
-  }
+		checkBadQuery("\"jo*  id:1 smith\""); // mixing fields in a phrase is
+												// bad
+		checkBadQuery("\"jo* \"smith\" a \""); // phrases inside phrases is bad
+		
+	}
 
-  private void checkMatches(String qString, String expectedVals)
-      throws Exception {
-    QueryParser qp = new ComplexPhraseQueryParser(defaultFieldName, analyzer);
-    qp.setFuzzyPrefixLength(1); // usually a good idea
+	private void checkBadQuery(String qString) {
+		QueryParser qp = new ComplexPhraseQueryParser(defaultFieldName,
+				analyzer);
+		Throwable expected = null;
+		try {
+			qp.parse(qString);
+		} catch (Throwable e) {
+			expected = e;
+		}
+		assertNotNull("Expected parse error in " + qString, expected);
 
-    Query q = qp.parse(qString);
+	}
 
-    HashSet expecteds = new HashSet();
-    String[] vals = expectedVals.split(",");
-    for (int i = 0; i < vals.length; i++) {
-      if (vals[i].length() > 0)
-        expecteds.add(vals[i]);
-    }
+	private void checkMatches(String qString, String expectedVals)
+			throws Exception {
+		QueryParser qp = new ComplexPhraseQueryParser(defaultFieldName,
+				analyzer);
+		qp.setFuzzyPrefixLength(1); // usually a good idea
 
-    TopDocs td = searcher.search(q, 10);
-    ScoreDoc[] sd = td.scoreDocs;
-    for (int i = 0; i < sd.length; i++) {
-      Document doc = searcher.doc(sd[i].doc);
-      String id = doc.get("id");
-      assertTrue(qString + "matched doc#" + id + " not expected", expecteds
-          .contains(id));
-      expecteds.remove(id);
-    }
+		Query q = qp.parse(qString);
 
-    assertEquals(qString + " missing some matches ", 0, expecteds.size());
+		HashSet expecteds = new HashSet();
+		String[] vals = expectedVals.split(",");
+		for (int i = 0; i < vals.length; i++) {
+			if (vals[i].length() > 0)
+				expecteds.add(vals[i]);
+		}
 
-  }
+		TopDocs td = searcher.search(q, 10);
+		ScoreDoc[] sd = td.scoreDocs;
+		for (int i = 0; i < sd.length; i++) {
+			Document doc = searcher.doc(sd[i].doc);
+			String id = doc.get("id");
+			assertTrue(qString + "matched doc#" + id + " not expected",
+					expecteds.contains(id));
+			expecteds.remove(id);
+		}
 
-  protected void setUp() throws Exception {
-    RAMDirectory rd = new RAMDirectory();
-    IndexWriter w = new IndexWriter(rd, analyzer, MaxFieldLength.UNLIMITED);
-    for (int i = 0; i < docsContent.length; i++) {
-      Document doc = new Document();
-      doc.add(new Field("name", docsContent[i].name, Field.Store.YES,
-          Field.Index.ANALYZED));
-      doc.add(new Field("id", docsContent[i].id, Field.Store.YES,
-          Field.Index.ANALYZED));
-      w.addDocument(doc);
-    }
-    w.close();
-    searcher = new IndexSearcher(rd);
-  }
+		assertEquals(qString + " missing some matches ", 0, expecteds.size());
 
-  protected void tearDown() throws Exception {
-    searcher.close();
-  }
+	}
 
-  static class DocData {
-    String name;
+	protected void setUp() throws Exception {
+		RAMDirectory rd = new RAMDirectory();
+		IndexWriter w = new IndexWriter(rd, analyzer, MaxFieldLength.UNLIMITED);
+		for (int i = 0; i < docsContent.length; i++) {
+			Document doc = new Document();
+			doc.add(new Field("name", docsContent[i].name, Field.Store.YES,
+					Field.Index.ANALYZED));
+			doc.add(new Field("id", docsContent[i].id, Field.Store.YES,
+					Field.Index.ANALYZED));
+			w.addDocument(doc);
+		}
+		w.close();
+		searcher = new IndexSearcher(rd);
+	}
 
-    String id;
+	protected void tearDown() throws Exception {
+		searcher.close();
+	}
 
-    public DocData(String name, String id) {
-      super();
-      this.name = name;
-      this.id = id;
-    }
-  }
+	static class DocData {
+		String name;
+
+		String id;
+
+		public DocData(String name, String id) {
+			super();
+			this.name = name;
+			this.id = id;
+		}
+	}
 
 }
