private void checkExpression(PsiExpression expression, final PsiAnnotation[] annotations, ProblemsHolder holder) {
    if (annotations.length == 0) return;
    final PsiAnnotation psiAnnotation = annotations[0];

    // cache compiled pattern with annotation
    CachedValue<Pattern> p = psiAnnotation.getUserData(COMPLIED_PATTERN);
    if (p == null) {
      final CachedValueProvider<Pattern> provider = () -> {
        final String pattern = AnnotationUtilEx.calcAnnotationValue(psiAnnotation, "value");
        Pattern p1 = null;
        if (pattern != null) {
          try {
            p1 = Pattern.compile(pattern);
          }
          catch (PatternSyntaxException e) {
            // pattern stays null
          }
        }
        return CachedValueProvider.Result.create(p1, (Object[])annotations);
      };
      p = CachedValuesManager.getManager(expression.getProject()).createCachedValue(provider, false);
      psiAnnotation.putUserData(COMPLIED_PATTERN, p);
    }

    final Pattern pattern = p.getValue();
    if (pattern == null) return;

    List<PsiExpression> nonConstantElements = new SmartList<>();
    Configuration configuration = Configuration.getInstance();
    final Object result = new SubstitutedExpressionEvaluationHelper(expression.getProject()).computeExpression(
      expression, configuration.getAdvancedConfiguration().getDfaOption(), false, nonConstantElements);
    final String o = result == null ? null : String.valueOf(result);
    if (o != null) {
      if (!pattern.matcher(o).matches()) {
        if (annotations.length > 1) {
          // the last element contains the element's actual annotation
          final String fqn = annotations[annotations.length - 1].getQualifiedName();
          assert fqn != null;

          final String name = StringUtil.getShortName(fqn);
          holder.registerProblem(expression,
                                 IntelliLangBundle.message("inspection.message.expression.does.not.match.pattern", o, name,
                                                           pattern.pattern()));
        }
        else {
          holder.registerProblem(expression,
                                 IntelliLangBundle.message("inspection.message.expression.does.not.match.pattern2", o, pattern.pattern()));
        }
      }
    }
    else if (CHECK_NON_CONSTANT_VALUES) {
      for (PsiExpression expr : nonConstantElements) {
        final PsiElement e;
        if (expr instanceof PsiReferenceExpression) {
          e = ((PsiReferenceExpression)expr).resolve();
        }
        else if (expr instanceof PsiMethodCallExpression) {
          e = ((PsiMethodCallExpression)expr).getMethodExpression().resolve();
        }
        else {
          e = expr;
        }
        final PsiModifierListOwner owner = ObjectUtils.tryCast(e, PsiModifierListOwner.class);
        List<LocalQuickFix> fixes = new SmartList<>();
        if (owner != null && PsiUtilEx.isLanguageAnnotationTarget(owner)) {
          PsiAnnotation[] resolvedAnnos =
            AnnotationUtilEx.getAnnotationFrom(owner, configuration.getAdvancedConfiguration().getPatternAnnotationPair(), true);
          if (resolvedAnnos.length == 2 &&
              annotations.length == 2 &&
              Comparing.strEqual(resolvedAnnos[1].getQualifiedName(), annotations[1].getQualifiedName())) {
            // both target and source annotated indirectly with the same anno
            return;
          }
        }
        if (holder.isOnTheFly()) {
          final String classname = configuration.getAdvancedConfiguration().getSubstAnnotationPair().first;
          if (owner != null && AddAnnotationFixWithoutArgFix.isApplicable(owner, classname)) {
            fixes.add(new AddAnnotationFixWithoutArgFix(classname, owner));
          } else {
            fixes.add(new IntroduceVariableFix(false));
          }
        }
        else {
          fixes.add(new IntroduceVariableFix(false));
        }
        holder.registerProblem(expr, IntelliLangBundle.message("inspection.pattern.validator.description"),
                               fixes.toArray(LocalQuickFix.EMPTY_ARRAY));
      }
    }
  }
private void checkExpression(PsiExpression expression, final PsiAnnotation[] annotations, ProblemsHolder holder)