@Test
public void testAnalyzeFulltextQuery() throws Exception {

    // invalid queries
    assertFulltextException("OR foo");
    assertFulltextException("OR foo bar");
    assertFulltextException("foo OR");
    assertFulltextException("foo bar OR");
    assertFulltextException("foo OR OR bar");
    assertFulltextException("foo bar OR OR baz");
    assertFulltextException("foo + bar");
    assertFulltextException("foo - bar");
    // ok queries
    assertFulltextQuery(null, "");
    assertFulltextQuery(null, "  ");
    assertFulltextQuery("foo", "foo");
    assertFulltextQuery("foo", " foo ");
    assertFulltextQuery("[foo AND bar]", "foo bar");
    assertFulltextQuery("[foo AND bar AND baz]", "foo bar baz");
    assertFulltextQuery("[foo AND ~bar]", "foo -bar");
    assertFulltextQuery("[foo AND baz AND ~bar]", "foo -bar baz");
    assertFulltextQuery("[foo AND ~bar AND ~baz]", "foo -bar -baz");
    assertFulltextQuery("[bar AND ~foo]", "-foo bar");
    assertFulltextQuery("[bar AND baz AND ~foo]", "-foo bar baz");
    // queries with OR
    assertFulltextQuery("[foo OR bar]", "foo OR bar");
    assertFulltextQuery("[foo OR [bar AND baz]]", "foo OR bar baz");
    assertFulltextQuery("[[foo AND bar] OR baz]", "foo bar OR baz");
    assertFulltextQuery("[foo OR bar OR baz]", "foo OR bar OR baz");
    assertFulltextQuery("[foo OR [bar AND baz] OR gee]",
            "foo OR bar baz OR gee");
    assertFulltextQuery("[[bar AND ~foo] OR baz]", "-foo bar OR baz");
    assertFulltextQuery("[foo OR [bar AND ~baz]]", "foo OR bar -baz");
    // queries containing suppressed terms
    assertFulltextQuery(null, "-foo");
    assertFulltextQuery(null, "-foo -bar");
    assertFulltextQuery("bar", "-foo OR bar");
    assertFulltextQuery("foo", "foo OR -bar");
    assertFulltextQuery(null, "-foo OR -bar");
    assertFulltextQuery("foo", "foo OR -bar -baz");
    assertFulltextQuery("baz", "-foo -bar OR baz");
    // query with phrases
    assertFulltextException("\"foo");
    assertFulltextException("\"foo bar");
    assertFulltextException("\"fo\"o\"");
    assertFulltextQuery(null, "\"\"");
    assertFulltextQuery(null, " \" \" ");
    assertFulltextQuery("foo", "\"foo\"");
    assertFulltextQuery("foo", "+\"foo\"");
    assertFulltextQuery(null, "-\"foo\"");
    assertFulltextQuery("foo", "\" foo\"");
    assertFulltextQuery("foo", "\"foo \"");
    assertFulltextQuery("foo", "\" foo \"");
    assertFulltextQuery("OR", "\"OR\"");
    assertFulltextQuery("{foo bar}", "\"foo bar\"");
    assertFulltextQuery("{foo bar}", "\" foo bar\"");
    assertFulltextQuery("{foo bar}", "\"foo bar \"");
    assertFulltextQuery("{foo bar}", "\" foo  bar \"");
    assertFulltextQuery("{foo bar}", "+\"foo bar\"");
    assertFulltextQuery("{foo or bar}", "\"foo or bar\"");
    assertFulltextQuery(null, "-\"foo bar\"");
    assertFulltextQuery("[foo AND {bar baz}]", "foo \"bar baz\"");
    assertFulltextQuery("[foo AND {bar baz}]", "foo +\"bar baz\"");
    assertFulltextQuery("[foo AND ~{bar baz}]", "foo -\"bar baz\"");
    assertFulltextQuery("[{foo bar} AND baz]", "\"foo bar\" baz");
    assertFulltextQuery("[{foo bar} AND baz]", "+\"foo bar\" baz");
    assertFulltextQuery("[baz AND ~{foo bar}]", "-\"foo bar\" baz");
    assertFulltextQuery("[{foo bar} AND ~{baz gee}]",
            "\"foo bar\" -\"baz gee\"");
}