private static List<AnnotatedValueResolver> of(Executable constructorOrMethod, Set<String> pathParams,
                                                   List<RequestObjectResolver> objectResolvers,
                                                   boolean implicitRequestObjectAnnotation,
                                                   boolean isServiceMethod,
                                                   boolean useBlockingExecutor,
                                                   DependencyInjector dependencyInjector,
                                                   @Nullable String queryDelimiter) {
        final ImmutableList<Parameter> parameters =
                Arrays.stream(constructorOrMethod.getParameters())
                      .filter(it -> !KotlinUtil.isContinuation(it.getType()))
                      .collect(toImmutableList());
        final int parametersSize = parameters.size();
        if (parametersSize == 0) {
            throw new NoParameterException(constructorOrMethod.toGenericString());
        }

        final Parameter headParameter = parameters.get(0);
        //
        // Try to check whether it is an annotated constructor or method first. e.g.
        //
        // @Param
        // void setter(String name) { ... }
        //
        // In this case, we need to retrieve the value of @Param annotation from 'name' parameter,
        // not the constructor or method. Also 'String' type is used for the parameter.
        //
        final AnnotatedValueResolver resolver;
        if (isAnnotationPresent(constructorOrMethod)) {
            //
            // Only allow a single parameter on an annotated method. The followings cause an error:
            //
            // @Param
            // void setter(String name, int id, String address) { ... }
            //
            // @Param
            // void setter() { ... }
            //
            if (parametersSize != 1) {
                throw new IllegalArgumentException("Only one parameter is allowed to an annotated method: " +
                                                   constructorOrMethod.toGenericString());
            }
            //
            // Filter out the cases like the following:
            //
            // @Param
            // void setter(@Header String name) { ... }
            //
            if (isAnnotationPresent(headParameter)) {
                throw new IllegalArgumentException("Both a method and parameter are annotated: " +
                                                   constructorOrMethod.toGenericString());
            }

            resolver = of(constructorOrMethod,
                          headParameter, headParameter.getType(), pathParams, objectResolvers,
                          implicitRequestObjectAnnotation, useBlockingExecutor,
                          dependencyInjector, queryDelimiter);
        } else if (!isServiceMethod && parametersSize == 1 &&
                   !AnnotationUtil.findDeclared(constructorOrMethod, RequestConverter.class).isEmpty()) {
            //
            // Filter out the cases like the following:
            //
            // @RequestConverter(BeanConverter.class)
            // void setter(@Header String name) { ... }
            //
            if (isAnnotationPresent(headParameter)) {
                throw new IllegalArgumentException("Both a method and parameter are annotated: " +
                                                   constructorOrMethod.toGenericString());
            }
            //
            // Implicitly apply @RequestObject for the following case:
            //
            // @RequestConverter(BeanConverter.class)
            // void setter(Bean bean) { ... }
            //
            resolver = of(headParameter, pathParams, objectResolvers, true,
                          useBlockingExecutor, dependencyInjector, queryDelimiter);
        } else {
            //
            // There's no annotation. So there should be no @Default annotation, too.
            // e.g.
            // @Default("a")
            // void method1(ServiceRequestContext) { ... }
            //
            if (constructorOrMethod.isAnnotationPresent(Default.class)) {
                throw new IllegalArgumentException(
                        '@' + Default.class.getSimpleName() + " is not supported for: " +
                        constructorOrMethod.toGenericString());
            }

            resolver = null;
        }
        //
        // If there is no annotation on the constructor or method, try to check whether it has
        // annotated parameters. e.g.
        //
        // void setter1(@Param String name) { ... }
        // void setter2(@Param String name, @Header List<String> xForwardedFor) { ... }
        //
        final List<AnnotatedValueResolver> list;
        if (resolver != null) {
            list = ImmutableList.of(resolver);
        } else {
            list = parameters.stream()
                             .map(p -> of(p, pathParams, objectResolvers, implicitRequestObjectAnnotation,
                                          useBlockingExecutor, dependencyInjector, queryDelimiter))
                             .filter(Objects::nonNull)
                             .collect(toImmutableList());
        }

        if (list.isEmpty()) {
            throw new NoAnnotatedParameterException(constructorOrMethod.toGenericString());
        }

        if (list.size() != parametersSize) {
            // There are parameters which cannot be resolved, so we cannot accept this constructor or method
            // as an annotated bean or method. We handle this case in two ways as follows.
            if (list.stream().anyMatch(r -> r.annotationType() != null)) {
                // If a user specify one of @Param, @Header or @RequestObject on the parameter list,
                // it clearly means that the user wants to convert the parameter into a bean. e.g.
                //
                // class BeanA {
                //     ...
                //     BeanA(@Param("a") int a, int b) { ... }
                // }
                throw new IllegalArgumentException("Unsupported parameter exists: " +
                                                   constructorOrMethod.toGenericString());
            } else {
                // But for the automatically injected types such as RequestContext and HttpRequest, etc.
                // it is not easy to understand what a user intends for. So we ignore that.
                //
                // class BeanB {
                //     ...
                //     BeanB(ServiceRequestContext ctx, int b) { ... }
                // }
                throw new NoAnnotatedParameterException("Unsupported parameter exists: " +
                                                        constructorOrMethod.toGenericString());
            }
        }
        //
        // If there are annotations used more than once on the constructor or method, warn it.
        //
        // class RequestBean {
        //     RequestBean(@Param("serialNo") Long serialNo, @Param("serialNo") Long serialNo2) { ... }
        // }
        //
        // or
        //
        // void setter(@Param("serialNo") Long serialNo, @Param("serialNo") Long serialNo2) { ... }
        //
        warnOnDuplicateResolver(constructorOrMethod, list);
        return list;
    }
Returns a list of {@link AnnotatedValueResolver} which is constructed with the specified
{@link Executable}, {@code pathParams}, {@code objectResolvers} and
{@code implicitRequestObjectAnnotation}.
The {@link Executable} can be either {@link Constructor} or {@link Method}.

@param isServiceMethod {@code true} if the {@code constructorOrMethod} is a service method.
core/src/main/java/com/linecorp/armeria/internal/server/annotation/AnnotatedValueResolver.java