private static boolean statementAssignsVariableOrFails(@Nullable PsiStatement statement, PsiVariable variable,
                                                         @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
    if (statement == null) {
      return false;
    }
    if (ExceptionUtils.statementThrowsException(statement)) {
      return true;
    }
    if (statement instanceof PsiBreakStatement ||
        statement instanceof PsiContinueStatement ||
        statement instanceof PsiAssertStatement ||
        statement instanceof PsiEmptyStatement ||
        statement instanceof PsiSwitchLabelStatement) {
      return false;
    }
    else if (statement instanceof PsiReturnStatement returnStatement) {
      return expressionAssignsVariableOrFails(returnStatement.getReturnValue(), variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiThrowStatement throwStatement) {
      return expressionAssignsVariableOrFails(throwStatement.getException(), variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiExpressionListStatement list) {
      final PsiExpressionList expressionList = list.getExpressionList();
      for (final PsiExpression expression : expressionList.getExpressions()) {
        if (expressionAssignsVariableOrFails(expression, variable, checkedMethods, strict)) {
          return true;
        }
      }
      return false;
    }
    else if (statement instanceof PsiExpressionStatement expressionStatement) {
      return expressionAssignsVariableOrFails(expressionStatement.getExpression(), variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiDeclarationStatement declarationStatement) {
      return declarationStatementAssignsVariableOrFails(declarationStatement, variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiForStatement forStatement) {
      return forStatementAssignsVariableOrFails(forStatement, variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiForeachStatement foreachStatement) {
      return foreachStatementAssignsVariableOrFails(foreachStatement, variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiWhileStatement whileStatement) {
      return whileStatementAssignsVariableOrFails(whileStatement, variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiDoWhileStatement doWhileStatement) {
      return doWhileAssignsVariableOrFails(doWhileStatement, variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiSynchronizedStatement synchronizedStatement) {
      return blockAssignsVariableOrFails(synchronizedStatement.getBody(), variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiBlockStatement blockStatement) {
      return blockAssignsVariableOrFails(blockStatement.getCodeBlock(), variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiLabeledStatement labeledStatement) {
      return statementAssignsVariableOrFails(labeledStatement.getStatement(), variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiIfStatement ifStatement) {
      return ifStatementAssignsVariableOrFails(ifStatement, variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiTryStatement tryStatement) {
      return tryStatementAssignsVariableOrFails(tryStatement, variable, checkedMethods, strict);
    }
    else if (statement instanceof PsiSwitchStatement switchStatement) {
      return switchStatementAssignsVariableOrFails(switchStatement, variable, checkedMethods, strict);
    }
    else {
      // unknown statement type
      return false;
    }
  }
private static boolean statementAssignsVariableOrFails(@Nullable PsiStatement statement, PsiVariable variable,
                                                         @NotNull Set<MethodSignature> checkedMethods, boolean strict)