private void processReferencesForIfStatement(@NotNull PsiIfStatement ifStatement,
                                                 @NotNull PsiPatternVariable variable,
                                                 @NotNull PsiInstanceOfExpression psiInstanceOfExpression,
                                                 @NotNull List<PsiReferenceExpression> references) {
      List<PsiReferenceExpression> unusedReferences = new ArrayList<>(references);

      PsiStatement thenBranch = ifStatement.getThenBranch();
      if (this.tryToPreserveUnusedVariables) {
        //trivial cases
        ConditionState conditionState = getConditionIfInstanceOfTrue(psiInstanceOfExpression, ifStatement.getCondition());

        if (conditionState == ConditionState.TRUE &&
            thenBranch != null && !(thenBranch instanceof PsiEmptyStatement) &&
            ifStatement.getElseBranch() == null) {
          List<PsiReferenceExpression> referencesForThenBranch =
            ContainerUtil.filter(unusedReferences, t -> PsiTreeUtil.isAncestor(thenBranch, t, false));
          unusedReferences.removeAll(referencesForThenBranch);
          addDeclarationInsideBlock(thenBranch, variable);
        }

        if (conditionState.equals(ConditionState.FALSE) && !ControlFlowUtils.statementMayCompleteNormally(thenBranch) &&
            ifStatement.getElseBranch() == null &&
            !(ifStatement.getParent() instanceof PsiIfStatement parentIf && parentIf.getElseBranch() == ifStatement)) {

          List<PsiReferenceExpression> referencesForOutsideIf =
            ContainerUtil.filter(unusedReferences, t -> !PsiTreeUtil.isAncestor(ifStatement, t, false));
          unusedReferences.removeAll(referencesForOutsideIf);
          addDeclarationOutsideBlock(ifStatement, variable);
        }
      }

      //insert statements and casts in place
      Map<Boolean, List<PsiReferenceExpression>> collectedInsideThenBranch = unusedReferences.stream()
        .collect(
          Collectors.groupingBy(referenceExpression -> PsiTreeUtil.isAncestor(thenBranch, referenceExpression, false)));
      if (thenBranch != null && !(thenBranch instanceof PsiEmptyStatement) && collectedInsideThenBranch.get(Boolean.TRUE) != null) {
        addDeclarationInsideBlock(thenBranch, variable);
      }


      //in else branch
      PsiStatement elseBranch = ifStatement.getElseBranch();
      Map<Boolean, List<PsiReferenceExpression>> collectedInsideElseBlock =
        collectedInsideThenBranch.getOrDefault(Boolean.FALSE, List.of()).stream()
          .collect(Collectors.groupingBy(referenceExpression -> PsiTreeUtil.isAncestor(elseBranch, referenceExpression, false)));

      if (elseBranch != null && collectedInsideElseBlock.get(Boolean.TRUE) != null) {
        if (elseBranch instanceof PsiIfStatement elseIfStatement) {
          processReferencesForIfStatement(elseIfStatement, variable, psiInstanceOfExpression, collectedInsideElseBlock.get(Boolean.TRUE));
        }
        else {
          addDeclarationInsideBlock(elseBranch, variable);
        }
      }

      //outside
      Map<Boolean, List<PsiReferenceExpression>> collectedOutside = collectedInsideElseBlock.getOrDefault(Boolean.FALSE, List.of()).stream()
        .collect(Collectors.groupingBy(referenceExpression -> !PsiTreeUtil.isAncestor(ifStatement, referenceExpression, false)));

      if (collectedOutside.get(Boolean.TRUE) != null) {
        addDeclarationOutsideBlock(ifStatement, variable);
      }

      //typeCast - for example, in Conditions
      replaceWithCast(variable, collectedOutside.get(Boolean.FALSE));
    }
private void processReferencesForIfStatement(@NotNull PsiIfStatement ifStatement,
                                                 @NotNull PsiPatternVariable variable,
                                                 @NotNull PsiInstanceOfExpression psiInstanceOfExpression,
                                                 @NotNull List<PsiReferenceExpression> references)