package org.jinstagram.http;

import java.io.IOException;
import java.io.InputStream;

import java.net.HttpURLConnection;
import java.net.UnknownHostException;

import java.util.HashMap;
import java.util.Map;

/**
 * Represents an HTTP Response.
 */
public class Response {
	private static final String EMPTY_RESPONSE = "";

	private String body;

	private int code;

	private Map<String, String> headers;

	private InputStream stream;
	
	private String url;

    Response(HttpURLConnection connection) throws IOException {
        try {
            connection.connect();

            url = connection.getURL().toString();
            code = connection.getResponseCode();
            headers = parseHeaders(connection);
            stream = wasSuccessful() ? connection.getInputStream() : connection.getErrorStream();
        } catch (UnknownHostException e) {
            code = HttpStatus.NOT_FOUND.value();
            body = EMPTY_RESPONSE;
        }
    }

    public String getURL() {
		return url;
	}

	private String parseBodyContents() {
		return StreamUtils.getStreamContents(getStream());
	}

	private Map<String, String> parseHeaders(HttpURLConnection conn) {
		Map<String, String> headers = new HashMap<String, String>();

		for (String key : conn.getHeaderFields().keySet()) {
			headers.put(key, conn.getHeaderFields().get(key).get(0));
		}

		return headers;
	}

	private boolean wasSuccessful() {
		return (getCode() >= 200) && (getCode() < 400);
	}

	/**
	 * Obtains the HTTP Response body
	 * 
	 * @return response body
	 */
	public String getBody() {
		if (body == null) {
			body = parseBodyContents();
		}
		return body;
	}

	/**
	 * Obtains the meaningful stream of the HttpUrlConnection, either
	 * inputStream or errorInputStream, depending on the status code
	 * 
	 * @return input stream / error stream
	 */
	public InputStream getStream() {
		return stream;
	}

	/**
	 * Obtains the HTTP status code
	 * 
	 * @return the status code
	 */
	public int getCode() {
		return code;
	}

	/**
	 * Obtains a {@link Map} containing the HTTP Response Headers
	 * 
	 * @return headers
	 */
	public Map<String, String> getHeaders() {
		return headers;
	}

	/**
	 * Obtains a single HTTP Header value, or null if undefined
	 * 
	 * @param headerName name of the header
	 * 
	 * @return header value or null
	 */
	public String getHeader(String headerName) {
		return headers.get(headerName);
	}
}

@@ -171,20 +171,39 @@
 va.util.
-Hash
+List;%0Aimport java.util.
 Map;%0Aimp
@@ -212,24 +212,28 @@
 t java.util.
+Tree
 Map;%0A%0A/**%0A *
@@ -1228,12 +1228,12 @@
 new 
-Hash
+Tree
 Map%3C
@@ -1252,28 +1252,93 @@
 ng%3E(
-);%0A%0A%09%09for (String ke
+String.CASE_INSENSITIVE_ORDER);%0A%0A%09%09for (java.util.Map.Entry%3CString,List%3CString%3E%3E entr
 y : 
@@ -1360,18 +1360,20 @@
 ields().
-k
 e
+ntr
 ySet()) 
@@ -1381,70 +1381,245 @@
 %0A%09%09%09
-headers.put(key, conn.getHeaderFields().get(key).get(0)
+String key= entry.getKey();%0A%09%09%09List%3CString%3E valueList= entry.getValue();%0A%09%09%09if (key!=null && valueList!=null && valueList.size()%3E0) %7B%0A%09%09%09%09String value= valueList.get(0);%0A%09%09%09%09if (value!=null) %7B%0A%09%09%09%09%09headers.put(key, value
 );%0A%09%09
+%09
+%09
 %7D%0A
+%09%09%09%7D%0A%09%09%7D
 %0A%09%09r

Make HTTP header keys case insensitive, make header parsing null safe