/** Closes the factory. */
  public void close() {
    InternalIndexReader tmpReader = null;
    tmpReader = _oldReader;

    _oldReader = null;

    try {
      // close the old reader
      if (tmpReader != null) {
        try {
          tmpReader.dispose();
        } catch (IOException e) {
          log.error("Problem closing reader", e);
        }
      }
    } finally {
      // close the current reader
      tmpReader = _currentReader;
      _currentReader = null;

      if (tmpReader != null) {
        try {
          tmpReader.dispose();
        } catch (IOException e) {
          log.error("Problem closing reader", e);
        }
      }
    }
  }
  /**
   * get a fresh new reader instance
   *
   * @return an IndexReader instance, can be null if index does not yet exit
   * @throws IOException
   */
  public ZoieIndexReader getNewReader() throws IOException {
    // wack the old reader
    if (_oldReader != null) {
      try {
        _oldReader.dispose();
      } catch (IOException ioe) {
        log.warn("Problem closing reader", ioe);
      } finally {
        _oldReader = null;
      }
    }

    int numTries = INDEX_OPEN_NUM_RETRIES;
    InternalIndexReader reader = null;

    // try it for a few times, there is a case where lucene is swapping the segment file,
    // or a case where the index directory file is updated, both are legitimate,
    // trying again does not block searchers,
    // the extra time it takes to get the reader, and to sync the index, memory index is collecting
    // docs

    while (reader == null) {
      if (numTries == 0) {
        break;
      }
      numTries--;
      try {
        IndexSignature sig = getCurrentIndexSignature(_indexHome);

        if (sig == null) {
          throw new IOException("no index exist");
        }
        String luceneDir = sig.getIndexPath();

        if (luceneDir == null || luceneDir.trim().length() == 0) {
          throw new IOException(INDEX_DIRECTORY + " contains no data.");
        }

        if (luceneDir != null) {
          reader = newReader(new File(_indexHome, luceneDir), sig);
          break;
        }
      } catch (IOException ioe) {
        try {
          Thread.sleep(100);
        } catch (InterruptedException e) {
          log.warn("thread interrupted.");
          continue;
        }
      }
    }

    // swap the internal readers

    _oldReader = _currentReader;
    _currentReader = reader;

    return reader;
  }