@Override
    public void visitAssignmentExpression(@NotNull PsiAssignmentExpression assignment) {
      super.visitAssignmentExpression(assignment);
      final PsiElement assignmentParent = assignment.getParent();
      if (!(assignmentParent instanceof PsiExpressionStatement)) {
        return;
      }
      final PsiExpression lhs = PsiUtil.skipParenthesizedExprDown(assignment.getLExpression());
      if (!(lhs instanceof PsiReferenceExpression reference)) {
        return;
      }
      final PsiElement referent = reference.resolve();
      if (!(referent instanceof PsiLocalVariable variable)) {
        return;
      }
      if (variable.getInitializer() == null) {
        return;
      }
      final IElementType tokenType = assignment.getOperationTokenType();
      if (!JavaTokenType.EQ.equals(tokenType)) {
        return;
      }
      final PsiExpression rhs = assignment.getRExpression();
      if (VariableAccessUtils.variableIsUsed(variable, rhs)) {
        return;
      }
      final PsiCodeBlock variableBlock = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
      if (variableBlock == null) {
        return;
      }
      if (hasParentOfTypeBeforeAncestor(assignment, variableBlock, PsiLoopStatement.class, PsiTryStatement.class)) {
        // this could be weakened, slightly, if it could be verified
        // that a variable is used in only one branch of a try statement
        return;
      }
      final PsiElement assignmentBlock = assignmentParent.getParent();
      if (assignmentBlock == null) {
        return;
      }
      if (variableBlock.equals(assignmentBlock)) {
        registerError(lhs);
        return;
      }
      if (assignmentBlock instanceof PsiCodeBlock block) {
        boolean before = true;
        for (PsiStatement statement : block.getStatements()) {
          if (statement.equals(assignmentParent)) before = false;
          if (before) continue;
          if (statement instanceof PsiBreakStatement) break;
          if (statement instanceof PsiReturnStatement || statement instanceof PsiThrowStatement) {
            registerError(lhs);
            return;
          }
        }
      }
      PsiElement child = assignmentBlock;
      PsiElement parent = child.getParent();
      outer:
      while (parent != null) {
        boolean before = true;
        if (child instanceof PsiSwitchLabeledRuleStatement ruleStatement) {
          parent = ruleStatement.getEnclosingSwitchBlock();
        }
        else if (child instanceof PsiBreakStatement breakStatement) {
          // in switch statement
          parent = breakStatement.findExitedStatement();
        }
        else if (parent instanceof PsiCodeBlock) {
          for (PsiStatement statement : ((PsiCodeBlock)parent).getStatements()) {
            if (statement.equals(child)) {
              before = false;
              continue;
            }
            if (before) continue;
            if (VariableAccessUtils.variableIsUsed(variable, statement)) return;
            if (statement instanceof PsiReturnStatement || statement instanceof PsiThrowStatement) break outer;
          }
        }
        if (parent == variableBlock || parent == null) break;
        child = parent;
        parent = child.getParent();
      }
      registerError(lhs);
    }
@Override
    public void visitAssignmentExpression(@NotNull PsiAssignmentExpression assignment)