// Path: src/main/java/com/webfluxclient/client/RequestExecutor.java
// public interface RequestExecutor {
//     Mono<ClientResponse> execute(Request request);
// }
// 
// Path: src/main/java/com/webfluxclient/client/ResponseBodyProcessor.java
// public interface ResponseBodyProcessor {
//     Object process(Mono<ClientResponse> monoResponse, ResolvableType bodyType);
// }
// 
// Path: src/main/java/com/webfluxclient/metadata/MethodMetadata.java
// @Getter
// public class MethodMetadata {
//     private Method targetMethod;
//     private ResolvableType responseBodyType;
//     private RequestTemplate requestTemplate;
//     
//     private MethodMetadata(Builder builder) {
//         targetMethod = builder.targetMethod;
//         responseBodyType = builder.returnType;
//         requestTemplate = new RequestTemplate(
//                 builder.uriBuilder,
//                 builder.httpMethod,
//                 new RequestHeaders(builder.headers, builder.headerIndexToName),
//                 builder.bodyIndex,
//                 builder.bodyType,
//                 builder.variableIndexToName);
//     }
//     
//     public static Builder newBuilder(URI baseUri) {
//         return new Builder(baseUri.getScheme(), baseUri.getAuthority());
//     }
//     
//     public static Builder newBuilder(MethodMetadata other) {
//         return new Builder(other);
//     }
//     
//     public static class Builder {
//         private UriBuilder uriBuilder;
//         private MultiValueMap<Integer, String> variableIndexToName;
//         private Map<String, RequestHeader> headers;
//         private Map<Integer, String> headerIndexToName;
//         private HttpMethod httpMethod;
//         private Method targetMethod;
//         private Integer bodyIndex;
//         private ResolvableType returnType;
//         private ResolvableType bodyType;
//         
//         private Builder() {
//             variableIndexToName = new LinkedMultiValueMap<>();
//             headers = new HashMap<>();
//             headerIndexToName = new HashMap<>();
//         }
//         
//         public Builder(String scheme, String authority) {
//             this();
//             if (scheme != null && authority != null) {
//                 uriBuilder = new DefaultUriBuilderFactory(scheme + "://" + authority).builder();
//             }
//             else {
//                 uriBuilder = new DefaultUriBuilderFactory().builder();
//             }
//         }
//         
//         public Builder(MethodMetadata other) {
//             this();
//             uriBuilder = new DefaultUriBuilderFactory(other.getRequestTemplate().getUriBuilder().build().toString()).builder();
//             variableIndexToName.putAll(other.getRequestTemplate().getVariableIndexToName());
//             headers.putAll(other.getRequestTemplate().getRequestHeaders().getHeaders());
//             headerIndexToName.putAll(other.getRequestTemplate().getRequestHeaders().getIndexToName());
//             httpMethod = other.getRequestTemplate().getHttpMethod();
//             targetMethod = other.getTargetMethod();
//         }
//         
//         public Builder addPath(String path) {
//             uriBuilder.path(path);
//             return this;
//         }
//         
//         public Builder addPathIndex(Integer index, String pathVariable) {
//             this.variableIndexToName.add(index, pathVariable);
//             return this;
//         }
//         
//         public Builder addHeader(String name, String value) {
//             headers.put(name, new RequestHeader.BasicRequestHeader(name, value));
//             return this;
//         }
//         
//         public Builder addHeader(Integer index, String name) {
//             headers.put(name, new RequestHeader.DynamicRequestHeader(name));
//             headerIndexToName.put(index, name);
//             return this;
//         }
//         
//         public Builder addParameter(Integer index, String name) {
//             variableIndexToName.add(index, name);
//             uriBuilder.query(name + "={" + name + "}");
//             return this;
//         }
//         
//         public Builder httpMethod(HttpMethod httpMethod) {
//             this.httpMethod = httpMethod;
//             return this;
//         }
//         
//         public Builder body(Integer bodyIndex, Type bodyType) {
//             if (this.bodyType != null && this.bodyIndex != null) {
//                 throw new IllegalArgumentException();
//             }
//             
//             this.bodyIndex = bodyIndex;
//             this.bodyType = ResolvableType.forType(bodyType);
//             return this;
//         }
//         
//         public Builder targetMethod(Method targetMethod) {
//             this.targetMethod = targetMethod;
//             this.returnType = ResolvableType.forMethodReturnType(targetMethod);
//             return this;
//         }
//         
//         public MethodMetadata build() {
//             return new MethodMetadata(this);
//         }
//     }
// }
// 
// Path: src/main/java/com/webfluxclient/metadata/request/Request.java
// public interface Request {
//     
//     HttpMethod httpMethod();
//     
//     HttpHeaders headers();
//     
//     Map<String, Object> variables();
//     
//     BodyInserter<?, ? super ClientHttpRequest> bodyInserter();
//     
//     URI expand();
// }


