private static boolean isGoodExpression(
      PsiExpression expression,
      @NotNull AllowedValues allowedValues,
      @NotNull PsiElement scope,
      @NotNull PsiManager manager) {
    expression = PsiUtil.deparenthesizeExpression(expression);
    if (expression == null) return true;
    if (expression instanceof PsiConditionalExpression) {
      PsiExpression thenExpression = ((PsiConditionalExpression) expression).getThenExpression();
      boolean thenAllowed =
          thenExpression == null || isAllowed(scope, thenExpression, allowedValues, manager);
      if (!thenAllowed) return false;
      PsiExpression elseExpression = ((PsiConditionalExpression) expression).getElseExpression();
      return elseExpression == null || isAllowed(scope, elseExpression, allowedValues, manager);
    }

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

    if (allowedValues.canBeOred) {
      PsiExpression zero = getLiteralExpression(expression, manager, "0");
      if (same(expression, zero, manager)) return true;
      PsiExpression mOne = getLiteralExpression(expression, manager, "-1");
      if (same(expression, mOne, manager)) return true;
      if (expression instanceof PsiPolyadicExpression) {
        IElementType tokenType = ((PsiPolyadicExpression) expression).getOperationTokenType();
        if (JavaTokenType.OR.equals(tokenType) || JavaTokenType.AND.equals(tokenType)) {
          for (PsiExpression operand : ((PsiPolyadicExpression) expression).getOperands()) {
            if (!isAllowed(scope, operand, allowedValues, manager)) return false;
          }
          return true;
        }
      }
      if (expression instanceof PsiPrefixExpression
          && JavaTokenType.TILDE.equals(
              ((PsiPrefixExpression) expression).getOperationTokenType())) {
        PsiExpression operand = ((PsiPrefixExpression) expression).getOperand();
        return operand == null || isAllowed(scope, operand, allowedValues, manager);
      }
    }

    PsiElement resolved = null;
    if (expression instanceof PsiReference) {
      resolved = ((PsiReference) expression).resolve();
    } else if (expression instanceof PsiCallExpression) {
      resolved = ((PsiCallExpression) expression).resolveMethod();
    }

    AllowedValues allowedForRef;
    if (resolved instanceof PsiModifierListOwner
        && (allowedForRef =
                getAllowedValues(
                    (PsiModifierListOwner) resolved,
                    getType((PsiModifierListOwner) resolved),
                    null))
            != null
        && allowedForRef.isSubsetOf(allowedValues, manager)) return true;

    return PsiType.NULL.equals(expression.getType());
  }
 private static void checkExpression(
     PsiExpression expression, PsiModifierListOwner owner, PsiType type, ProblemsHolder holder) {
   AllowedValues allowed = getAllowedValues(owner, type, null);
   if (allowed == null) return;
   PsiElement scope = PsiUtil.getTopLevelEnclosingCodeBlock(expression, null);
   if (scope == null) scope = expression;
   if (!isAllowed(scope, expression, allowed, expression.getManager())) {
     registerProblem(expression, allowed, holder);
   }
 }
  private static void checkMagicParameterArgument(
      @NotNull PsiParameter parameter,
      PsiExpression argument,
      @NotNull AllowedValues allowedValues,
      @NotNull ProblemsHolder holder) {
    final PsiManager manager = PsiManager.getInstance(holder.getProject());

    if (!argument.getTextRange().isEmpty()
        && !isAllowed(parameter.getDeclarationScope(), argument, allowedValues, manager)) {
      registerProblem(argument, allowedValues, holder);
    }
  }
  private static boolean processValuesFlownTo(
      @NotNull final PsiExpression argument,
      PsiElement scope,
      @NotNull final Processor<PsiExpression> processor) {
    SliceAnalysisParams params = new SliceAnalysisParams();
    params.dataFlowToThis = true;
    params.scope = new AnalysisScope(new LocalSearchScope(scope), argument.getProject());

    SliceRootNode rootNode =
        new SliceRootNode(
            scope.getProject(), new DuplicateMap(), SliceManager.createRootUsage(argument, params));

    Collection<? extends AbstractTreeNode> children =
        rootNode.getChildren().iterator().next().getChildren();
    for (AbstractTreeNode child : children) {
      SliceUsage usage = (SliceUsage) child.getValue();
      PsiElement element = usage.getElement();
      if (element instanceof PsiExpression && !processor.process((PsiExpression) element))
        return false;
    }

    return !children.isEmpty();
  }