package jp.agentec.adf.net.http;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import jp.agentec.abook.abv.bl.acms.type.AcmsApis;
import jp.agentec.abook.abv.bl.common.exception.ABVRuntimeException;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.adf.net.http.HttpHeaderProperties.PropertyKey;
import jp.agentec.adf.util.DateTimeUtil;
import jp.agentec.adf.util.StringUtil;

/**
 * HTTP通信のリクエストとレスポンスを処理する為の機能を提供します。<br>
 * このクラスは、post及びgetの簡単な通信を手伝うためのクラスであり、<br>
 * request及びresponseの詳細な制御が必要な場合は、このクラスを利用せずに、独自のコードを作成してください。
 * @author Taejin Hong
 * @version 1.1.0 
 */
public class HttpRequestSender {
	private static final String TAG = "HttpRequestSender";
	
	/**
	 * ホストに接続するまでのタイムアウト時間をミリ秒で設定します。<br>
	 * デフォルトは20,000ミリ秒（20秒）です。
	 * @since 1.0.0
	 */
	public static final int DefaultConnectionTimeout = 20 * 1000;
	/**
	 * 通信に利用する既定の文字セットです。UTF-8となります。
	 * @since 1.0.0
	 */
	public static final String DefaultEncoding = "UTF-8";
	public static final String MethodPost = "POST";
	public static final String MethodGet = "GET";
	public static final String MethodDelete = "DELETE";
    public static final String MethodHead = "HEAD";
	public static String testUserAgent;

