private <T extends Sniffer> List<T> getApplicableSniffers(
      List<URI> uris, Types types, Collection<T> sniffers, boolean checkPath) {
    if (sniffers == null || sniffers.isEmpty()) {
      return Collections.emptyList();
    }

    List<T> result = new ArrayList<T>();
    for (T sniffer : sniffers) {
      Class<? extends Annotation>[] annotations = sniffer.getAnnotationTypes();
      if (annotations == null) continue;
      for (Class<? extends Annotation> annotationType : annotations) {
        if (types != null) {
          Type type = types.getBy(annotationType.getName());
          if (type instanceof AnnotationType) {
            Collection<AnnotatedElement> elements = ((AnnotationType) type).allAnnotatedTypes();
            for (AnnotatedElement element : elements) {
              if (checkPath) {
                Type t =
                    (element instanceof Member
                        ? ((Member) element).getDeclaringType()
                        : (Type) element);
                if (t.wasDefinedIn(uris)) {
                  result.add(sniffer);
                  break;
                }
              } else {
                result.add(sniffer);
                break;
              }
            }
          }
        }
      }
    }
    return result;
  }