void (CompletionParameters parameters, CompletionResultSet result, Set<ExpectedTypeInfo> expectedInfos, List<LookupElement> base) { PsiElement position = parameters.getPosition(); PsiJavaCodeReferenceElement reference = (PsiJavaCodeReferenceElement)position.getParent(); List<LookupElement> chainable = ContainerUtil.filter(base, item -> isChainable(item.getObject())); if (chainable.isEmpty()) return; for (ExpectedTypeInfo info : expectedInfos) { Set<Pair<LookupElement, String>> processedChains = new HashSet<>(); JavaSmartCompletionParameters smartParams = new JavaSmartCompletionParameters(parameters, info); for (LookupElement item : chainable) { addSecondCompletionVariants(position, reference, item, smartParams, lookupElement -> { ContainerUtil.addIfNotNull(processedChains, chainInfo(lookupElement)); result.consume(JavaSmartCompletionContributor.decorate(lookupElement, expectedInfos)); }); } if (!reference.isQualified()) { BasicExpressionCompletionContributor.processDataflowExpressionTypes(smartParams, null, PrefixMatcher.ALWAYS_TRUE, baseItem -> addSecondCompletionVariants(position, reference, baseItem, smartParams, lookupElement -> { if (!processedChains.contains(chainInfo(lookupElement))) { result.consume(JavaSmartCompletionContributor.decorate(lookupElement, expectedInfos)); } })); } } }