ComplexExtremumTerminal (@NotNull PsiExpression nullCheckExpr, @NotNull PsiExpression comparisonExpr, PsiStatement @NotNull [] statements, @NotNull TerminalBlock terminalBlock, @Nullable List<? extends PsiVariable> nonFinalVariables, boolean isNegated) { Comparison comparison = Comparison.extract(comparisonExpr, terminalBlock.getVariable(), isNegated); if (comparison == null) return null; PsiBinaryExpression nullCheckBinary = tryCast(skipParenthesizedExprDown(nullCheckExpr), PsiBinaryExpression.class); if (nullCheckBinary == null) return null; PsiVariable extremumNullChecked = ExpressionUtils.getVariableFromNullComparison(nullCheckBinary, true); if (extremumNullChecked == null) return null; ComplexAssignment assignment = ComplexAssignment.extract(statements, extremumNullChecked); if (assignment == null) return null; if (!assignment.getLoopVar().equals(terminalBlock.getVariable())) return null; PsiVariable extremumKey = resolveVariableReference(comparison.getExtremumExpr()); if (extremumKey == null) return null; if (!extremumKey.equals(assignment.getExtremumKey())) return null; PsiVariable extremum = assignment.getExtremum(); if (mayChangeBeforeLoop(extremumKey, terminalBlock) || mayChangeBeforeLoop(extremum, terminalBlock)) { return null; } PsiExpression loopVarExpr = comparison.getLoopVarExpr(); if (!ourEquivalence.expressionsAreEquivalent(assignment.getLoopVarExpression(), loopVarExpr)) return null; if (nonFinalVariables != null) { if (containsAnyVariable(assignment.getLoopVarExpression(), nonFinalVariables)) return null; } PsiType loopVarExprType = loopVarExpr.getType(); if (!hasKnownComparableType(comparison, loopVarExprType)) return null; PsiExpression extremumInitializer = extremum.getInitializer(); PsiExpression extremumKeyInitializer = extremumKey.getInitializer(); if (extremumInitializer == null || extremumKeyInitializer == null) return null; if (!ExpressionUtils.isNullLiteral(extremumInitializer)) return null; if (!ExpressionUtils.isEvaluatedAtCompileTime(extremumKeyInitializer)) return null; return new ComplexExtremumTerminal(comparison.isMax(), extremum, extremumKey, extremumKeyInitializer, loopVarExpr, terminalBlock, comparison.getComparator()); }