@Nullable
    private static AnnotatedValueResolver of(AnnotatedElement annotatedElement,
                                             AnnotatedElement typeElement, Class<?> type,
                                             Set<String> pathParams,
                                             List<RequestObjectResolver> objectResolvers,
                                             boolean implicitRequestObjectAnnotation,
                                             boolean useBlockingExecutor,
                                             DependencyInjector dependencyInjector,
                                             @Nullable String queryDelimiter) {
        requireNonNull(annotatedElement, "annotatedElement");
        requireNonNull(typeElement, "typeElement");
        requireNonNull(type, "type");
        requireNonNull(pathParams, "pathParams");
        requireNonNull(objectResolvers, "objectResolvers");
        requireNonNull(dependencyInjector, "dependencyInjector");

        final DescriptionInfo description = findDescription(annotatedElement);

        final Attribute attr = annotatedElement.getAnnotation(Attribute.class);
        if (attr != null) {
            final String name = findName(typeElement, attr.value());
            return ofAttribute(name, attr, annotatedElement, typeElement, type, description);
        }

        final Param param = annotatedElement.getAnnotation(Param.class);
        if (param != null) {
            final String name = findName(typeElement, param.value());
            // If the parameter is of type Map and the @Param annotation does not specify a value,
            // map all query parameters into the Map.
            if (Map.class.isAssignableFrom(type)) {
                if (DefaultValues.isSpecified(param.value())) {
                    throw new IllegalArgumentException(
                            String.format("Invalid @Param annotation on Map parameter: '%s'. " +
                                          "The @Param annotation specifies a value ('%s'), " +
                                          "which is not allowed. ",
                                          annotatedElement, param.value()));
                }
                return ofQueryParamMap(name, annotatedElement, typeElement, type, description);
            }
            if (type == File.class || type == Path.class || type == MultipartFile.class) {
                return ofFileParam(name, annotatedElement, typeElement, type, description);
            }
            if (pathParams.contains(name)) {
                return ofPathVariable(name, annotatedElement, typeElement, type, description);
            } else {
                return ofQueryParam(name, annotatedElement, typeElement, type, description, queryDelimiter);
            }
        }

        final Header header = annotatedElement.getAnnotation(Header.class);
        if (header != null) {
            final String name = findName(header, typeElement);
            return ofHeader(name, annotatedElement, typeElement, type, description);
        }

        final String name = getNameOrDefault(typeElement, type.getName());
        final RequestObject requestObject = annotatedElement.getAnnotation(RequestObject.class);
        if (requestObject != null) {
            // Find more request converters from a field or parameter.
            final List<RequestConverter> converters =
                    AnnotationUtil.findDeclared(typeElement, RequestConverter.class);
            return ofRequestObject(name, annotatedElement, type, pathParams,
                                   addToFirstIfExists(objectResolvers, converters, dependencyInjector),
                                   dependencyInjector, description);
        }

        // There should be no '@Default' annotation on 'annotatedElement' if 'annotatedElement' is
        // different from 'typeElement', because it was checked before calling this method.
        // So, 'typeElement' should be used when finding an injectable type because we need to check
        // syntactic errors like below:
        //
        // void method1(@Default("a") ServiceRequestContext ctx) { ... }
        //
        final AnnotatedValueResolver resolver = ofInjectableTypes(name, typeElement, type, useBlockingExecutor);
        if (resolver != null) {
            return resolver;
        }

        final List<RequestConverter> converters =
                AnnotationUtil.findDeclared(typeElement, RequestConverter.class);
        if (!converters.isEmpty()) {
            // Apply @RequestObject implicitly when a @RequestConverter is specified.
            return ofRequestObject(name, annotatedElement, type, pathParams,
                                   addToFirstIfExists(objectResolvers, converters, dependencyInjector),
                                   dependencyInjector, description);
        }

        if (implicitRequestObjectAnnotation) {
            return ofRequestObject(name, annotatedElement, type, pathParams, objectResolvers,
                                   dependencyInjector, description);
        }

        return null;
    }
Creates a new {@link AnnotatedValueResolver} instance if the specified {@code annotatedElement} is
a component of {@link AnnotatedService}.

@param annotatedElement an element which is annotated with a value specifier such as {@link Param} and
                        {@link Header}.
@param typeElement      an element which is used for retrieving its type and name.
@param type             a type of the given {@link Parameter} or {@link Field}. It is a type of
                        the specified {@code typeElement} parameter.
@param pathParams       a set of path variables.
@param objectResolvers  a list of {@link RequestObjectResolver} to be evaluated for the objects which
                        are annotated with {@link RequestObject} annotation.
@param implicitRequestObjectAnnotation {@code true} if an element is always treated like it is annotated
                                       with {@link RequestObject} so that conversion is always done.
                                       {@code false} if an element has to be annotated with
                                       {@link RequestObject} explicitly to get converted.
@param useBlockingExecutor whether to use blocking task executor
core/src/main/java/com/linecorp/armeria/internal/server/annotation/AnnotatedValueResolver.java