// Path: library/src/main/java/org/mariotaku/restfu/http/mime/Body.java
// public interface Body extends Closeable {
//     ContentType contentType();
// 
//     String contentEncoding();
// 
//     long length() throws IOException;
// 
//     long writeTo(final OutputStream os) throws IOException;
// 
//     InputStream stream() throws IOException;
// 
//     void close() throws IOException;
// 
// }


import org.jetbrains.annotations.NotNull;
import org.mariotaku.commons.collection.Pair;
import org.mariotaku.commons.io.StreamUtils;
import org.mariotaku.restfu.http.*;
import org.mariotaku.restfu.http.mime.Body;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
package org.mariotaku.restfu.urlconnection;



/**
 * Created by mariotaku on 16/2/12.
 */
public class URLConnectionRestClient implements RestHttpClient {
    @NotNull
    @Override
    public HttpCall newCall(@NotNull HttpRequest request) {
        return new URLConnectionCall(request);
    }

    @Override
    public void enqueue(@NotNull HttpCall call, @NotNull HttpCallback callback) {
        call.enqueue(callback);
    }

    static class URLConnectionCall implements HttpCall {

        private final HttpRequest request;
        private URLConnectionResponse resp;

        public URLConnectionCall(HttpRequest request) {
            this.request = request;
        }

        @NotNull
        @Override
        public HttpResponse execute() throws IOException {
            if (resp != null) throw new IllegalStateException("A call can be executed only once");
            final URL url = new URL(request.getUrl());
            final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod(request.getMethod());
            for (Pair<String, String> pair : request.getHeaders().toList()) {
                conn.addRequestProperty(pair.first, pair.second);
            }
// Path: library/src/main/java/org/mariotaku/restfu/http/mime/Body.java
// public interface Body extends Closeable {
//     ContentType contentType();
// 
//     String contentEncoding();
// 
//     long length() throws IOException;
// 
//     long writeTo(final OutputStream os) throws IOException;
// 
//     InputStream stream() throws IOException;
// 
//     void close() throws IOException;
// 
// }


// Path: urlconnection/src/main/java/org/mariotaku/restfu/urlconnection/URLConnectionRestClient.java
import org.jetbrains.annotations.NotNull;
import org.mariotaku.commons.collection.Pair;
import org.mariotaku.commons.io.StreamUtils;
import org.mariotaku.restfu.http.*;
import org.mariotaku.restfu.http.mime.Body;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;

package org.mariotaku.restfu.urlconnection;



/**
 * Created by mariotaku on 16/2/12.
 */
public class URLConnectionRestClient implements RestHttpClient {
    @NotNull
    @Override
    public HttpCall newCall(@NotNull HttpRequest request) {
        return new URLConnectionCall(request);
    }

    @Override
    public void enqueue(@NotNull HttpCall call, @NotNull HttpCallback callback) {
        call.enqueue(callback);
    }

    static class URLConnectionCall implements HttpCall {

        private final HttpRequest request;
        private URLConnectionResponse resp;

        public URLConnectionCall(HttpRequest request) {
            this.request = request;
        }

        @NotNull
        @Override
        public HttpResponse execute() throws IOException {
            if (resp != null) throw new IllegalStateException("A call can be executed only once");
            final URL url = new URL(request.getUrl());
            final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod(request.getMethod());
            for (Pair<String, String> pair : request.getHeaders().toList()) {
                conn.addRequestProperty(pair.first, pair.second);
            }
            final Body body = request.getBody();