boost::any StringCache::createValue(IndexReaderPtr reader, EntryPtr key)
 {
     EntryPtr entry(key);
     String field(entry->field);
     Collection<String> retArray(Collection<String>::newInstance(reader->maxDoc()));
     TermDocsPtr termDocs(reader->termDocs());
     TermEnumPtr termEnum(reader->terms(newLucene<Term>(field)));
     LuceneException finally;
     try
     {
         do
         {
             TermPtr term(termEnum->term());
             if (!term || term->field() != field)
                 break;
             String termval(term->text());
             termDocs->seek(termEnum);
             while (termDocs->next())
                 retArray[termDocs->doc()] = termval;
         }
         while (termEnum->next());
     }
     catch (LuceneException& e)
     {
         finally = e;
     }
     termDocs->close();
     termEnum->close();
     finally.throwException();
     return retArray;
 }
 boost::any StringIndexCache::createValue(IndexReaderPtr reader, EntryPtr key)
 {
     EntryPtr entry(key);
     String field(entry->field);
     Collection<int32_t> retArray(Collection<int32_t>::newInstance(reader->maxDoc()));
     Collection<String> mterms(Collection<String>::newInstance(reader->maxDoc() + 1));
     TermDocsPtr termDocs(reader->termDocs());
     TermEnumPtr termEnum(reader->terms(newLucene<Term>(field)));
     int32_t t = 0; // current term number
     
     // an entry for documents that have no terms in this field should a document with no terms be at 
     // top or bottom?  This puts them at the top - if it is changed, FieldDocSortedHitQueue needs to 
     // change as well.
     mterms[t++] = L"";
     
     LuceneException finally;
     try
     {
         do
         {
             TermPtr term(termEnum->term());
             if (!term || term->field() != field || t >= mterms.size() )
                 break;
             
             // store term text
             mterms[t] = term->text();
             
             termDocs->seek(termEnum);
             while (termDocs->next())
                 retArray[termDocs->doc()] = t;
             
             ++t;
         }
         while (termEnum->next());
     }
     catch (LuceneException& e)
     {
         finally = e;
     }
     termDocs->close();
     termEnum->close();
     finally.throwException();
     
     if (t == 0)
     {
         // if there are no terms, make the term array have a single null entry
         mterms = Collection<String>::newInstance(1);
     }
     else if (t < mterms.size())
     {
         // if there are less terms than documents, trim off the dead array space
         mterms.resize(t);
     }
     
     return newLucene<StringIndex>(retArray, mterms);
 }
 boost::any DoubleCache::createValue(IndexReaderPtr reader, EntryPtr key)
 {
     EntryPtr entry(key);
     String field(entry->field);
     DoubleParserPtr parser(VariantUtils::get<DoubleParserPtr>(entry->custom));
     if (!parser)
     {
         FieldCachePtr wrapper(_wrapper);
         boost::any doubles;
         try
         {
             doubles = wrapper->getDoubles(reader, field, FieldCache::DEFAULT_DOUBLE_PARSER());
         }
         catch (NumberFormatException&)
         {
             doubles = wrapper->getDoubles(reader, field, FieldCache::NUMERIC_UTILS_DOUBLE_PARSER());
         }
         return doubles;
     }
     Collection<double> retArray;
     TermDocsPtr termDocs(reader->termDocs());
     TermEnumPtr termEnum(reader->terms(newLucene<Term>(field)));
     LuceneException finally;
     try
     {
         do
         {
             TermPtr term(termEnum->term());
             if (!term || term->field() != field)
                 break;
             double termval = parser->parseDouble(term->text());
             if (!retArray) // late init
                 retArray = Collection<double>::newInstance(reader->maxDoc());
             termDocs->seek(termEnum);
             while (termDocs->next())
                 retArray[termDocs->doc()] = termval;
         }
         while (termEnum->next());
     }
     catch (StopFillCacheException&)
     {
     }
     catch (LuceneException& e)
     {
         finally = e;
     }
     termDocs->close();
     termEnum->close();
     finally.throwException();
     if (!retArray) // no values
         retArray = Collection<double>::newInstance(reader->maxDoc());
     return retArray;
 }
int32_t IndexReader::deleteDocuments(const TermPtr& term) {
    ensureOpen();
    TermDocsPtr docs(termDocs(term));
    if (!docs) {
        return 0;
    }
    int32_t n = 0;
    LuceneException finally;
    try {
        while (docs->next()) {
            deleteDocument(docs->doc());
            ++n;
        }
    } catch (LuceneException& e) {
        finally = e;
    }
    docs->close();
    finally.throwException();
    return n;
}
  TermDocs* IndexReader::termDocs(Term* term) {
  //Func - Returns an enumeration of all the documents which contain
  //       term. For each document, the document number, the frequency of
  //       the term in that document is also provided, for use in search scoring.
  //       Thus, this method implements the mapping:
  //
  //       Term => <docNum, freq>*
  //	   The enumeration is ordered by document number.  Each document number
  //       is greater than all that precede it in the enumeration.
  //Pre  - term != NULL
  //Post - A reference to TermDocs containing an enumeration of all found documents
  //       has been returned

      CND_PRECONDITION(term != NULL, "term is NULL");

      ensureOpen();
      //Reference an instantiated TermDocs instance
      TermDocs* _termDocs = termDocs();
      //Seek all documents containing term
      _termDocs->seek(term);
      //return the enumaration
      return _termDocs;
  }
 boost::any ByteCache::createValue(IndexReaderPtr reader, EntryPtr key)
 {
     EntryPtr entry(key);
     String field(entry->field);
     ByteParserPtr parser(VariantUtils::get<ByteParserPtr>(entry->custom));
     if (!parser)
         return FieldCachePtr(_wrapper)->getBytes(reader, field, FieldCache::DEFAULT_BYTE_PARSER());
     Collection<uint8_t> retArray(Collection<uint8_t>::newInstance(reader->maxDoc()));
     TermDocsPtr termDocs(reader->termDocs());
     TermEnumPtr termEnum(reader->terms(newLucene<Term>(field)));
     LuceneException finally;
     try
     {
         do
         {
             TermPtr term(termEnum->term());
             if (!term || term->field() != field)
                 break;
             uint8_t termval = parser->parseByte(term->text());
             termDocs->seek(termEnum);
             while (termDocs->next())
                 retArray[termDocs->doc()] = termval;
         }
         while (termEnum->next());
     }
     catch (StopFillCacheException&)
     {
     }
     catch (LuceneException& e)
     {
         finally = e;
     }
     termDocs->close();
     termEnum->close();
     finally.throwException();
     return retArray;
 }
TermDocsPtr IndexReader::termDocs(const TermPtr& term) {
    ensureOpen();
    TermDocsPtr _termDocs(termDocs());
    _termDocs->seek(term);
    return _termDocs;
}