@SuppressWarnings("unchecked")
    static <A extends Annotation> @Nullable A getAnnotationRecursively(
            final @NonNull AnnotationAccessor annotations,
            final @NonNull Class<A> clazz,
            final @NonNull Set<Class<? extends Annotation>> checkedAnnotations
    ) {
        A innerCandidate = null;
        for (final Annotation annotation : annotations.annotations()) {
            if (!checkedAnnotations.add(annotation.annotationType())) {
                continue;
            }
            if (annotation.annotationType().equals(clazz)) {
                return (A) annotation;
            }
            if (annotation.annotationType().getPackage().getName().startsWith("java.lang")) {
                continue;
            }
            final A inner = getAnnotationRecursively(
                    AnnotationAccessor.of(annotation.annotationType()),
                    clazz,
                    checkedAnnotations
            );
            if (inner != null) {
                innerCandidate = inner;
            }
        }
        return innerCandidate;
    }
Construct a new annotation parser

@param manager           Command manager instance
@param commandSenderType Command sender type
@param metaMapper        Function that is used to create {@link CommandMeta} instances from annotations on the
                         command methods. These annotations will be mapped to
                         {@link ParserParameter}. Mappers for the
                         parser parameters can be registered using {@link #registerAnnotationMapper(Class, AnnotationMapper)}
cloud-annotations/src/main/java/org/incendo/cloud/annotations/AnnotationParser.java