import com.webfluxclient.client.RequestExecutor;
import com.webfluxclient.client.ResponseBodyProcessor;
import com.webfluxclient.metadata.MethodMetadata;
import com.webfluxclient.metadata.request.Request;
import org.springframework.web.reactive.function.client.ClientResponse;
import reactor.core.publisher.Mono;
package com.webfluxclient.handler;


public class DefaultClientMethodHandler implements ClientMethodHandler {

    private MethodMetadata methodMetadata;
    private RequestExecutor requestExecutor;
    private ResponseBodyProcessor responseBodyProcessor;
    DefaultClientMethodHandler(MethodMetadata methodMetadata,
                               RequestExecutor requestExecutor,
                               ResponseBodyProcessor responseBodyProcessor) {
        this.methodMetadata = methodMetadata;
        this.requestExecutor = requestExecutor;
        this.responseBodyProcessor = responseBodyProcessor;
    }

    @Override
    public Object invoke(Object[] args) {
// Path: src/main/java/com/webfluxclient/client/RequestExecutor.java
// public interface RequestExecutor {
//     Mono<ClientResponse> execute(Request request);
// }
// 
// Path: src/main/java/com/webfluxclient/client/ResponseBodyProcessor.java
// public interface ResponseBodyProcessor {
//     Object process(Mono<ClientResponse> monoResponse, ResolvableType bodyType);
// }
// 
// Path: src/main/java/com/webfluxclient/metadata/MethodMetadata.java
// @Getter
// public class MethodMetadata {
//     private Method targetMethod;
//     private ResolvableType responseBodyType;
//     private RequestTemplate requestTemplate;
//     
//     private MethodMetadata(Builder builder) {
//         targetMethod = builder.targetMethod;
//         responseBodyType = builder.returnType;
//         requestTemplate = new RequestTemplate(
//                 builder.uriBuilder,
//                 builder.httpMethod,
//                 new RequestHeaders(builder.headers, builder.headerIndexToName),
//                 builder.bodyIndex,
//                 builder.bodyType,
//                 builder.variableIndexToName);
//     }
//     
//     public static Builder newBuilder(URI baseUri) {
//         return new Builder(baseUri.getScheme(), baseUri.getAuthority());
//     }
//     
//     public static Builder newBuilder(MethodMetadata other) {
//         return new Builder(other);
//     }
//     
//     public static class Builder {
//         private UriBuilder uriBuilder;
//         private MultiValueMap<Integer, String> variableIndexToName;
//         private Map<String, RequestHeader> headers;
//         private Map<Integer, String> headerIndexToName;
//         private HttpMethod httpMethod;
//         private Method targetMethod;
//         private Integer bodyIndex;
//         private ResolvableType returnType;
//         private ResolvableType bodyType;
//         
//         private Builder() {
//             variableIndexToName = new LinkedMultiValueMap<>();
//             headers = new HashMap<>();
//             headerIndexToName = new HashMap<>();
//         }
//         
//         public Builder(String scheme, String authority) {
//             this();
//             if (scheme != null && authority != null) {
//                 uriBuilder = new DefaultUriBuilderFactory(scheme + "://" + authority).builder();
//             }
//             else {
//                 uriBuilder = new DefaultUriBuilderFactory().builder();
//             }
//         }
//         
//         public Builder(MethodMetadata other) {
//             this();
//             uriBuilder = new DefaultUriBuilderFactory(other.getRequestTemplate().getUriBuilder().build().toString()).builder();
//             variableIndexToName.putAll(other.getRequestTemplate().getVariableIndexToName());
//             headers.putAll(other.getRequestTemplate().getRequestHeaders().getHeaders());
//             headerIndexToName.putAll(other.getRequestTemplate().getRequestHeaders().getIndexToName());
//             httpMethod = other.getRequestTemplate().getHttpMethod();
//             targetMethod = other.getTargetMethod();
//         }
//         
//         public Builder addPath(String path) {
//             uriBuilder.path(path);
//             return this;
//         }
//         
//         public Builder addPathIndex(Integer index, String pathVariable) {
//             this.variableIndexToName.add(index, pathVariable);
//             return this;
//         }
//         
//         public Builder addHeader(String name, String value) {
//             headers.put(name, new RequestHeader.BasicRequestHeader(name, value));
//             return this;
//         }
//         
//         public Builder addHeader(Integer index, String name) {
//             headers.put(name, new RequestHeader.DynamicRequestHeader(name));
//             headerIndexToName.put(index, name);
//             return this;
//         }
//         
//         public Builder addParameter(Integer index, String name) {
//             variableIndexToName.add(index, name);
//             uriBuilder.query(name + "={" + name + "}");
//             return this;
//         }
//         
//         public Builder httpMethod(HttpMethod httpMethod) {
//             this.httpMethod = httpMethod;
//             return this;
//         }
//         
//         public Builder body(Integer bodyIndex, Type bodyType) {
//             if (this.bodyType != null && this.bodyIndex != null) {
//                 throw new IllegalArgumentException();
//             }
//             
//             this.bodyIndex = bodyIndex;
//             this.bodyType = ResolvableType.forType(bodyType);
//             return this;
//         }
//         
//         public Builder targetMethod(Method targetMethod) {
//             this.targetMethod = targetMethod;
//             this.returnType = ResolvableType.forMethodReturnType(targetMethod);
//             return this;
//         }
//         
//         public MethodMetadata build() {
//             return new MethodMetadata(this);
//         }
//     }
// }
// 
// Path: src/main/java/com/webfluxclient/metadata/request/Request.java
// public interface Request {
//     
//     HttpMethod httpMethod();
//     
//     HttpHeaders headers();
//     
//     Map<String, Object> variables();
//     
//     BodyInserter<?, ? super ClientHttpRequest> bodyInserter();
//     
//     URI expand();
// }


// Path: src/main/java/com/webfluxclient/handler/DefaultClientMethodHandler.java
import com.webfluxclient.client.RequestExecutor;
import com.webfluxclient.client.ResponseBodyProcessor;
import com.webfluxclient.metadata.MethodMetadata;
import com.webfluxclient.metadata.request.Request;
import org.springframework.web.reactive.function.client.ClientResponse;
import reactor.core.publisher.Mono;

package com.webfluxclient.handler;


public class DefaultClientMethodHandler implements ClientMethodHandler {

    private MethodMetadata methodMetadata;
    private RequestExecutor requestExecutor;
    private ResponseBodyProcessor responseBodyProcessor;
    DefaultClientMethodHandler(MethodMetadata methodMetadata,
                               RequestExecutor requestExecutor,
                               ResponseBodyProcessor responseBodyProcessor) {
        this.methodMetadata = methodMetadata;
        this.requestExecutor = requestExecutor;
        this.responseBodyProcessor = responseBodyProcessor;
    }

    @Override
    public Object invoke(Object[] args) {
        Request request = methodMetadata.getRequestTemplate().apply(args);