private Mono<ClientResponse> toClientResponse(HttpResponse response, ClientRequestContext ctx) {
        final SplitHttpResponse splitResponse = response.split();
        return Mono.fromFuture(splitResponse.headers()).flatMap(headers -> {
            if (statusHandler != null) {
                final Throwable cause = statusHandler.handle(ctx, headers.status());
                if (cause != null) {
                    // It would be better to release the resources by consuming than sending an RST stream by
                    // aborting. Because:
                    // - The server may have sent a response body already.
                    // - In general, a stream response is not expected with an error status.
                    // - If too many RSTs are sent, it can be mistaken for 'Rapid Reset' attacks.
                    splitResponse.body().subscribe();
                    return Mono.error(cause);
                }
            }

            final ArmeriaClientHttpResponse httpResponse =
                    new ArmeriaClientHttpResponse(headers, splitResponse,
                                                  DataBufferFactoryWrapper.DEFAULT);

            final HttpStatusCode statusCode = HttpStatusCode.valueOf(httpResponse.getRawStatusCode());
            final ClientResponse clientResponse =
                    ClientResponse.create(statusCode, exchangeStrategies)
                                  .cookies(cookies -> cookies.addAll(httpResponse.getCookies()))
                                  .headers(headers0 -> headers0.addAll(httpResponse.getHeaders()))
                                  .body(httpResponse.getBody())
                                  .build();
            return Mono.just(clientResponse);
        });
    }
Sends the specified {@link HttpRequestValues} to the {@link WebClient} and returns the response.

<p><h4>Implementation note</h4>
In order to encode {@link HttpRequestValues#getBodyValue()} to {@link HttpData}, we need to convert
the {@link HttpRequestValues} to {@link ClientRequest} first. The serialization process is delegated to
the {@link ClientRequest}. After that, the request is written to {@link ArmeriaClientHttpRequest} to send
the request via the {@link WebClient}.

<p>The response handling has to be done in the reverse order. Armeria {@link HttpResponse} is converted
into {@link ArmeriaClientHttpResponse} first and then converted into {@link ClientResponse}.
spring/spring6/src/main/java/com/linecorp/armeria/spring/client/ArmeriaHttpExchangeAdapter.java