CandidateInfo (@NotNull List<CandidateInfo> conflicts) { if (mySignature == null) return null; if (conflicts.isEmpty()) return null; if (conflicts.size() == 1) return conflicts.get(0); final Map<MethodCandidateInfo, PsiSubstitutor> map = FactoryMap.create(key -> key.getSubstitutor(false)); checkSameSignatures(conflicts, map); if (conflicts.size() == 1) return conflicts.get(0); checkAccessStaticLevels(conflicts, true); if (conflicts.size() == 1) return conflicts.get(0); PsiType[] argTypes = mySignature.getParameterTypes(); boolean hasReceiver = PsiMethodReferenceUtil.isSecondSearchPossible(argTypes, myQualifierResolveResult, myReferenceExpression); List<CandidateInfo> firstCandidates = new ArrayList<>(); List<CandidateInfo> secondCandidates = new ArrayList<>(); for (CandidateInfo conflict : conflicts) { if (!(conflict instanceof MethodCandidateInfo)) continue; Boolean applicableByFirstSearch = isApplicableByFirstSearch(conflict, argTypes, hasReceiver, myReferenceExpression, myFunctionalMethodVarArgs, myInterfaceMethod); if (applicableByFirstSearch != null) { (applicableByFirstSearch ? firstCandidates : secondCandidates).add(conflict); } } if (myQualifierResolveResult.isReferenceTypeQualified() && myReferenceExpression.getReferenceNameElement() instanceof PsiIdentifier) { int firstApplicability = checkApplicability(firstCandidates); ArrayList<CandidateInfo> firstResults = new ArrayList<>(firstCandidates); checkSpecifics(firstResults, firstApplicability, map, 0); int secondApplicability = checkApplicability(secondCandidates); ArrayList<CandidateInfo> secondResults = new ArrayList<>(secondCandidates); checkSpecifics(secondResults, secondApplicability, map, 1); //If the first search produces a static method, and no non-static method is applicable for the second search, then the result of the first search is the compile-time declaration. CandidateInfo candidateInfo = filterStaticCorrectCandidates(firstResults, secondCandidates, true); if (candidateInfo != null) { return candidateInfo; } //If the second search produces a non-static method, and no static method is applicable for the first search, then the result of the second search is the compile-time declaration. candidateInfo = filterStaticCorrectCandidates(secondResults, firstCandidates, false); if (candidateInfo != null) { return candidateInfo; } conflicts.clear(); conflicts.addAll(firstResults); conflicts.addAll(secondResults); return null; } CandidateInfo candidateInfo = resolveConflicts(firstCandidates, secondCandidates, map, MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY); if (candidateInfo != null) { return candidateInfo; } candidateInfo = resolveConflicts(firstCandidates, secondCandidates, map, MethodCandidateInfo.ApplicabilityLevel.VARARGS); if (candidateInfo != null) { return candidateInfo; } if (firstCandidates.isEmpty() && secondCandidates.isEmpty()) { return null; } conflicts.clear(); firstCandidates.addAll(secondCandidates); conflicts.addAll(firstCandidates); return null; }