// Path: src/org/httpkit/ProtocolException.java
// public class ProtocolException extends HTTPException {
// 
//     private static final long serialVersionUID = 1L;
// 
//     public ProtocolException(String msg) {
//         super(msg);
//     }
// }
// 
// Path: src/org/httpkit/HttpUtils.java
// public static final byte SP = 32;
// 
// Path: src/org/httpkit/HttpUtils.java
// public static InetSocketAddress getServerAddr(URI uri) throws UnknownHostException {
//     InetAddress host = getByName(uri.getHost());
//     return new InetSocketAddress(host, getPort(uri));
// }


import org.httpkit.*;
import org.httpkit.ProtocolException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import static java.lang.System.currentTimeMillis;
import static java.nio.channels.SelectionKey.*;
import static org.httpkit.HttpUtils.SP;
import static org.httpkit.HttpUtils.getServerAddr;
import static org.httpkit.client.State.ALL_READ;
import static org.httpkit.client.State.READ_INITIAL;
        try {
            request = encode(cfg.method, headers, cfg.body, uri);
        } catch (IOException e) {
            cb.onThrowable(e);
            return;
        }
        if ("https".equals(scheme)) {
            if (engine == null) {
                engine = DEFAULT_CONTEXT.createSSLEngine();
            }
            engine.setUseClientMode(true);
            pending.offer(new HttpsRequest(addr, request, cb, requests, cfg, engine));
        } else {
            pending.offer(new Request(addr, request, cb, requests, cfg));
        }

//        pending.offer(new Request(addr, request, cb, requests, cfg));
        selector.wakeup();
    }

    private ByteBuffer[] encode(HttpMethod method, HeaderMap headers, Object body,
                                URI uri) throws IOException {
        ByteBuffer bodyBuffer = HttpUtils.bodyBuffer(body);

        if (body != null) {
            headers.put("Content-Length", Integer.toString(bodyBuffer.remaining()));
        } else {
            headers.put("Content-Length", "0");
        }
        DynamicBytes bytes = new DynamicBytes(196);
// Path: src/org/httpkit/ProtocolException.java
// public class ProtocolException extends HTTPException {
// 
//     private static final long serialVersionUID = 1L;
// 
//     public ProtocolException(String msg) {
//         super(msg);
//     }
// }
// 
// Path: src/org/httpkit/HttpUtils.java
// public static final byte SP = 32;
// 
// Path: src/org/httpkit/HttpUtils.java
// public static InetSocketAddress getServerAddr(URI uri) throws UnknownHostException {
//     InetAddress host = getByName(uri.getHost());
//     return new InetSocketAddress(host, getPort(uri));
// }


// Path: src/org/httpkit/client/HttpClient.java
import org.httpkit.*;
import org.httpkit.ProtocolException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import static java.lang.System.currentTimeMillis;
import static java.nio.channels.SelectionKey.*;
import static org.httpkit.HttpUtils.SP;
import static org.httpkit.HttpUtils.getServerAddr;
import static org.httpkit.client.State.ALL_READ;
import static org.httpkit.client.State.READ_INITIAL;

        try {
            request = encode(cfg.method, headers, cfg.body, uri);
        } catch (IOException e) {
            cb.onThrowable(e);
            return;
        }
        if ("https".equals(scheme)) {
            if (engine == null) {
                engine = DEFAULT_CONTEXT.createSSLEngine();
            }
            engine.setUseClientMode(true);
            pending.offer(new HttpsRequest(addr, request, cb, requests, cfg, engine));
        } else {
            pending.offer(new Request(addr, request, cb, requests, cfg));
        }

//        pending.offer(new Request(addr, request, cb, requests, cfg));
        selector.wakeup();
    }

    private ByteBuffer[] encode(HttpMethod method, HeaderMap headers, Object body,
                                URI uri) throws IOException {
        ByteBuffer bodyBuffer = HttpUtils.bodyBuffer(body);

        if (body != null) {
            headers.put("Content-Length", Integer.toString(bodyBuffer.remaining()));
        } else {
            headers.put("Content-Length", "0");
        }
        DynamicBytes bytes = new DynamicBytes(196);
        bytes.append(method.toString()).append(SP).append(HttpUtils.getPath(uri));