public static boolean isUnnecessaryPrimitiveNumericCast(PsiTypeCastExpression expression) {
    final PsiType castType = expression.getType();
    if (!ClassUtils.isPrimitiveNumericType(castType)) {
      return false;
    }
    final PsiExpression operand = expression.getOperand();
    if (operand == null) {
      return false;
    }
    final PsiType operandType = operand.getType();
    if (!ClassUtils.isPrimitiveNumericType(operandType)) {
      return false;
    }
    PsiElement parent = expression.getParent();
    while (parent instanceof PsiParenthesizedExpression) {
      parent = parent.getParent();
    }
    if (parent instanceof PsiPrefixExpression prefixExpression) {
      // JLS 5.6 Numeric Contexts
      final IElementType tokenType = prefixExpression.getOperationTokenType();
      if (JavaTokenType.MINUS == tokenType || JavaTokenType.PLUS == tokenType || JavaTokenType.TILDE == tokenType) {
        if (TypeUtils.isNarrowingConversion(operandType, castType)) {
          return false;
        }
        if (PsiTypes.intType().equals(castType)) {
          return !PsiTypes.longType().equals(operandType) && !PsiTypes.floatType().equals(operandType) && !PsiTypes.doubleType().equals(operandType);
        }
      }
      return false;
    }
    if (castType.equals(operandType)) {
      // cast to the same type is caught by "Redundant type cast" inspection
      return false;
    }
    if (parent instanceof PsiPolyadicExpression polyadicExpression) {
      final IElementType tokenType = polyadicExpression.getOperationTokenType();
      if (binaryPromotionOperators.contains(tokenType)) {
        if (TypeUtils.isNarrowingConversion(operandType, castType)) {
          return false;
        }
        if (PsiTypes.intType().equals(castType)) {
          if (PsiTypes.charType().equals(operandType) && TypeUtils.getStringType(polyadicExpression).equals(polyadicExpression.getType())) {
            return false;
          }
          return !PsiTypes.longType().equals(operandType) && !PsiTypes.floatType().equals(operandType) && !PsiTypes.doubleType().equals(operandType);
        }
        if (PsiTypes.longType().equals(castType) || PsiTypes.floatType().equals(castType) || PsiTypes.doubleType().equals(castType)) {
          final PsiExpression[] operands = polyadicExpression.getOperands();
          int expressionIndex = -1;
          for (int i = 0; i < operands.length; i++) {
            if (expressionIndex == 0 && i > 1) {
              return false;
            }
            final PsiExpression operand1 = operands[i];
            if (PsiTreeUtil.isAncestor(operand1, expression, false)) {
              if (i > 0) {
                return false;
              }
              else {
                expressionIndex = i;
                continue;
              }
            }
            final PsiType type = operand1.getType();
            if (castType.equals(type)) {
              return true;
            }
          }
        }
      }
      else if (ExpressionParser.SHIFT_OPS.contains(tokenType)) {
        final PsiExpression firstOperand = polyadicExpression.getOperands()[0];
        if (!PsiTreeUtil.isAncestor(firstOperand, expression, false)) {
          return true;
        }
        return !PsiTypes.longType().equals(castType) && isLegalWideningConversion(operand, PsiTypes.intType());
      }
      return false;
    }
    else if (parent instanceof PsiAssignmentExpression assignmentExpression) {
      final PsiType lhsType = assignmentExpression.getType();
      if (castType.equals(lhsType) && (isLegalAssignmentConversion(operand, lhsType) || isLegalWideningConversion(operand, lhsType))) return true;
    }
    else if (parent instanceof PsiVariable variable) {
      final PsiTypeElement typeElement = variable.getTypeElement();
      if (typeElement == null || typeElement.isInferredType()) {
        return false;
      }
      final PsiType lhsType = variable.getType();
      if (castType.equals(lhsType) && (isLegalAssignmentConversion(operand, lhsType) || isLegalWideningConversion(operand, lhsType))) return true;
    }
    else if (MethodCallUtils.isNecessaryForSurroundingMethodCall(expression, operand)) {
      return false;
    }
    final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false, true);
    return operandType.equals(expectedType) && isLegalAssignmentConversion(operand, castType) ||
           castType.equals(expectedType) && isLegalWideningConversion(operand, castType);
  }
public static boolean isUnnecessaryPrimitiveNumericCast(PsiTypeCastExpression expression)