void (CompletionParameters parameters, Consumer<? super CompletionResult> consumer) { final Set<LookupElement> lookupSet = ContainerUtil.newConcurrentSet(); AtomicBoolean typoTolerant = new AtomicBoolean(); BatchConsumer<CompletionResult> batchConsumer = new BatchConsumer<>() { @Override public void startBatch() { if (consumer instanceof BatchConsumer) { ((BatchConsumer<?>)consumer).startBatch(); } } @Override public void endBatch() { if (consumer instanceof BatchConsumer) { ((BatchConsumer<?>)consumer).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); } }