static int32_t count(const TermPtr& t, const IndexReaderPtr& r) {
    int32_t count = 0;
    TermDocsPtr td = r->termDocs(t);
    while (td->next()) {
        td->doc();
        ++count;
    }
    td->close();
    return count;
}
static void verifyTermDocs(DirectoryPtr dir, TermPtr term, int32_t numDocs)
{
    IndexReaderPtr reader = IndexReader::open(dir, true);
    TermDocsPtr termDocs = reader->termDocs(term);
    int32_t count = 0;
    while (termDocs->next())
        ++count;
    BOOST_CHECK_EQUAL(count, numDocs);
    reader->close();
}
TEST_F(ParallelTermEnumTest, testParallelTermEnum) {
    ParallelReaderPtr pr = newLucene<ParallelReader>();
    pr->add(ir1);
    pr->add(ir2);

    TermDocsPtr td = pr->termDocs();
    TermEnumPtr te = pr->terms();

    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field1:brown", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field1:fox", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field1:jumps", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field1:quick", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field1:the", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field2:brown", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field2:fox", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field2:jumps", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field2:quick", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field2:the", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field3:dog", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field3:fox", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field3:jumps", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field3:lazy", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field3:over", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(te->next());
    EXPECT_EQ(L"field3:the", te->term()->toString());
    td->seek(te->term());
    EXPECT_TRUE(td->next());
    EXPECT_EQ(0, td->doc());
    EXPECT_TRUE(!td->next());
    EXPECT_TRUE(!te->next());
}
    void checkSkipTo(int32_t indexDivisor) {
        DirectoryPtr dir = newLucene<RAMDirectory>();
        IndexWriterPtr writer = newLucene<IndexWriter>(dir, newLucene<WhitespaceAnalyzer>(), true, IndexWriter::MaxFieldLengthLIMITED);

        TermPtr ta = newLucene<Term>(L"content", L"aaa");
        for (int32_t i = 0; i < 10; ++i) {
            addDoc(writer, L"aaa aaa aaa aaa");
        }

        TermPtr tb = newLucene<Term>(L"content", L"bbb");
        for (int32_t i = 0; i < 16; ++i) {
            addDoc(writer, L"bbb bbb bbb bbb");
        }

        TermPtr tc = newLucene<Term>(L"content", L"ccc");
        for (int32_t i = 0; i < 50; ++i) {
            addDoc(writer, L"ccc ccc ccc ccc");
        }

        // assure that we deal with a single segment
        writer->optimize();
        writer->close();

        IndexReaderPtr reader = IndexReader::open(dir, IndexDeletionPolicyPtr(), true, indexDivisor);

        TermDocsPtr tdocs = reader->termDocs();

        // without optimization (assumption skipInterval == 16)

        // with next
        tdocs->seek(ta);
        EXPECT_TRUE(tdocs->next());
        EXPECT_EQ(0, tdocs->doc());
        EXPECT_EQ(4, tdocs->freq());
        EXPECT_TRUE(tdocs->next());
        EXPECT_EQ(1, tdocs->doc());
        EXPECT_EQ(4, tdocs->freq());
        EXPECT_TRUE(tdocs->skipTo(0));
        EXPECT_EQ(2, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(4));
        EXPECT_EQ(4, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(9));
        EXPECT_EQ(9, tdocs->doc());
        EXPECT_TRUE(!tdocs->skipTo(10));

        // without next
        tdocs->seek(ta);
        EXPECT_TRUE(tdocs->skipTo(0));
        EXPECT_EQ(0, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(4));
        EXPECT_EQ(4, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(9));
        EXPECT_EQ(9, tdocs->doc());
        EXPECT_TRUE(!tdocs->skipTo(10));

        // exactly skipInterval documents and therefore with optimization

        // with next
        tdocs->seek(tb);
        EXPECT_TRUE(tdocs->next());
        EXPECT_EQ(10, tdocs->doc());
        EXPECT_EQ(4, tdocs->freq());
        EXPECT_TRUE(tdocs->next());
        EXPECT_EQ(11, tdocs->doc());
        EXPECT_EQ(4, tdocs->freq());
        EXPECT_TRUE(tdocs->skipTo(5));
        EXPECT_EQ(12, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(15));
        EXPECT_EQ(15, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(24));
        EXPECT_EQ(24, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(25));
        EXPECT_EQ(25, tdocs->doc());
        EXPECT_TRUE(!tdocs->skipTo(26));

        // without next
        tdocs->seek(tb);
        EXPECT_TRUE(tdocs->skipTo(5));
        EXPECT_EQ(10, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(15));
        EXPECT_EQ(15, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(24));
        EXPECT_EQ(24, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(25));
        EXPECT_EQ(25, tdocs->doc());
        EXPECT_TRUE(!tdocs->skipTo(26));

        // much more than skipInterval documents and therefore with optimization

        // with next
        tdocs->seek(tc);
        EXPECT_TRUE(tdocs->next());
        EXPECT_EQ(26, tdocs->doc());
        EXPECT_EQ(4, tdocs->freq());
        EXPECT_TRUE(tdocs->next());
        EXPECT_EQ(27, tdocs->doc());
        EXPECT_EQ(4, tdocs->freq());
        EXPECT_TRUE(tdocs->skipTo(5));
        EXPECT_EQ(28, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(40));
        EXPECT_EQ(40, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(57));
        EXPECT_EQ(57, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(74));
        EXPECT_EQ(74, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(75));
        EXPECT_EQ(75, tdocs->doc());
        EXPECT_TRUE(!tdocs->skipTo(76));

        // without next
        tdocs->seek(tc);
        EXPECT_TRUE(tdocs->skipTo(5));
        EXPECT_EQ(26, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(40));
        EXPECT_EQ(40, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(57));
        EXPECT_EQ(57, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(74));
        EXPECT_EQ(74, tdocs->doc());
        EXPECT_TRUE(tdocs->skipTo(75));
        EXPECT_EQ(75, tdocs->doc());
        EXPECT_TRUE(!tdocs->skipTo(76));

        tdocs->close();
        reader->close();
        dir->close();
    }