private boolean statementAssignsVariable(@Nullable PsiStatement statement, @NotNull PsiVariable variable,
                                           int stamp, @NotNull Set<MethodSignature> checkedMethods) {
    if (statement == null) {
      return false;
    }
    if (ExceptionUtils.statementThrowsException(statement)) {
      return true;
    }
    if (statement instanceof PsiBreakStatement ||
        statement instanceof PsiContinueStatement ||
        statement instanceof PsiAssertStatement ||
        statement instanceof PsiEmptyStatement) {
      return false;
    }
    else if (statement instanceof PsiReturnStatement returnStatement) {
      final PsiExpression returnValue = returnStatement.getReturnValue();
      return expressionAssignsVariable(returnValue, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiThrowStatement throwStatement) {
      final PsiExpression exception = throwStatement.getException();
      return expressionAssignsVariable(exception, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiExpressionListStatement list) {
      final PsiExpressionList expressionList = list.getExpressionList();
      final PsiExpression[] expressions = expressionList.getExpressions();
      for (final PsiExpression expression : expressions) {
        if (expressionAssignsVariable(expression, variable, stamp, checkedMethods)) {
          return true;
        }
      }
      return false;
    }
    else if (statement instanceof PsiExpressionStatement expressionStatement) {
      final PsiExpression expression = expressionStatement.getExpression();
      return expressionAssignsVariable(expression, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiDeclarationStatement declarationStatement) {
      return declarationStatementAssignsVariable(declarationStatement, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiForStatement forStatement) {
      return forStatementAssignsVariable(forStatement, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiForeachStatement foreachStatement) {
      return foreachStatementAssignsVariable(foreachStatement, variable);
    }
    else if (statement instanceof PsiWhileStatement whileStatement) {
      return whileStatementAssignsVariable(whileStatement, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiDoWhileStatement doWhileStatement) {
      return doWhileAssignsVariable(doWhileStatement, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiSynchronizedStatement synchronizedStatement) {
      final PsiCodeBlock body = synchronizedStatement.getBody();
      return blockAssignsVariable(body, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiBlockStatement blockStatement) {
      final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
      return blockAssignsVariable(codeBlock, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiLabeledStatement labeledStatement) {
      final PsiStatement statementLabeled = labeledStatement.getStatement();
      return statementAssignsVariable(statementLabeled, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiIfStatement ifStatement) {
      return ifStatementAssignsVariable(ifStatement, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiTryStatement tryStatement) {
      return tryStatementAssignsVariable(tryStatement, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiSwitchStatement switchStatement) {
      return switchBlockAssignsVariable(switchStatement, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiSwitchLabelStatement) {
      return false;
    }
    else if (statement instanceof PsiSwitchLabeledRuleStatement switchLabeledRuleStatement) {
      final PsiStatement body = switchLabeledRuleStatement.getBody();
      return statementAssignsVariable(body, variable, stamp, checkedMethods);
    }
    else if (statement instanceof PsiYieldStatement yieldStatement) {
      final PsiExpression expression = yieldStatement.getExpression();
      return expressionAssignsVariable(expression, variable, stamp, checkedMethods);
    }
    else {
      assert false : "unknown statement: " + statement;
      return false;
    }
  }
private boolean statementAssignsVariable(@Nullable PsiStatement statement, @NotNull PsiVariable variable,
                                           int stamp, @NotNull Set<MethodSignature> checkedMethods)