// Path: http-builder-ng-core/src/main/java/groovyx/net/http/util/IoUtils.java
// public class IoUtils {
// 
//     /**
//      * Reads all bytes from the stream into a byte array.
//      *
//      * @param inputStream the {@link InputStream}
//      * @return the array of bytes from the stream
//      * @throws IOException if there is a problem reading the stream
//      */
//     public static byte[] streamToBytes(final InputStream inputStream) throws IOException {
//         return streamToBytes(inputStream, true);
//     }
// 
//     public static byte[] streamToBytes(final InputStream inputStream, boolean close) throws IOException {
//         try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
//             final byte[] bytes = new byte[2_048];
// 
//             int read;
//             while ((read = inputStream.read(bytes)) != -1) {
//                 outputStream.write(bytes, 0, read);
//             }
// 
//             return outputStream.toByteArray();
// 
//         } finally {
//             if (close) inputStream.close();
//         }
//     }
// 
//     /**
//      * Safely copies the contents of the {@link BufferedInputStream} to a {@link String} and resets the stream.
//      * This method is generally only useful for testing and logging purposes.
//      *
//      * @param inputStream the BufferedInputStream
//      * @return a String copy of the stream contents
//      * @throws IOException           if something goes wrong with the stream
//      * @throws IllegalStateException if the stream cannot be reset
//      */
//     public static String copyAsString(final BufferedInputStream inputStream) throws IOException, IllegalStateException {
//         if (inputStream == null) return null;
// 
//         try {
//             inputStream.mark(Integer.MAX_VALUE);
//             return new String(streamToBytes(inputStream, false));
//         } finally {
//             try {
//                 inputStream.reset();
//             } catch (IOException ioe) {
//                 throw new IllegalStateException("Unable to reset stream - original stream content may be corrupted");
//             }
//         }
//     }
// 
//     /**
//      * Transfers the contents of the {@link InputStream} into the {@link OutputStream}, optionally closing the stream.
//      *
//      * @param istream the input stream
//      * @param ostream the output stream
//      * @param close   whether or not to close the output stream
//      */
//     public static void transfer(final InputStream istream, final OutputStream ostream, final boolean close) {
//         try {
//             final byte[] bytes = new byte[2_048];
//             int read;
//             while ((read = istream.read(bytes)) != -1) {
//                 ostream.write(bytes, 0, read);
//             }
//         } catch (IOException e) {
//             throw new TransportingException(e);
//         } finally {
//             if (close) {
//                 try {
//                     ostream.close();
//                 } catch (IOException ioe) {
//                     throw new TransportingException(ioe);
//                 }
//             }
//         }
//     }
// }
// 
// Path: http-builder-ng-core/src/main/java/groovyx/net/http/FromServer.java
// public static Header<?> keyValue(String key, String value) {
//     final BiFunction<String, String, ? extends Header> func = constructors.get(key);
//     return func == null ? new ValueOnly(key, value) : func.apply(key, value);
// }
// 
// Path: http-builder-ng-core/src/main/java/groovyx/net/http/HttpBuilder.java
// static final ResponseHandlerFunction HANDLER_FUNCTION = new ResponseHandlerFunction();


