@Test(expected = ClassCastException.class)
  public void testPOJOCombinedSearchWithJacksonHandle() {
    PojoRepository<Artifact, Long> products = client.newPojoRepository(Artifact.class, Long.class);
    PojoPage<Artifact> p;
    this.loadSimplePojos(products);
    QueryManager queryMgr = client.newQueryManager();
    String queryAsString =
        "{\"search\":{\"query\":{\"and-query\":["
            + "{\"word-constraint-query\":{\"constraint-name\":\"pojo-name-field\", \"text\":\"Acme\"}},"
            + "{\"word-constraint-query\":{\"constraint-name\":\"pojo-name-field\", \"text\":\"special\"}}]},"
            + "\"options\":{\"constraint\":{\"name\":\"pojo-name-field\", \"word\":{\"json-property\":\"name\"}}}"
            + "}}";

    PojoQueryDefinition qd =
        (PojoQueryDefinition)
            queryMgr.newRawCombinedQueryDefinition(
                new StringHandle(queryAsString).withFormat(Format.JSON));
    JacksonHandle results = new JacksonHandle();
    p = products.search(qd, 1, results);
    products.setPageLength(11);
    assertEquals("total no of pages", 1, p.getTotalPages());
    //		System.out.println(p.getTotalPages()+results.get().toString());
    long pageNo = 1, count = 0;
    do {
      count = 0;
      p = products.search(qd, pageNo, results);

      while (p.iterator().hasNext()) {
        Artifact a = p.iterator().next();
        validateArtifact(a);
        count++;
        assertTrue(
            "Manufacture name starts with acme", a.getManufacturer().getName().contains("Acme"));
        assertTrue("Artifact name contains", a.getName().contains("special"));
      }
      assertEquals("Page size", count, p.size());
      pageNo = pageNo + p.getPageSize();

      assertEquals(
          "Page start from search handls vs page methods",
          results.get().get("start").asLong(),
          p.getStart());
      assertEquals(
          "Format in the search handle",
          "json",
          results.get().withArray("results").get(1).path("format").asText());
      assertTrue(
          "Uri in search handle contains Artifact",
          results.get().withArray("results").get(1).path("uri").asText().contains("Artifact"));
      //			System.out.println(results.get().toString());
    } while (!p.isLastPage() && pageNo < p.getTotalSize());
    assertFalse("search handle has metrics", results.get().has("metrics"));
    assertEquals("Total from search handle", 11, results.get().get("total").asInt());
    assertEquals("page number after the loop", 1, p.getPageNumber());
    assertEquals("total no of pages", 1, p.getTotalPages());
  }
 // This test is to verify extract-document-data & extract-path with  selected=exclude option query
 @Test
 public void testExtractDocumentData2() throws Exception {
   this.loadJSONDocuments();
   this.loadXMLDocuments();
   String head = "<search:search xmlns:search=\"http://marklogic.com/appservices/search\">";
   String tail = "</search:search>";
   String qtext4 = "<search:qtext>71 OR dog14</search:qtext>";
   DocumentManager docMgr = client.newDocumentManager();
   QueryManager queryMgr = client.newQueryManager();
   String options =
       "<search:options>"
           + "<search:extract-document-data selected=\"exclude\">"
           + "<search:extract-path>//foo</search:extract-path>"
           + "<search:extract-path>//says</search:extract-path>"
           + "</search:extract-document-data>"
           + "</search:options>";
   // test XML response with extracted XML and JSON matches
   String combinedSearch = head + qtext4 + options + tail;
   RawCombinedQueryDefinition rawCombinedQueryDefinition =
       queryMgr.newRawCombinedQueryDefinition(
           new StringHandle(combinedSearch).withMimetype("application/xml"));
   SearchHandle results = queryMgr.search(rawCombinedQueryDefinition, new SearchHandle());
   MatchDocumentSummary[] summaries = results.getMatchResults();
   assertNotNull(summaries);
   assertEquals(2, summaries.length);
   for (MatchDocumentSummary summary : summaries) {
     ExtractedResult extracted = summary.getExtracted();
     if (Format.XML == summary.getFormat()) {
       // we don't test for kind because it isn't sent in this case
       System.out.println("EXTRACTED Size ==" + extracted.size());
       // TODO:: Bug 33921 also add test to include-with-ancestors
       assertEquals(0, extracted.size());
       //			Document item1 = extracted.next().getAs(Document.class);
       //			assertEquals("This is so foo with a bar 71", item1.getFirstChild().getTextContent());
       continue;
     } else if (Format.JSON == summary.getFormat()) {
       // we don't test for kind because it isn't sent in this case
       assertEquals(1, extracted.size());
       for (ExtractedItem item : extracted) {
         String stringJsonItem = item.getAs(String.class);
         JsonNode nodeJsonItem = item.getAs(JsonNode.class);
         if (nodeJsonItem.has("animal")) {
           assertEquals("{\"animal\":\"dog14\"}", stringJsonItem);
           continue;
         }
         fail("unexpected extracted item:" + stringJsonItem);
       }
       continue;
     }
     fail("unexpected search result:" + summary.getUri());
   }
 }
  @Test
  public void testExtractMetadata() throws SAXException, IOException {
    QueryManager queryMgr = Common.client.newQueryManager();

    String combined =
        "<search xmlns=\"http://marklogic.com/appservices/search\">"
            + "<query>"
            + "<value-query>"
            + "<element ns=\"http://marklogic.com/xdmp/json\" name=\"firstKey\"/>"
            + "<text>first value</text>"
            + "</value-query>"
            + "</query>"
            + "<options>"
            + "<extract-metadata>"
            + "<qname elem-ns=\"http://marklogic.com/xdmp/json\" elem-name=\"subKey\"/>"
            + "</extract-metadata>"
            + "</options>"
            + "</search>";
    StringHandle rawHandle = new StringHandle(combined);

    RawCombinedQueryDefinition rawDef = queryMgr.newRawCombinedQueryDefinition(rawHandle);

    SearchHandle sh = queryMgr.search(rawDef, new SearchHandle());

    MatchDocumentSummary[] summaries = sh.getMatchResults();
    assertNotNull(summaries);
    assertEquals("expected 1 result", 1, summaries.length);

    MatchDocumentSummary matchResult = summaries[0];
    Document metadata = matchResult.getMetadata();
    Element subKey =
        (Element)
            metadata.getElementsByTagNameNS("http://marklogic.com/xdmp/json", "subKey").item(0);
    assertEquals("string", subKey.getAttribute("type"));
    assertEquals("sub value", subKey.getTextContent());

    String docStr = Common.testDocumentToString(metadata);
    String handleStr = matchResult.getMetadata(new StringHandle()).get();
    assertXMLEqual("Different metadata for handle", docStr, handleStr);

    Document snippet = matchResult.getSnippets()[0];
    docStr = Common.testDocumentToString(snippet);
    handleStr = matchResult.getSnippetIterator(new StringHandle()).next().get();
    assertXMLEqual("Different snippet for handle", docStr, handleStr);
  }
  // Searching for Id as Number in JSON using range query
  @Test(expected = ClassCastException.class)
  public void testPOJOcombinedSearchforNumberWithStringHandle()
      throws JsonProcessingException, IOException {
    PojoRepository<Artifact, Long> products = client.newPojoRepository(Artifact.class, Long.class);
    PojoPage<Artifact> p;
    this.loadSimplePojos(products);

    QueryManager queryMgr = client.newQueryManager();
    String queryAsString =
        "{\"search\":{\"query\":{"
            + "\"range-constraint-query\":{\"constraint-name\":\"id\", \"value\":[5,10,15,20,25,30]}},"
            + "\"options\":{\"return-metrics\":false, \"constraint\":{\"name\":\"id\", \"range\":{\"type\": \"xs:long\",\"json-property\":\"id\"}}}"
            + "}}";
    PojoQueryDefinition qd =
        (PojoQueryDefinition)
            queryMgr.newRawCombinedQueryDefinition(
                new StringHandle(queryAsString).withFormat(Format.JSON));

    StringHandle results = new StringHandle();
    JacksonHandle jh = new JacksonHandle();
    p = products.search(qd, 1, jh);

    long pageNo = 1, count = 0;
    do {
      count = 0;
      p = products.search(qd, pageNo, results.withFormat(Format.JSON));

      while (p.iterator().hasNext()) {
        Artifact a = p.iterator().next();
        validateArtifact(a);
        count++;
      }
      assertEquals("Page total results", count, p.getTotalSize());
      pageNo = pageNo + p.getPageSize();
      System.out.println(results.get().toString());
    } while (!p.isLastPage() && pageNo < p.getTotalSize());
    assertFalse("String handle is not empty", results.get().isEmpty());
    assertTrue("String handle contains results", results.get().contains("results"));
    assertTrue("String handle contains format", results.get().contains("\"format\":\"json\""));
    ObjectMapper mapper = new ObjectMapper();
    JsonNode actNode = mapper.readTree(results.get()).get("total");
    assertEquals("Total search results resulted are ", 6, actNode.asInt());
  }