static KeyExtractor.Factory fromAnnotation(Class<? extends Annotation> annotation) {
    Objects.requireNonNull(annotation, "annotation");

    Predicate<Member> predicate = m -> m instanceof AnnotatedElement
            && ((AnnotatedElement) m).isAnnotationPresent(annotation);

    // there can be multiple members with the same annotation
    Function<Class<?>, List<Member>> membersFn = type -> ClassScanner.of(type)
            .stream()
            .filter(predicate)
            .collect(Collectors.toList());

    return entityType -> {
      Objects.requireNonNull(entityType, "entityType");
      List<Member> members = membersFn.apply(entityType);
      if (members.isEmpty()) {
        // be strict and don't allow entities without a key
        throw new IllegalArgumentException(String.format("Annotation %s not found in members of %s", annotation.getName(), entityType));
      }

      if (members.size() == 1) {
        return new KeyExtractors.SingleMember(entityType, members.get(0));
      }

      return new KeyExtractors.MultipleMembers(entityType, members);
    };
  }
Extract key information based by scanning a class for a particular annotation. Presence
of annotation is required otherwise exception will be thrown.

@throws NullPointerException if argument is null
@throws IllegalArgumentException if annotation is not present on entity class
criteria/common/src/org/immutables/criteria/backend/KeyExtractor.java