@Override
  public void addDocuments(
      String searchEngineId,
      long companyId,
      Collection<Document> documents,
      boolean commitImmediately)
      throws SearchException {

    if (isIndexReadOnly() || (documents == null) || documents.isEmpty()) {
      return;
    }

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    for (Document document : documents) {
      if (_log.isDebugEnabled()) {
        _log.debug("Add document " + document.toString());
      }

      _searchPermissionChecker.addPermissionFields(companyId, document);
    }

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    setCommitImmediately(searchContext, commitImmediately);

    indexWriter.addDocuments(searchContext, documents);
  }
  @Override
  public void deleteEntityDocuments(
      String searchEngineId, long companyId, String className, boolean commitImmediately)
      throws SearchException {

    if (isIndexReadOnly()) {
      return;
    }

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    if (searchEngine == null) {
      return;
    }

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    setCommitImmediately(searchContext, commitImmediately);

    indexWriter.deleteEntityDocuments(searchContext, className);
  }
  @Override
  public void updateDocument(
      String searchEngineId, long companyId, Document document, boolean commitImmediately)
      throws SearchException {

    if (isIndexReadOnly() || (document == null)) {
      return;
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Document " + document.toString());
    }

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    _searchPermissionChecker.addPermissionFields(companyId, document);

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    setCommitImmediately(searchContext, commitImmediately || ProxyModeThreadLocal.isForceSync());

    indexWriter.updateDocument(searchContext, document);
  }
  @Override
  public void commit(String searchEngineId, long companyId) throws SearchException {

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    indexWriter.commit(searchContext);
  }
  @Override
  public void indexSpellCheckerDictionaries(String searchEngineId, long companyId)
      throws SearchException {

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    indexWriter.indexSpellCheckerDictionaries(searchContext);
  }
  @Override
  public void indexQuerySuggestionDictionary(String searchEngineId, long companyId, Locale locale)
      throws SearchException {

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);
    searchContext.setLocale(locale);

    indexWriter.indexQuerySuggestionDictionary(searchContext);
  }
  @Override
  public void deleteDocuments(
      String searchEngineId, long companyId, Collection<String> uids, boolean commitImmediately)
      throws SearchException {

    if (isIndexReadOnly() || (uids == null) || uids.isEmpty()) {
      return;
    }

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    setCommitImmediately(searchContext, commitImmediately);

    indexWriter.deleteDocuments(searchContext, uids);
  }
  @Override
  public void indexKeyword(
      String searchEngineId,
      long companyId,
      String querySuggestion,
      float weight,
      String keywordType,
      Locale locale)
      throws SearchException {

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);
    searchContext.setKeywords(querySuggestion);
    searchContext.setLocale(locale);

    indexWriter.indexKeyword(searchContext, weight, keywordType);
  }