boolean (@Nullable PsiElement pattern, @Nullable PsiElement candidate, @NotNull List<PsiElement> candidates, @NotNull Match match) { if (pattern == null || candidate == null) return pattern == candidate; final Boolean parameterMatches = matchParameter(pattern, candidate, match); if (parameterMatches != null) { return parameterMatches; } if (!canBeEquivalent(pattern, candidate)) { return false; // Q : is it correct to check implementation classes? } if (pattern instanceof PsiExpressionList && candidate instanceof PsiExpressionList) { Boolean matches = matchVarargs((PsiExpressionList)pattern, (PsiExpressionList)candidate, candidates, match); if (matches != null) { return matches; } } if (isParameterModification(pattern, candidate)) { return false; } if (pattern instanceof PsiJavaCodeReferenceElement && candidate instanceof PsiJavaCodeReferenceElement) { Boolean matches = matchReferenceElement((PsiJavaCodeReferenceElement)pattern, (PsiJavaCodeReferenceElement)candidate, candidates, match); if (matches != null) { return matches; } } if (pattern instanceof PsiTypeCastExpression && candidate instanceof PsiTypeCastExpression) { if (!isEquivalentTypeCast((PsiTypeCastExpression)pattern, (PsiTypeCastExpression)candidate)) { return false; } } else if (pattern instanceof PsiNewExpression && candidate instanceof PsiNewExpression) { if (!isEquivalentNewExpression((PsiNewExpression)pattern, (PsiNewExpression)candidate)) { return false; } } else if (pattern instanceof PsiClassObjectAccessExpression && candidate instanceof PsiClassObjectAccessExpression) { return matchObjectAccess((PsiClassObjectAccessExpression)pattern, (PsiClassObjectAccessExpression)candidate); } else if (pattern instanceof PsiInstanceOfExpression && candidate instanceof PsiInstanceOfExpression) { if (!isEquivalentInstanceOf((PsiInstanceOfExpression)pattern, (PsiInstanceOfExpression)candidate)) { return false; } } else if (pattern instanceof PsiReturnStatement) { return matchReturnStatement((PsiReturnStatement)pattern, candidate, candidates, match); } else if (pattern instanceof PsiContinueStatement) { match.registerReturnValue(new ContinueReturnValue()); } else if (pattern instanceof PsiBreakStatement) { match.registerReturnValue(new BreakReturnValue()); } else if (pattern instanceof PsiMethodCallExpression && candidate instanceof PsiMethodCallExpression) { if (!isEquivalentMethodCall((PsiMethodCallExpression)pattern, (PsiMethodCallExpression)candidate)) { return false; } } else if (pattern instanceof PsiReferenceExpression && candidate instanceof PsiReferenceExpression) { final Boolean matches = matchReferenceExpression((PsiReferenceExpression)pattern, (PsiReferenceExpression)candidate, match); if (matches != null) { return matches; } } else if (pattern instanceof PsiThisExpression) { return matchThisExpression((PsiThisExpression)pattern, candidate, match); } else if (pattern instanceof PsiSuperExpression && candidate instanceof PsiSuperExpression) { return matchSuperExpression((PsiSuperExpression)pattern, (PsiSuperExpression)candidate); } else if (pattern instanceof PsiModifierList && candidate instanceof PsiModifierList) { return matchModifierList((PsiModifierList)pattern, (PsiModifierList)candidate); } PsiElement[] children1 = getFilteredChildren(pattern); PsiElement[] children2 = getFilteredChildren(candidate); if (!matchChildren(children1, children2, candidates, match)) { return false; } if (children1.length == 0) { return matchLeaf(pattern, candidate, match); } return true; }