private void addRecovered(long nodeId, Object value)
     throws IOException, IndexCapacityExceededException {
   IndexSearcher searcher = searcherManager.acquire();
   try {
     TopDocs hits =
         searcher.search(new TermQuery(documentStructure.newQueryForChangeOrRemove(nodeId)), 1);
     if (hits.totalHits > 0) {
       Fieldable encodedValue = documentStructure.encodeAsFieldable(value);
       writer.updateDocument(
           documentStructure.newQueryForChangeOrRemove(nodeId),
           documentStructure.newDocumentRepresentingProperty(nodeId, encodedValue));
     } else {
       add(nodeId, value);
     }
   } finally {
     searcherManager.release(searcher);
   }
 }
 @Override
 public IndexReader newReader() {
   final IndexSearcher searcher = searcherManager.acquire();
   final TaskControl token = taskCoordinator.newInstance();
   final Closeable closeable =
       new Closeable() {
         @Override
         public void close() throws IOException {
           searcherManager.release(searcher);
           token.close();
         }
       };
   return makeNewReader(searcher, closeable, token);
 }
 // This method should be synchronized because we need every thread to perform actual refresh
 // and not just skip it because some other refresh is in progress
 private synchronized void refreshSearcherManager() throws IOException {
   searcherManager.maybeRefresh();
 }
 private void closeIndexResources() throws IOException {
   writerStatus.close(writer);
   searcherManager.close();
 }