private Documents<FindDocument> executeQuery(
      final AciService aciService, final AciParameters aciParameters) {
    QueryResponseData responseData;
    try {
      responseData = aciService.executeAction(aciParameters, queryResponseProcessor);
    } catch (final AciErrorException e) {
      final String errorString = e.getErrorString();
      if (MISSING_RULE_ERROR.equals(errorString) || INVALID_RULE_ERROR.equals(errorString)) {
        aciParameters.remove(QmsActionParams.Blacklist.name());
        responseData = aciService.executeAction(aciParameters, queryResponseProcessor);
      } else {
        throw e;
      }
    }

    final List<Hit> hits = responseData.getHit();
    final List<FindDocument> results = parseQueryHits(hits);
    return new Documents<>(results, responseData.getTotalhits(), null);
  }
  @Override
  public List<FindDocument> findSimilar(final Set<String> indexes, final String reference)
      throws AciErrorException {
    final AciParameters aciParameters = new AciParameters(QueryActions.Suggest.name());
    aciParameters.add(SuggestParams.Reference.name(), new Reference(reference));
    if (!indexes.isEmpty()) {
      aciParameters.add(SuggestParams.DatabaseMatch.name(), new Databases(indexes));
    }
    aciParameters.add(SuggestParams.Print.name(), PrintParam.None);
    aciParameters.add(SuggestParams.MaxResults.name(), MAX_SIMILAR_DOCUMENTS);
    aciParameters.add(SuggestParams.Summary.name(), SummaryParam.Concept);

    final SuggestResponseData responseData =
        contentAciService.executeAction(aciParameters, suggestResponseProcessor);
    final List<Hit> hits = responseData.getHit();
    return parseQueryHits(hits);
  }
  private Documents<FindDocument> queryTextIndex(
      final AciService aciService,
      final FindQueryParams<String> findQueryParams,
      final boolean promotions) {
    final AciParameters aciParameters = new AciParameters(QueryActions.Query.name());
    aciParameters.add(QueryParams.Text.name(), findQueryParams.getText());
    aciParameters.add(QueryParams.MaxResults.name(), findQueryParams.getMaxResults());
    aciParameters.add(
        QueryParams.Summary.name(), SummaryParam.fromValue(findQueryParams.getSummary(), null));

    if (!promotions && !findQueryParams.getIndex().isEmpty()) {
      aciParameters.add(
          QueryParams.DatabaseMatch.name(), new Databases(findQueryParams.getIndex()));
    }

    aciParameters.add(QueryParams.Combine.name(), CombineParam.Simple);
    aciParameters.add(QueryParams.Predict.name(), false);
    aciParameters.add(QueryParams.FieldText.name(), findQueryParams.getFieldText());
    aciParameters.add(QueryParams.Sort.name(), findQueryParams.getSort());
    aciParameters.add(QueryParams.MinDate.name(), formatDate(findQueryParams.getMinDate()));
    aciParameters.add(QueryParams.MaxDate.name(), formatDate(findQueryParams.getMaxDate()));
    aciParameters.add(QueryParams.Print.name(), PrintParam.Fields);
    aciParameters.add(QueryParams.PrintFields.name(), new PrintFields(FindDocument.ALL_FIELDS));
    aciParameters.add(QueryParams.XMLMeta.name(), true);
    aciParameters.add(QueryParams.AnyLanguage.name(), true);

    if (findQueryParams.isHighlight()) {
      aciParameters.add(QueryParams.Highlight.name(), HighlightParam.SummaryTerms);
      aciParameters.add(QueryParams.StartTag.name(), HIGHLIGHT_START_TAG);
      aciParameters.add(QueryParams.EndTag.name(), HIGHLIGHT_END_TAG);
    }

    aciParameters.add(
        QmsActionParams.Blacklist.name(),
        configService.getConfig().getQueryManipulation().getBlacklist());
    aciParameters.add(
        QmsActionParams.ExpandQuery.name(),
        configService.getConfig().getQueryManipulation().getExpandQuery());

    if (promotions) {
      aciParameters.add(QmsActionParams.Promotions.name(), true);
    }

    return executeQuery(aciService, aciParameters);
  }