public static boolean isLocalVariableCopy(@NotNull PsiLocalVariable variable, @Nullable PsiExpression expression) {
    if (expression instanceof PsiTypeCastExpression) {
      PsiExpression operand = ((PsiTypeCastExpression)expression).getOperand();
      if (operand instanceof PsiReferenceExpression && RedundantCastUtil.isCastRedundant((PsiTypeCastExpression)expression)) {
        expression = operand;
      }
    }
    if (!(expression instanceof PsiReferenceExpression reference)) {
      return false;
    }
    final PsiVariable initialization = ObjectUtils.tryCast(reference.resolve(), PsiVariable.class);
    if (initialization == null) {
      return false;
    }
    if (!(initialization instanceof PsiResourceVariable) && variable instanceof PsiResourceVariable) {
      return false;
    }
    if (!(initialization instanceof PsiLocalVariable || initialization instanceof PsiParameter)) {
      if (!isFinalChain(reference) || getVariableReferences(variable).size() != 1) {
        // only warn when variable is referenced once, to avoid warning when a field is cached in local variable
        // as in e.g. gnu.trove.TObjectHash#forEach()
        return false;
      }
    }
    final PsiCodeBlock containingScope = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
    if (containingScope == null) {
      return false;
    }
    if (variableMayChange(containingScope, null, variable)) {
      return false;
    }
    if (variableMayChange(containingScope, PsiUtil.skipParenthesizedExprDown(reference.getQualifierExpression()), initialization)) {
      return false;
    }

    final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(containingScope.getProject()).getResolveHelper();
    final String initializationName = initialization.getName();
    if (initializationName == null) {
      return false;
    }

    final boolean finalVariableIntroduction =
      !initialization.hasModifierProperty(PsiModifier.FINAL) && variable.hasModifierProperty(PsiModifier.FINAL) ||
      PsiUtil.isAvailable(JavaFeature.EFFECTIVELY_FINAL, initialization) &&
      !HighlightControlFlowUtil.isEffectivelyFinal(initialization, containingScope, null) &&
      HighlightControlFlowUtil.isEffectivelyFinal(variable, containingScope, null);
    final boolean canCaptureThis = initialization instanceof PsiField && !initialization.hasModifierProperty(PsiModifier.STATIC);

    final PsiType variableType = variable.getType();
    final PsiType initializationType = initialization.getType();
    final boolean sameType = Comparing.equal(variableType, initializationType);
    for (PsiReferenceExpression refElement : getVariableReferences(variable)) {
      if (finalVariableIntroduction || canCaptureThis) {
        PsiElement element = LambdaUtil.getContainingClassOrLambda(refElement);
        if (element != null && PsiTreeUtil.isAncestor(containingScope, element, true)) {
          return false;
        }

        PsiSwitchLabelStatementBase switchLabel = PsiTreeUtil.getParentOfType(refElement, PsiSwitchLabelStatementBase.class);
        if (switchLabel != null &&
            switchLabel.getGuardExpression() != null &&
            PsiTreeUtil.isAncestor(switchLabel.getGuardExpression(), refElement, true) &&
            PsiTreeUtil.isAncestor(containingScope, switchLabel, true)) {
          return false;
        }
      }

      if (resolveHelper.resolveReferencedVariable(initializationName, refElement) != initialization) {
        return false;
      }

      if (!sameType && !isVariableTypeChangeSafeForReference(initializationType, refElement)) {
        return false;
      }
    }

    return !TypeConversionUtil.boxingConversionApplicable(variableType, initializationType);
  }
public static boolean isLocalVariableCopy(@NotNull PsiLocalVariable variable, @Nullable PsiExpression expression)