public void performCompletion(@NotNull CompletionParameters parameters, @NotNull Consumer<? super CompletionResult> consumer) {
    Set<LookupElement> lookupSet = ConcurrentHashMap.newKeySet();
    AtomicBoolean typoTolerant = new AtomicBoolean();

    BatchConsumer<CompletionResult> batchConsumer = new BatchConsumer<>() {
      @Override
      public void startBatch() {
        if (consumer instanceof BatchConsumer<?> c) {
          c.startBatch();
        }
      }

      @Override
      public void endBatch() {
        if (consumer instanceof BatchConsumer<?> c) {
          c.endBatch();
        }
      }

      @Override
      public void consume(CompletionResult result) {
        if (typoTolerant.get() && result.getLookupElement().getAutoCompletionPolicy() != AutoCompletionPolicy.NEVER_AUTOCOMPLETE) {
          result = result.withLookupElement(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(result.getLookupElement()));
        }
        if (lookupSet.add(result.getLookupElement())) {
          consumer.consume(result);
        }
      }
    };
    String prefix = suggestPrefix(parameters);
    getVariantsFromContributors(parameters, null, createMatcher(prefix, false), batchConsumer);
    if (lookupSet.isEmpty() && prefix.length() > 2) {
      typoTolerant.set(true);
      getVariantsFromContributors(parameters, null, createMatcher(prefix, true), batchConsumer);
    }
  }
public void performCompletion(@NotNull CompletionParameters parameters, @NotNull Consumer<? super CompletionResult> consumer)