private static boolean isGoodExpression(@NotNull PsiExpression argument,
                                          @NotNull AllowedValues allowedValues,
                                          @NotNull PsiElement scope,
                                          @NotNull PsiManager manager,
                                          @Nullable Set<PsiExpression> visited) {
    if (visited == null) visited = new HashSet<>();
    if (!visited.add(argument)) return false;
    if (argument instanceof PsiParenthesizedExpression ||
        argument instanceof PsiConditionalExpression ||
        argument instanceof PsiSwitchExpression) {
      List<PsiExpression> expressions = ExpressionUtils.nonStructuralChildren(argument).toList();
      for (PsiExpression expression : expressions) {
        if (!isAllowed(expression, scope, allowedValues, manager, visited)) {
          return false;
        }
      }
      return true;
    }

    if (isOneOf(argument, allowedValues, manager)) return true;

    if (allowedValues.isFlagSet()) {
      PsiExpression zero = getLiteralExpression(argument, manager, "0");
      if (MagicConstantUtils.same(argument, zero, manager)
          // if for some crazy reason the constant with value "0" is included to allowed values for flags, do not treat literal "0" as allowed value anymore
          // see e.g. Font.BOLD=1, Font.ITALIC=2, Font.PLAIN=0
          && !allowedValues.hasZeroValue()) return true;
      PsiExpression minusOne = getLiteralExpression(argument, manager, "-1");
      if (MagicConstantUtils.same(argument, minusOne, manager)) return true;
      if (argument instanceof PsiPolyadicExpression polyadic) {
        IElementType tokenType = polyadic.getOperationTokenType();
        if (JavaTokenType.OR.equals(tokenType) || JavaTokenType.XOR.equals(tokenType) ||
            JavaTokenType.AND.equals(tokenType) || JavaTokenType.PLUS.equals(tokenType)) {
          for (PsiExpression operand : polyadic.getOperands()) {
            if (!isAllowed(operand, scope, allowedValues, manager, visited)) return false;
          }
          return true;
        }
      }
      if (argument instanceof PsiPrefixExpression prefixExpression &&
          JavaTokenType.TILDE.equals(prefixExpression.getOperationTokenType())) {
        PsiExpression operand = prefixExpression.getOperand();
        return operand == null || isAllowed(operand, scope, allowedValues, manager, visited);
      }
    }

    PsiModifierListOwner owner = null;
    AllowedValues allowedForRef = null;
    if (argument instanceof PsiReference reference) {
      owner = ObjectUtils.tryCast(reference.resolve(), PsiModifierListOwner.class);
    }
    else if (argument instanceof PsiMethodCallExpression call) {
      allowedForRef = SPECIAL_CASES.mapFirst(call);
      owner = call.resolveMethod();
    }

    if (allowedForRef == null && owner != null) {
      allowedForRef = MagicConstantUtils.getAllowedValues(owner, PsiUtil.getTypeByPsiElement(owner), argument);
    }
    if (allowedForRef != null && allowedForRef.isSubsetOf(allowedValues, manager)) {
      return true;
    }

    return PsiTypes.nullType().equals(argument.getType());
  }
private static boolean isGoodExpression(@NotNull PsiExpression argument,
                                          @NotNull AllowedValues allowedValues,
                                          @NotNull PsiElement scope,
                                          @NotNull PsiManager manager,
                                          @Nullable Set<PsiExpression> visited)