private int computeComplexity(PsiExpression expression) {
    expression = PsiUtil.skipParenthesizedExprDown(expression);

    if (expression instanceof PsiAssignmentExpression || expression instanceof PsiSuperExpression) {
      return TOO_COMPLEX;
    }

    if (expression instanceof PsiLiteralExpression || expression instanceof PsiQualifiedExpression) {
      return 1;
    }

    if (expression instanceof PsiUnaryExpression) {
      IElementType tokenType = ((PsiUnaryExpression)expression).getOperationTokenType();
      if (JavaTokenType.PLUSPLUS.equals(tokenType) || JavaTokenType.MINUSMINUS.equals(tokenType)) {
        return TOO_COMPLEX;
      }
      return 1 + getComplexity(((PsiUnaryExpression)expression).getOperand());
    }

    if (expression instanceof PsiBinaryExpression) {
      int complexity = 1 + getComplexity(((PsiBinaryExpression)expression).getLOperand());
      if (complexity > MAX_ACCEPTABLE) return complexity;
      return complexity + getComplexity(((PsiBinaryExpression)expression).getROperand());
    }

    if (expression instanceof PsiConditionalExpression) {
      int complexity = 1 + getComplexity(((PsiConditionalExpression)expression).getCondition());
      if (complexity > MAX_ACCEPTABLE) return complexity;

      complexity += getComplexity(((PsiConditionalExpression)expression).getThenExpression());
      if (complexity > MAX_ACCEPTABLE) return complexity;

      return complexity + getComplexity(((PsiConditionalExpression)expression).getElseExpression());
    }

    if (expression instanceof PsiArrayAccessExpression) {
      int complexity = 3 + getComplexity(((PsiArrayAccessExpression)expression).getArrayExpression());
      if (complexity > MAX_ACCEPTABLE) return complexity;

      return complexity + getComplexity(((PsiArrayAccessExpression)expression).getIndexExpression());
    }

    if (expression instanceof PsiReferenceExpression) {
      PsiElement resolved = ((PsiReferenceExpression)expression).resolve();
      if (resolved == null || isWithinScope(resolved)) {
        return TOO_COMPLEX;
      }
      if (resolved instanceof PsiVariable &&
          ((PsiVariable)resolved).hasModifierProperty(PsiModifier.STATIC) &&
          ((PsiVariable)resolved).hasModifierProperty(PsiModifier.FINAL)) {
        return 1;
      }

      PsiExpression qualifier = ((PsiReferenceExpression)expression).getQualifierExpression();
      if (qualifier == null) {
        return 2;
      }
      return 2 + getComplexity(qualifier);
    }

    if (expression instanceof PsiMethodCallExpression) {
      PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expression).getMethodExpression();
      PsiElement resolved = methodExpression.resolve();
      if (resolved == null || isWithinScope(resolved)) {
        return TOO_COMPLEX;
      }
      int complexity = 3;
      PsiExpression qualifier = methodExpression.getQualifierExpression();
      if (qualifier != null) {
        complexity += getComplexity(qualifier);
        if (complexity > MAX_ACCEPTABLE) {
          return complexity;
        }
      }
      PsiExpression[] arguments = ((PsiMethodCallExpression)expression).getArgumentList().getExpressions();
      for (PsiExpression argument : arguments) {
        complexity += getComplexity(argument);
        if (complexity > MAX_ACCEPTABLE) {
          return complexity;
        }
      }
      return complexity;
    }

    return TOO_COMPLEX;
  }
private int computeComplexity(PsiExpression expression)