	static {
		trustAllHosts();
	}

	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * @param url ホストのURL文字列です。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, T param) throws IOException {
		return send(MethodPost, url, DefaultEncoding, param, null, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * @param url ホストのURL文字列です。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, T param, int connectionTimeout) throws IOException {
		return send(MethodPost, url, DefaultEncoding, param, null, connectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * @param url ホストのURL文字列です。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, T param, HttpHeaderProperties properties) throws IOException {
		return send(MethodPost, url, DefaultEncoding, param, properties, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * @param url ホストのURL文字列です。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, T param, int connectionTimeout, HttpHeaderProperties properties) throws IOException {
		return send(MethodPost, url, DefaultEncoding, param, properties, connectionTimeout);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。<br>
	 * UTF-8でエンコーディングします。
	 * @param url ホストのURL文字列です。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, HttpMultipart[] multiparts) throws IOException {
		return send(url, DefaultEncoding, null, DefaultConnectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * UTF-8でエンコーディングします。
	 * @param url ホストのURL文字列です。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, int connectionTimeout, HttpMultipart[] multiparts) throws IOException {
		return send(url, DefaultEncoding, null, connectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。<br>
	 * UTF-8でエンコーディングします。
	 * @param url ホストのURL文字列です。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, HttpHeaderProperties properties, HttpMultipart[] multiparts) throws IOException {
		return send(url, DefaultEncoding, properties, DefaultConnectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * UTF-8でエンコーディングします。
	 * @param url ホストのURL文字列です。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, int connectionTimeout, HttpHeaderProperties properties, HttpMultipart[] multiparts) throws IOException {
		return send(url, DefaultEncoding, properties, connectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, T param) throws IOException {
		return send(MethodPost, url, DefaultEncoding, param, null, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, T param, int connectionTimeout) throws IOException {
		return send(MethodPost, url, DefaultEncoding, param, null, connectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, T param, HttpHeaderProperties properties) throws IOException {
		return send(MethodPost, url, DefaultEncoding, param, properties, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, T param, int connectionTimeout, HttpHeaderProperties properties) throws IOException {
		return send(MethodPost, url, DefaultEncoding, param, properties, connectionTimeout);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。<br>
	 * UTF-8でエンコーディングします。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, HttpMultipart[] multiparts) throws IOException {
		return send(url, DefaultEncoding, null, DefaultConnectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * UTF-8でエンコーディングします。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, int connectionTimeout, HttpMultipart[] multiparts) throws IOException {
		return send(url, DefaultEncoding, null, connectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。<br>
	 * UTF-8でエンコーディングします。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, HttpHeaderProperties properties, HttpMultipart[] multiparts) throws IOException {
		return send(url, DefaultEncoding, properties, DefaultConnectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * UTF-8でエンコーディングします。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, int connectionTimeout, HttpHeaderProperties properties, HttpMultipart[] multiparts) throws IOException {
		return send(url, DefaultEncoding, properties, connectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, String encoding, T param) throws IOException {
		return send(MethodPost, url, encoding, param, null, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, String encoding, T param, int connectionTimeout) throws IOException {
		return send(MethodPost, url, encoding, param, null, connectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, String encoding, T param, HttpHeaderProperties properties) throws IOException {
		return send(MethodPost, url, encoding, param, properties, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, String encoding, T param, int connectionTimeout, HttpHeaderProperties properties) throws IOException {
		return send(MethodPost, url, encoding, param, properties, connectionTimeout);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, String encoding, HttpMultipart[] multiparts) throws IOException {
		return send(url, encoding, null, DefaultConnectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, String encoding, int connectionTimeout, HttpMultipart[] multiparts) throws IOException {
		return send(url, encoding, null, connectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, String encoding, HttpHeaderProperties properties, HttpMultipart[] multiparts) throws IOException {
		return send(url, encoding, properties, DefaultConnectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(String url, String encoding, int connectionTimeout, HttpHeaderProperties properties, HttpMultipart[] multiparts) throws IOException {
		return send(url, encoding, properties, connectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, String encoding, T param) throws IOException {
		return send(MethodPost, url, encoding, param, null, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, String encoding, T param, int connectionTimeout) throws IOException {
		return send(MethodPost, url, encoding, param, null, connectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, String encoding, T param, HttpHeaderProperties properties) throws IOException {
		return send(MethodPost, url, encoding, param, properties, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにPOSTリクエストを送信し、レスポンスの文字列を返します。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, String encoding, T param, int connectionTimeout, HttpHeaderProperties properties) throws IOException {
		return send(MethodPost, url, encoding, param, properties, connectionTimeout);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, String encoding, HttpMultipart[] multiparts) throws IOException {
		return send(url, encoding, null, DefaultConnectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, String encoding, int connectionTimeout, HttpMultipart[] multiparts) throws IOException {
		return send(url, encoding, null, connectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, String encoding, HttpHeaderProperties properties, HttpMultipart[] multiparts) throws IOException {
		return send(url, encoding, properties, DefaultConnectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにmultipart POSTリクエストを送信し、レスポンスの文字列を返します。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @param multiparts multipartの配列です。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.1.0
	 */
	public static <T extends HttpParameterObject> HttpResponse post(URL url, String encoding, int connectionTimeout, HttpHeaderProperties properties, HttpMultipart[] multiparts) throws IOException {
		return send(url, encoding, properties, connectionTimeout, multiparts);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストのURL文字列です。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(String url, T param) throws IOException {
		return send(MethodGet, url, DefaultEncoding, param, null, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * @param url ホストのURL文字列です。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(String url, T param, int connectionTimeout) throws IOException {
		return send(MethodGet, url, DefaultEncoding, param, null, connectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストのURL文字列です。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(String url, T param, HttpHeaderProperties properties) throws IOException {
		return send(MethodGet, url, DefaultEncoding, param, properties, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * @param url ホストのURL文字列です。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(String url, T param, int connectionTimeout, HttpHeaderProperties properties) throws IOException {
		return send(MethodGet, url, DefaultEncoding, param, properties, connectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(URL url) throws IOException {
		return send(MethodGet, url, DefaultEncoding, null, null, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(URL url, int connectionTimeout) throws IOException {
		return send(MethodGet, url, DefaultEncoding, null, null, connectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * パラメータはUTF-8でエンコーディングします。
	 * param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(URL url, int connectionTimeout, HttpHeaderProperties properties) throws IOException {
		return send(MethodGet, url, DefaultEncoding, null, properties, connectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(String url, String encoding, T param) throws IOException {
		return send(MethodGet, url, encoding, param, null, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(String url, String encoding, T param, int connectionTimeout) throws IOException {
		return send(MethodGet, url, encoding, param, null, connectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(String url, String encoding, T param, HttpHeaderProperties properties) throws IOException {
		return send(MethodGet, url, encoding, param, properties, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。
	 * @param url ホストのURL文字列です。
	 * @param encoding 通信に利用する文字セットです。
	 * @param param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(String url, String encoding, T param, int connectionTimeout, HttpHeaderProperties properties) throws IOException {
		return send(MethodGet, url, encoding, param, properties, connectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(URL url, String encoding) throws IOException {
		return send(MethodGet, url, encoding, null, null, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。
	 * param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(URL url, String encoding, int connectionTimeout) throws IOException {
		return send(MethodGet, url, encoding, null, null, connectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。<br>
	 * ホストに接続するまでのデフォルトのタイムアウト時間は {@link HttpRequestSender#DefaultConnectionTimeout} はです。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param encoding 通信に利用する文字セットです。
	 * パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(URL url, String encoding, HttpHeaderProperties properties) throws IOException {
		return send(MethodGet, url, encoding, null, properties, DefaultConnectionTimeout);
	}
	
	/**
	 * 指定したURLにGETリクエストを送信し、レスポンスの文字列を返します。
	 * param パラメータのインスタンス。これは {@link HttpParameterObject} を継承している必要があります。
	 * @param url ホストの {@link URL} オブジェクトです。
	 * @param connectionTimeout ホストに接続するまでのタイムアウト時間をミリ秒で設定します。
	 * @param properties リクエストヘッダーのプロパティを追加・書き替えする場合、{@link HttpHeaderProperties} を設定します。
	 * @return ホストのレスポンスを文字列で返します。
	 * @since 1.0.0 
	 */
	public static <T extends HttpParameterObject> HttpResponse get(URL url, String encoding, int connectionTimeout, HttpHeaderProperties properties) throws IOException {
		return send(MethodGet, url, encoding, null, properties, connectionTimeout);
	}
	
	public static <T extends HttpParameterObject> HttpResponse delete(String url) throws IOException {
		return send(MethodDelete, new URL(url), DefaultEncoding, null, null, DefaultConnectionTimeout);
	}

    public static HttpResponse head(String url, HttpHeaderProperties properties, int connectionTimeout) throws IOException {
        return send(MethodHead, url, null, null, properties, connectionTimeout);
    }

    public static HttpResponse head(String url, HttpHeaderProperties properties) throws IOException {
        return send(MethodHead, url, null, null, properties, DefaultConnectionTimeout);
    }
	

	private static <T extends HttpParameterObject> HttpResponse send(String method, String url, String encoding, T param, HttpHeaderProperties properties, int connectionTimeout) throws IOException {
		HttpResponse response = new HttpResponse();
		URL hostUrl;
		
		if (!StringUtil.isNullOrWhiteSpace(url)) {

            hostUrl = getAdummyUrl(url, param, method, encoding);
            response = send(method, hostUrl, encoding, param, properties, connectionTimeout);
		}
		
		return response;
	}
	
	private static <T extends HttpParameterObject> HttpResponse send(String method, URL url, String encoding, T param, HttpHeaderProperties properties, int connectionTimeout) throws IOException {
		HttpResponse response = new HttpResponse();
		HttpURLConnection conn = null;
		BufferedReader reader = null;
		StringBuffer sb = new StringBuffer();
		
		if (url != null) {
			try {
				conn = openConnection(method, url, encoding, param, properties, connectionTimeout);
				try {
					response.httpResponseCode = conn.getResponseCode();
					response.eTag = conn.getHeaderField("ETag");
				} catch (IOException e) { // androidの糞ソースのお陰で401のとき、getResponseCode()でIOExceptionがthrowされる。もう一度getResponseCode()で401も取れる。
					try {
						Logger.e(TAG, "http send error. " + e.toString());
						response.httpResponseCode = conn.getResponseCode();
						Logger.e(TAG, "hhttpResponseCode=" + response.httpResponseCode);
						if (response.httpResponseCode != 401) {
							throw e;
						}
					} catch (IOException e2) {
						if (e2.getMessage().contains("authentication")) { // API level14では再度getResponseCode()をしてもIOExceptionがthrowされるのでここで返す。
							response.httpResponseCode = 401;
							return response;
						}
					}
				}
				response.httpResponseMessage = conn.getResponseMessage();
				
				try {
					if (response.httpResponseCode >= 200 && response.httpResponseCode < 300) {
                        reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    } else if (response.httpResponseCode == 304) {
                        // データ変更なし
                        return response;
					} else {
                        InputStream is = conn.getErrorStream();
                        if (is != null) {
                            reader = new BufferedReader(new InputStreamReader(is));
                        }
					}

                    if (!method.equals(MethodHead) && reader != null) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            sb.append(line);
                        }
                    }

				} catch (IOException e) {
					if (response.httpResponseCode >= 200 && response.httpResponseCode < 300) { // TODO: later この条件でいいか？
						throw e;
					}
				}
				
				response.httpResponseBody = sb.toString();
			} finally {
				if (reader != null) {
					try {
						reader.close();
                    } catch (Exception e2) {}
				}
				
				if (conn != null) {
					try {
						conn.disconnect();
                    } catch (Exception e2) {}
				}
			}
		}
		
		return response;
	}
	
	private static HttpResponse send(String url, String encoding, HttpHeaderProperties properties, int connectionTimeout, HttpMultipart[] multiparts) throws IOException {
		HttpResponse response = new HttpResponse();
		
		if (!StringUtil.isNullOrEmpty(url)) {
            URL hostUrl = getAdummyUrl(url, null, null, encoding);
			response = send(hostUrl, encoding, properties, connectionTimeout, multiparts);
		}
		
		return response;
	}
	
	private static <T extends HttpParameterObject> HttpResponse send(URL url, String encoding, HttpHeaderProperties properties, int connectionTimeout, HttpMultipart[] multiparts) throws IOException {
		HttpResponse response = new HttpResponse();
		HttpURLConnection conn = null;
		BufferedReader reader = null;
		StringBuffer sb = new StringBuffer();
		
		if (url != null) {
			try {
				conn = openConnectionMultipartPost(url, encoding, properties, connectionTimeout, multiparts);
				
				response.httpResponseCode = conn.getResponseCode();
				response.httpResponseMessage = conn.getResponseMessage();
				
				try {
					if (response.httpResponseCode >= 200 && response.httpResponseCode < 300) {
						reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
					} else {
						reader = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
					}

					String line;
					
					while ((line = reader.readLine()) != null) {
						sb.append(line);
					}
				} catch (IOException e) {
					if (response.httpResponseCode >= 200 && response.httpResponseCode < 300) {// TODO: later この条件でいいか？
						throw e;
					}
				}
				
				response.httpResponseBody = sb.toString();
			} finally {
				if (reader != null) {
					try {
						reader.close();
                    } catch (Exception e2) {}
				}
				
				if (conn != null) {
					try {
						conn.disconnect();
                    } catch (Exception e2) {}
				}
			}
		}
		
		return response;
	}
	
	public static <T extends HttpParameterObject> HttpURLConnection openConnection(String method, URL url, String encoding, T param, HttpHeaderProperties properties, int connectionTimeout) throws IOException {
		HttpURLConnection conn = null;
		OutputStreamWriter writer = null;
		
		if (url != null) {
			try {
				if (url.getProtocol().toLowerCase().equals("https")) {
					HttpsURLConnection httpsConn = (HttpsURLConnection)url.openConnection();
					httpsConn.setHostnameVerifier(DO_NOT_VERIFY);
					conn = httpsConn;
				} else {
					conn = (HttpURLConnection) url.openConnection();
				}
				conn.setConnectTimeout(connectionTimeout);
				conn.setRequestMethod(method);
				
				if (testUserAgent != null) {
					if (properties == null) {
						properties = new HttpHeaderProperties();
						properties.addProperty(PropertyKey.UserAgent, testUserAgent);
					}
				}

				setRequestProperties(conn, properties);

				String paramStr = null;
				
				if (method.equals(MethodPost)) {
					conn.setDoOutput(true);
					
					conn.setRequestProperty(HttpHeaderProperties.PropertyKey.AcceptCharset.key(), encoding);
					
					if (properties != null && !properties.containsKey(HttpHeaderProperties.PropertyKey.ContentType)) {
						conn.setRequestProperty(HttpHeaderProperties.PropertyKey.ContentType.key(), "application/x-www-form-urlencoded;charset=" + encoding);
					}

					if (param != null) {
						paramStr = param.toHttpParameterString(encoding);
					}
				} else if (method.equals(MethodHead)) {
                    conn.setInstanceFollowRedirects(false);
                }
				conn.connect();
				
				if (!StringUtil.isNullOrWhiteSpace(paramStr)) {
					writer = new OutputStreamWriter(conn.getOutputStream());
                    if(paramStr != null) {
                        writer.write(paramStr);
                        //	writer.write(paramStr.getBytes(encoding));
                        writer.flush();
                    }

				}
			} finally {
				if (writer != null) {
					try {
						writer.close();
                    } catch (Exception e2) {}
				}
			}
		}
		
		return conn;
	}
	
	public static <T extends HttpParameterObject> HttpURLConnection openConnectionMultipartPost(URL url, String encoding, HttpHeaderProperties properties, int connectionTimeout, HttpMultipart[] multiparts) throws IOException {
		HttpURLConnection conn = null;
		PrintWriter writer = null;
		OutputStream os;
		
		if (url != null && multiparts != null && multiparts.length > 0) {
			try {
				if (url.getProtocol().toLowerCase().equals("https")) {
					HttpsURLConnection httpsConn = (HttpsURLConnection)url.openConnection();
					httpsConn.setHostnameVerifier(DO_NOT_VERIFY);
					conn = httpsConn;
				} else {
					conn = (HttpURLConnection) url.openConnection();
				}
				conn.setConnectTimeout(connectionTimeout);
				conn.setRequestMethod(MethodPost);
				
				if (testUserAgent != null) {
					if (properties == null) {
						properties = new HttpHeaderProperties();
						properties.addProperty(PropertyKey.UserAgent, testUserAgent);
					}
				}

				setRequestProperties(conn, properties);

				String boundary = Long.toHexString(System.currentTimeMillis());
				
				conn.setDoOutput(true);
				
				conn.setRequestProperty(HttpHeaderProperties.PropertyKey.AcceptCharset.key(), encoding);
				
				if (properties == null || !properties.containsKey(HttpHeaderProperties.PropertyKey.ContentType)) {
					conn.setRequestProperty(HttpHeaderProperties.PropertyKey.ContentType.key(), "multipart/form-data;boundary=" + boundary);
				}
				
				conn.connect();
				
				os = conn.getOutputStream();
				writer = new PrintWriter(new OutputStreamWriter(os, encoding), true);
				
				for (HttpMultipart multipart : multiparts) {
					writer.append("--" + boundary).append(StringUtil.CRLF);
					writer.append(multipart.toString());
					
					writer.flush();
					
					if (multipart.isFileAttach()) {
						InputStream is = null;
						
						try {
							is = new FileInputStream(multipart.getFile());
							byte[] buf = new byte[1024];
							int len;
							
							while ((len = is.read(buf)) > 0) {
								os.write(buf, 0, len);
							}
							
							os.flush();
						} finally {
							if (is != null) {
								try { is.close(); } catch (Exception e) {}
							}
						}
						
						writer.append(StringUtil.CRLF);
						writer.flush();
					}
				}
				
				writer.append("--" + boundary + "--");
				writer.append(StringUtil.CRLF);
				writer.flush();
			} finally {
				if (writer != null) {
					try {
						writer.close();
                    } catch (Exception e2) {}
				}
			}
		}
		
		return conn;
	}
	
	final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
		@Override
        public boolean verify(String hostname, SSLSession session) {
				return true;
		}
	};

	private static void trustAllHosts() {
		// Install the all-trusting trust manager
		try {
			SSLContext sc = SSLContext.getInstance("TLS");
			sc.init(null, new TrustManager[]{new AGTX509TrustManager(null)}, new java.security.SecureRandom());
			HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
		} catch (Exception e) {
			throw new ABVRuntimeException(e);
		}
	}

	private static HttpURLConnection setRequestProperties(HttpURLConnection conn, HttpHeaderProperties properties) {
		if (conn != null && properties != null && properties.size() > 0) {
			for (PropertyKey property : properties.keySet()) {
				if (property.equals(PropertyKey.IfModifiedSince)) {
					// IfModifiedSinceをEtagと複数でリクエストする時、
					// Android 6以下はsetIfModifiedSince()とsetRequestProperty()別々でセットすると
					// 変化がなくてもhttpResponseCodeが200で帰ってくる場合もあるので、
					// IfModifiedSinceのセットをsetRequestProperty()で使用
					Date date = new Date(Long.valueOf(properties.get(property)));
					String lastmodified = DateTimeUtil.lastModifiedConnectFormatGmt(date);
					conn.setRequestProperty(property.key(), lastmodified);
				} else {
					conn.setRequestProperty(property.key(), properties.get(property));
				}
			}
		}


		
		return conn;
	}

    //URLにadummyの特定キーを追加する処理
    private static <T extends HttpParameterObject> URL getAdummyUrl(String url, T param, String method, String encoding) {
        URL adummyUrl = null;
        String adummy = null;
        StringBuilder urlPath = new StringBuilder(url);

        if (!url.contains(AcmsApis.ApiUrlNewAppStoreLogin) && !url.contains(AcmsApis.ApiUrlAppStoreNewLogin)) {
            adummy = ABVDataCache.getInstance().getAdummyKey();
        }

        if (method != null && method.equals(MethodGet) && param != null) {
            urlPath.append("?" + param.toHttpParameterString(encoding));
        }
        if (adummy != null) {
			urlPath.append((urlPath.toString().contains("?") ? "&" : "?") + "adummy=" + adummy);
        }
        try {
            adummyUrl = new URL(urlPath.toString());
        } catch (MalformedURLException e) {
            Logger.e(TAG, "getAdummyUrl error. " + e);
        }
        return adummyUrl;
    }
}