import com.burgstaller.okhttp.AuthenticationCacheInterceptor;
import com.burgstaller.okhttp.CachingAuthenticatorDecorator;
import com.burgstaller.okhttp.digest.CachingAuthenticator;
import com.burgstaller.okhttp.digest.DigestAuthenticator;
import groovy.lang.Closure;
import groovy.lang.DelegatesTo;
import groovyx.net.http.util.IoUtils;
import okhttp3.*;
import okio.BufferedSink;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.net.Proxy;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
import static groovyx.net.http.FromServer.Header.keyValue;
import static groovyx.net.http.HttpBuilder.ResponseHandlerFunction.HANDLER_FUNCTION;
import static groovyx.net.http.HttpConfig.AuthType.DIGEST;
import static okhttp3.MediaType.parse;
        }
    }

    private class OkHttpFromServer implements FromServer {

        private final URI uri;
        private final Response response;
        private List<Header<?>> headers;
        private boolean body;

        private OkHttpFromServer(final URI uri, final Response response) {
            this.uri = uri;
            this.response = response;
            this.headers = populateHeaders();

            addCookieStore(uri, headers);

            try {
                body = !response.body().source().exhausted() && response.peekBody(1).bytes().length > 0;
            } catch (IOException e) {
                body = false;
            }
        }

        private List<Header<?>> populateHeaders() {
            final Headers headers = response.headers();
            List<Header<?>> ret = new ArrayList<>();
            for (String name : headers.names()) {
                List<String> values = headers.values(name);
                for (String value : values) {
// Path: http-builder-ng-core/src/main/java/groovyx/net/http/util/IoUtils.java
// public class IoUtils {
// 
//     /**
//      * Reads all bytes from the stream into a byte array.
//      *
//      * @param inputStream the {@link InputStream}
//      * @return the array of bytes from the stream
//      * @throws IOException if there is a problem reading the stream
//      */
//     public static byte[] streamToBytes(final InputStream inputStream) throws IOException {
//         return streamToBytes(inputStream, true);
//     }
// 
//     public static byte[] streamToBytes(final InputStream inputStream, boolean close) throws IOException {
//         try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
//             final byte[] bytes = new byte[2_048];
// 
//             int read;
//             while ((read = inputStream.read(bytes)) != -1) {
//                 outputStream.write(bytes, 0, read);
//             }
// 
//             return outputStream.toByteArray();
// 
//         } finally {
//             if (close) inputStream.close();
//         }
//     }
// 
//     /**
//      * Safely copies the contents of the {@link BufferedInputStream} to a {@link String} and resets the stream.
//      * This method is generally only useful for testing and logging purposes.
//      *
//      * @param inputStream the BufferedInputStream
//      * @return a String copy of the stream contents
//      * @throws IOException           if something goes wrong with the stream
//      * @throws IllegalStateException if the stream cannot be reset
//      */
//     public static String copyAsString(final BufferedInputStream inputStream) throws IOException, IllegalStateException {
//         if (inputStream == null) return null;
// 
//         try {
//             inputStream.mark(Integer.MAX_VALUE);
//             return new String(streamToBytes(inputStream, false));
//         } finally {
//             try {
//                 inputStream.reset();
//             } catch (IOException ioe) {
//                 throw new IllegalStateException("Unable to reset stream - original stream content may be corrupted");
//             }
//         }
//     }
// 
//     /**
//      * Transfers the contents of the {@link InputStream} into the {@link OutputStream}, optionally closing the stream.
//      *
//      * @param istream the input stream
//      * @param ostream the output stream
//      * @param close   whether or not to close the output stream
//      */
//     public static void transfer(final InputStream istream, final OutputStream ostream, final boolean close) {
//         try {
//             final byte[] bytes = new byte[2_048];
//             int read;
//             while ((read = istream.read(bytes)) != -1) {
//                 ostream.write(bytes, 0, read);
//             }
//         } catch (IOException e) {
//             throw new TransportingException(e);
//         } finally {
//             if (close) {
//                 try {
//                     ostream.close();
//                 } catch (IOException ioe) {
//                     throw new TransportingException(ioe);
//                 }
//             }
//         }
//     }
// }
// 
// Path: http-builder-ng-core/src/main/java/groovyx/net/http/FromServer.java
// public static Header<?> keyValue(String key, String value) {
//     final BiFunction<String, String, ? extends Header> func = constructors.get(key);
//     return func == null ? new ValueOnly(key, value) : func.apply(key, value);
// }
// 
// Path: http-builder-ng-core/src/main/java/groovyx/net/http/HttpBuilder.java
// static final ResponseHandlerFunction HANDLER_FUNCTION = new ResponseHandlerFunction();


// Path: http-builder-ng-okhttp/src/main/java/groovyx/net/http/OkHttpBuilder.java
import com.burgstaller.okhttp.AuthenticationCacheInterceptor;
import com.burgstaller.okhttp.CachingAuthenticatorDecorator;
import com.burgstaller.okhttp.digest.CachingAuthenticator;
import com.burgstaller.okhttp.digest.DigestAuthenticator;
import groovy.lang.Closure;
import groovy.lang.DelegatesTo;
import groovyx.net.http.util.IoUtils;
import okhttp3.*;
import okio.BufferedSink;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.net.Proxy;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
import static groovyx.net.http.FromServer.Header.keyValue;
import static groovyx.net.http.HttpBuilder.ResponseHandlerFunction.HANDLER_FUNCTION;
import static groovyx.net.http.HttpConfig.AuthType.DIGEST;
import static okhttp3.MediaType.parse;

        }
    }

    private class OkHttpFromServer implements FromServer {

        private final URI uri;
        private final Response response;
        private List<Header<?>> headers;
        private boolean body;

        private OkHttpFromServer(final URI uri, final Response response) {
            this.uri = uri;
            this.response = response;
            this.headers = populateHeaders();

            addCookieStore(uri, headers);

            try {
                body = !response.body().source().exhausted() && response.peekBody(1).bytes().length > 0;
            } catch (IOException e) {
                body = false;
            }
        }

        private List<Header<?>> populateHeaders() {
            final Headers headers = response.headers();
            List<Header<?>> ret = new ArrayList<>();
            for (String name : headers.names()) {
                List<String> values = headers.values(name);
                for (String value : values) {
                    ret.add(keyValue(name, value));