@Override
  public final void visitModifierList(@NotNull PsiModifierList list) {
    final PsiModifierList other = (PsiModifierList)myMatchingVisitor.getElement();

    for (@PsiModifier.ModifierConstant String modifier : MODIFIERS) {
      if (!myMatchingVisitor.setResult(!list.hasModifierProperty(modifier) || other.hasModifierProperty(modifier))) {
        return;
      }
    }

    final PsiAnnotation[] annotations = list.getAnnotations();
    if (annotations.length > 0) {
      final Set<PsiAnnotation> annotationSet = ContainerUtil.newHashSet(annotations);

      for (PsiAnnotation annotation : annotations) {
        final PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();

        if (nameReferenceElement != null && MatchOptions.MODIFIER_ANNOTATION_NAME.equals(nameReferenceElement.getText())) {
          final PsiAnnotationParameterList parameterList = annotation.getParameterList();
          final PsiNameValuePair[] attributes = parameterList.getAttributes();

          for (PsiNameValuePair pair : attributes) {
            final PsiAnnotationMemberValue value = pair.getValue();
            if (value == null) continue;

            if (value instanceof PsiArrayInitializerMemberValue) {
              boolean matchedOne = false;

              for (PsiAnnotationMemberValue v : ((PsiArrayInitializerMemberValue)value).getInitializers()) {
                if (annotationValueMatchesModifierList(other, v)) {
                  matchedOne = true;
                  break;
                }
              }

              if (!myMatchingVisitor.setResult(matchedOne)) {
                return;
              }
            }
            else {
              if (!myMatchingVisitor.setResult(annotationValueMatchesModifierList(other, value))) {
                return;
              }
            }
          }

          annotationSet.remove(annotation);
        }
      }

      if (!annotationSet.isEmpty()) {
        final PsiAnnotation[] otherAnnotations = other.getAnnotations();
        final List<PsiElement> unmatchedElements = new SmartList<>(otherAnnotations);
        myMatchingVisitor.getMatchContext().pushMatchedElementsListener(elements -> unmatchedElements.removeAll(elements));
        try {
          myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(annotationSet.toArray(PsiAnnotation.EMPTY_ARRAY), otherAnnotations));
          other.putUserData(GlobalMatchingVisitor.UNMATCHED_ELEMENTS_KEY, unmatchedElements);
        }
        finally {
          myMatchingVisitor.getMatchContext().popMatchedElementsListener();
        }
      }
    }
  }
@Override
  public final void visitModifierList(@NotNull PsiModifierList list)