@Test
  public void testEscapeHtml() throws Exception {

    try {
      client.admin().indices().prepareDelete("test").execute().actionGet();
    } catch (Exception e) {
      // ignore
    }

    client
        .admin()
        .indices()
        .prepareCreate("test")
        .setSettings(ImmutableSettings.settingsBuilder().put("number_of_shards", 2))
        .addMapping(
            "type1",
            jsonBuilder()
                .startObject()
                .startObject("type1")
                .startObject("properties")
                .startObject("title")
                .field("type", "string")
                .field("store", "yes")
                .endObject()
                .endObject()
                .endObject())
        .execute()
        .actionGet();

    for (int i = 0; i < 5; i++) {
      client
          .prepareIndex("test", "type1", Integer.toString(i))
          .setSource("title", "This is a html escaping highlighting test for *&? elasticsearch")
          .setRefresh(true)
          .execute()
          .actionGet();
    }

    SearchResponse search =
        client
            .prepareSearch()
            .setQuery(fieldQuery("title", "test"))
            .setEncoder("html")
            .addHighlightedField("title", 50, 1, 10)
            .execute()
            .actionGet();

    assertThat(Arrays.toString(search.shardFailures()), search.failedShards(), equalTo(0));

    assertThat(search.hits().totalHits(), equalTo(5l));
    assertThat(search.hits().hits().length, equalTo(5));

    for (SearchHit hit : search.hits()) {
      // LUCENE 3.1 UPGRADE: Caused adding the space at the end...
      assertThat(
          hit.highlightFields().get("title").fragments()[0],
          equalTo("This is a html escaping highlighting <em>test</em> for *&amp;? elasticsearch"));
    }
  }
  @Test
  public void testSameContent() throws Exception {
    try {
      client.admin().indices().prepareDelete("test").execute().actionGet();
    } catch (Exception e) {
      // ignore
    }

    client
        .admin()
        .indices()
        .prepareCreate("test")
        .setSettings(ImmutableSettings.settingsBuilder().put("number_of_shards", 2))
        .addMapping(
            "type1",
            jsonBuilder()
                .startObject()
                .startObject("type1")
                .startObject("properties")
                .startObject("title")
                .field("type", "string")
                .field("store", "yes")
                .field("term_vector", "with_positions_offsets")
                .endObject()
                .endObject()
                .endObject()
                .endObject())
        .execute()
        .actionGet();

    for (int i = 0; i < 5; i++) {
      client
          .prepareIndex("test", "type1", Integer.toString(i))
          .setSource("title", "This is a test on the highlighting bug present in elasticsearch")
          .setRefresh(true)
          .execute()
          .actionGet();
    }

    SearchResponse search =
        client
            .prepareSearch()
            .setQuery(fieldQuery("title", "bug"))
            .addHighlightedField("title", -1, 0)
            .execute()
            .actionGet();

    assertThat(search.hits().totalHits(), equalTo(5l));
    assertThat(search.hits().hits().length, equalTo(5));
    assertThat(search.getFailedShards(), equalTo(0));

    for (SearchHit hit : search.hits()) {
      // LUCENE 3.1 UPGRADE: Caused adding the space at the end...
      assertThat(
          hit.highlightFields().get("title").fragments()[0],
          equalTo("This is a test on the highlighting <em>bug</em> present in elasticsearch "));
    }
  }
  @Test
  public void testSourceLookupHighlightingUsingPlainHighlighter() throws Exception {
    try {
      client.admin().indices().prepareDelete("test").execute().actionGet();
    } catch (Exception e) {
      // ignore
    }

    client
        .admin()
        .indices()
        .prepareCreate("test")
        .setSettings(ImmutableSettings.settingsBuilder().put("number_of_shards", 2))
        .addMapping(
            "type1",
            jsonBuilder()
                .startObject()
                .startObject("type1")
                .startObject("properties")
                // we don't store title and don't use term vector, now lets see if it works...
                .startObject("title")
                .field("type", "string")
                .field("store", "no")
                .field("term_vector", "no")
                .endObject()
                .startObject("attachments")
                .startObject("properties")
                .startObject("body")
                .field("type", "string")
                .field("store", "no")
                .field("term_vector", "no")
                .endObject()
                .endObject()
                .endObject()
                .endObject()
                .endObject()
                .endObject())
        .execute()
        .actionGet();

    for (int i = 0; i < 5; i++) {
      client
          .prepareIndex("test", "type1", Integer.toString(i))
          .setSource(
              XContentFactory.jsonBuilder()
                  .startObject()
                  .field("title", "This is a test on the highlighting bug present in elasticsearch")
                  .startArray("attachments")
                  .startObject()
                  .field("body", "attachment 1")
                  .endObject()
                  .startObject()
                  .field("body", "attachment 2")
                  .endObject()
                  .endArray()
                  .endObject())
          .setRefresh(true)
          .execute()
          .actionGet();
    }

    SearchResponse search =
        client
            .prepareSearch()
            .setQuery(fieldQuery("title", "bug"))
            .addHighlightedField("title", -1, 0)
            .execute()
            .actionGet();

    assertThat(Arrays.toString(search.shardFailures()), search.failedShards(), equalTo(0));

    assertThat(search.hits().totalHits(), equalTo(5l));
    assertThat(search.hits().hits().length, equalTo(5));

    for (SearchHit hit : search.hits()) {
      assertThat(
          hit.highlightFields().get("title").fragments()[0],
          equalTo("This is a test on the highlighting <em>bug</em> present in elasticsearch"));
    }

    search =
        client
            .prepareSearch()
            .setQuery(fieldQuery("attachments.body", "attachment"))
            .addHighlightedField("attachments.body", -1, 0)
            .execute()
            .actionGet();

    assertThat(Arrays.toString(search.shardFailures()), search.failedShards(), equalTo(0));

    assertThat(search.hits().totalHits(), equalTo(5l));
    assertThat(search.hits().hits().length, equalTo(5));

    for (SearchHit hit : search.hits()) {
      assertThat(
          hit.highlightFields().get("attachments.body").fragments()[0],
          equalTo("<em>attachment</em> 1 <em>attachment</em> 2"));
    }
  }
  @Test
  public void testFastVectorHighlighterManyDocs() throws Exception {
    try {
      client.admin().indices().prepareDelete("test").execute().actionGet();
    } catch (ElasticSearchException e) {
      assertThat(e.unwrapCause(), instanceOf(IndexMissingException.class));
    }
    client
        .admin()
        .indices()
        .prepareCreate("test")
        .addMapping("type1", type1TermVectorMapping())
        .execute()
        .actionGet();
    client.admin().cluster().prepareHealth("test").setWaitForGreenStatus().execute().actionGet();

    int COUNT = 100;
    logger.info("--> indexing docs");
    for (int i = 0; i < COUNT; i++) {
      client
          .prepareIndex("test", "type1", Integer.toString(i))
          .setSource("field1", "test " + i)
          .execute()
          .actionGet();
      if (i % 5 == 0) {
        // flush so we get updated readers and segmented readers
        client.admin().indices().prepareFlush().execute().actionGet();
      }
    }

    client.admin().indices().prepareRefresh().execute().actionGet();

    logger.info("--> searching explicitly on field1 and highlighting on it");
    SearchResponse searchResponse =
        client
            .prepareSearch()
            .setSize(COUNT)
            .setQuery(termQuery("field1", "test"))
            .addHighlightedField("field1", 100, 0)
            .execute()
            .actionGet();
    assertThat(searchResponse.hits().totalHits(), equalTo((long) COUNT));
    assertThat(searchResponse.hits().hits().length, equalTo(COUNT));
    for (SearchHit hit : searchResponse.hits()) {
      // LUCENE 3.1 UPGRADE: Caused adding the space at the end...
      assertThat(
          hit.highlightFields().get("field1").fragments()[0],
          equalTo("<em>test</em> " + hit.id() + " "));
    }

    logger.info("--> searching explicitly on field1 and highlighting on it, with DFS");
    searchResponse =
        client
            .prepareSearch()
            .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
            .setSize(COUNT)
            .setQuery(termQuery("field1", "test"))
            .addHighlightedField("field1", 100, 0)
            .execute()
            .actionGet();
    assertThat(searchResponse.hits().totalHits(), equalTo((long) COUNT));
    assertThat(searchResponse.hits().hits().length, equalTo(COUNT));
    for (SearchHit hit : searchResponse.hits()) {
      // LUCENE 3.1 UPGRADE: Caused adding the space at the end...
      assertThat(
          hit.highlightFields().get("field1").fragments()[0],
          equalTo("<em>test</em> " + hit.id() + " "));
    }

    logger.info("--> searching explicitly _all and highlighting on _all");
    searchResponse =
        client
            .prepareSearch()
            .setSize(COUNT)
            .setQuery(termQuery("_all", "test"))
            .addHighlightedField("_all", 100, 0)
            .execute()
            .actionGet();
    assertThat(searchResponse.hits().totalHits(), equalTo((long) COUNT));
    assertThat(searchResponse.hits().hits().length, equalTo(COUNT));
    for (SearchHit hit : searchResponse.hits()) {
      // LUCENE 3.1 UPGRADE: Caused adding the space at the end...
      assertThat(
          hit.highlightFields().get("_all").fragments()[0],
          equalTo("<em>test</em> " + hit.id() + "  "));
    }
  }