// Path: heroku-api/src/main/java/com/heroku/api/exception/HerokuAPIException.java
// public class HerokuAPIException extends RuntimeException {
// 
// 
//     public HerokuAPIException(String msg) {
//         super(msg);
//     }
// 
//     public HerokuAPIException(Throwable throwable) {
//         super(throwable);
//     }
// 
//     public HerokuAPIException(String msg, Throwable throwable) {
//         super(msg, throwable);
//     }
// 
// 
// }
// 
// Path: heroku-api/src/main/java/com/heroku/api/http/Http.java
// public class Http {
//     /**
//      * HTTP Accept header model.
//      */
//     public static enum Accept implements Header {
//         JSON("application/json"),
//         TEXT("text/plain");
// 
//         private String value;
//         static String ACCEPT = "Accept";
// 
//         Accept(String val) {
//             this.value = val;
//         }
// 
//         @Override
//         public String getHeaderName() {
//             return ACCEPT;
//         }
// 
//         @Override
//         public String getHeaderValue() {
//             return value;
//         }
// 
//     }
// 
//     /**
//      * HTTP Content-Type header model.
//      */
//     public static enum ContentType implements Header {
//         JSON("application/json"),
//         FORM_URLENCODED("application/x-www-form-urlencoded"),
//         SSH_AUTHKEY("text/ssh-authkey");
// 
//         private String value;
//         static String CONTENT_TYPE = "Content-Type";
// 
//         ContentType(String val) {
//             this.value = val;
//         }
// 
//         @Override
//         public String getHeaderName() {
//             return CONTENT_TYPE;
//         }
// 
//         @Override
//         public String getHeaderValue() {
//             return value;
//         }
// 
//     }
// 
//     /**
//      * HTTP User-Agent header model.
//      *
//      * @see UserAgentValueProvider
//      */
//     public static enum UserAgent implements Header {
//         LATEST(loadValueProvider());
// 
//         static final String USER_AGENT = "User-Agent";
//         private final UserAgentValueProvider userAgentValueProvider;
// 
//         UserAgent(UserAgentValueProvider userAgentValueProvider) {
//             this.userAgentValueProvider = userAgentValueProvider;
//         }
// 
//         @Override
//         public String getHeaderName() {
//             return USER_AGENT;
//         }
// 
//         @Override
//         public String getHeaderValue() {
//           return userAgentValueProvider.getHeaderValue();
//         }
// 
//         public String getHeaderValue(String customPart) {
//             return userAgentValueProvider.getHeaderValue(customPart);
//         }
// 
//         private static UserAgentValueProvider loadValueProvider() {
//             final Iterator<UserAgentValueProvider> customProviders =
//                     ServiceLoader.load(UserAgentValueProvider.class, UserAgent.class.getClassLoader()).iterator();
// 
//             if (customProviders.hasNext()) {
//                 return customProviders.next();
//             } else {
//                 return new UserAgentValueProvider.DEFAULT();
//             }
//         }
//     }
// 
//     /**
//      * Represent a name/value pair for a HTTP header. Not all are implemented. Only those used by the Heroku API.
//      */
//     public static interface Header {
// 
//         public static class Util {
//             public static Map<String, String> setHeaders(Header... headers) {
//                 Map<String, String> headerMap = new HashMap<String, String>();
//                 for (Header h : headers) {
//                     headerMap.put(h.getHeaderName(), h.getHeaderValue());
//                 }
//                 return headerMap;
//             }
//         }
// 
//         String getHeaderName();
// 
//         String getHeaderValue();
// 
//     }
// 
//     /**
//      * HTTP Methods. Not all are implemented. Only those used by the Heroku API.
//      */
//     public static enum Method {GET, PUT, POST, DELETE, PATCH}
// 
//     /**
//      * HTTP Status codes. Not all are implemented. Only those used by the Heroku API.
//      */
//     public static enum Status {
//         OK(200), CREATED(201), ACCEPTED(202), PAYMENT_REQUIRED(402), FORBIDDEN(403), NOT_FOUND(404), UNPROCESSABLE_ENTITY(422), INTERNAL_SERVER_ERROR(500), SERVICE_UNAVAILABLE(503);
// 
//         public final int statusCode;
// 
//         Status(int statusCode) {
//             this.statusCode = statusCode;
//         }
// 
//         public boolean equals(int code) {
//             return statusCode == code;
//         }
//     }
// }


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 java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import com.heroku.api.exception.HerokuAPIException;
import com.heroku.api.http.Http;
        
        public static String getProperty(String propName) {
            return properties.getProperty(propName);
        }

        public static Properties getProperties() {
            return properties;
        }
    }

    public static SSLContext herokuSSLContext() {
        return sslContext(Config.ENDPOINT.isDefault());
    }

    public static SSLContext sslContext(boolean verify) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            TrustManager[] tmgrs = null;
            if (!verify) {
                tmgrs = trustAllTrustManagers();
            }
            /*
Initializes this context.
Either of the first two parameters may be null in which case the installed security providers will be searched
for the highest priority implementation of the appropriate factory.
Likewise, the secure random parameter may be null in which case the default implementation will be used.
            */
            ctx.init(null, tmgrs, null);
            return ctx;
        } catch (NoSuchAlgorithmException e) {
// Path: heroku-api/src/main/java/com/heroku/api/exception/HerokuAPIException.java
// public class HerokuAPIException extends RuntimeException {
// 
// 
//     public HerokuAPIException(String msg) {
//         super(msg);
//     }
// 
//     public HerokuAPIException(Throwable throwable) {
//         super(throwable);
//     }
// 
//     public HerokuAPIException(String msg, Throwable throwable) {
//         super(msg, throwable);
//     }
// 
// 
// }
// 
// Path: heroku-api/src/main/java/com/heroku/api/http/Http.java
// public class Http {
//     /**
//      * HTTP Accept header model.
//      */
//     public static enum Accept implements Header {
//         JSON("application/json"),
//         TEXT("text/plain");
// 
//         private String value;
//         static String ACCEPT = "Accept";
// 
//         Accept(String val) {
//             this.value = val;
//         }
// 
//         @Override
//         public String getHeaderName() {
//             return ACCEPT;
//         }
// 
//         @Override
//         public String getHeaderValue() {
//             return value;
//         }
// 
//     }
// 
//     /**
//      * HTTP Content-Type header model.
//      */
//     public static enum ContentType implements Header {
//         JSON("application/json"),
//         FORM_URLENCODED("application/x-www-form-urlencoded"),
//         SSH_AUTHKEY("text/ssh-authkey");
// 
//         private String value;
//         static String CONTENT_TYPE = "Content-Type";
// 
//         ContentType(String val) {
//             this.value = val;
//         }
// 
//         @Override
//         public String getHeaderName() {
//             return CONTENT_TYPE;
//         }
// 
//         @Override
//         public String getHeaderValue() {
//             return value;
//         }
// 
//     }
// 
//     /**
//      * HTTP User-Agent header model.
//      *
//      * @see UserAgentValueProvider
//      */
//     public static enum UserAgent implements Header {
//         LATEST(loadValueProvider());
// 
//         static final String USER_AGENT = "User-Agent";
//         private final UserAgentValueProvider userAgentValueProvider;
// 
//         UserAgent(UserAgentValueProvider userAgentValueProvider) {
//             this.userAgentValueProvider = userAgentValueProvider;
//         }
// 
//         @Override
//         public String getHeaderName() {
//             return USER_AGENT;
//         }
// 
//         @Override
//         public String getHeaderValue() {
//           return userAgentValueProvider.getHeaderValue();
//         }
// 
//         public String getHeaderValue(String customPart) {
//             return userAgentValueProvider.getHeaderValue(customPart);
//         }
// 
//         private static UserAgentValueProvider loadValueProvider() {
//             final Iterator<UserAgentValueProvider> customProviders =
//                     ServiceLoader.load(UserAgentValueProvider.class, UserAgent.class.getClassLoader()).iterator();
// 
//             if (customProviders.hasNext()) {
//                 return customProviders.next();
//             } else {
//                 return new UserAgentValueProvider.DEFAULT();
//             }
//         }
//     }
// 
//     /**
//      * Represent a name/value pair for a HTTP header. Not all are implemented. Only those used by the Heroku API.
//      */
//     public static interface Header {
// 
//         public static class Util {
//             public static Map<String, String> setHeaders(Header... headers) {
//                 Map<String, String> headerMap = new HashMap<String, String>();
//                 for (Header h : headers) {
//                     headerMap.put(h.getHeaderName(), h.getHeaderValue());
//                 }
//                 return headerMap;
//             }
//         }
// 
//         String getHeaderName();
// 
//         String getHeaderValue();
// 
//     }
// 
//     /**
//      * HTTP Methods. Not all are implemented. Only those used by the Heroku API.
//      */
//     public static enum Method {GET, PUT, POST, DELETE, PATCH}
// 
//     /**
//      * HTTP Status codes. Not all are implemented. Only those used by the Heroku API.
//      */
//     public static enum Status {
//         OK(200), CREATED(201), ACCEPTED(202), PAYMENT_REQUIRED(402), FORBIDDEN(403), NOT_FOUND(404), UNPROCESSABLE_ENTITY(422), INTERNAL_SERVER_ERROR(500), SERVICE_UNAVAILABLE(503);
// 
//         public final int statusCode;
// 
//         Status(int statusCode) {
//             this.statusCode = statusCode;
//         }
// 
//         public boolean equals(int code) {
//             return statusCode == code;
//         }
//     }
// }


// Path: heroku-api/src/main/java/com/heroku/api/Heroku.java
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 java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import com.heroku.api.exception.HerokuAPIException;
import com.heroku.api.http.Http;

        
        public static String getProperty(String propName) {
            return properties.getProperty(propName);
        }

        public static Properties getProperties() {
            return properties;
        }
    }

    public static SSLContext herokuSSLContext() {
        return sslContext(Config.ENDPOINT.isDefault());
    }

    public static SSLContext sslContext(boolean verify) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            TrustManager[] tmgrs = null;
            if (!verify) {
                tmgrs = trustAllTrustManagers();
            }
            /*
Initializes this context.
Either of the first two parameters may be null in which case the installed security providers will be searched
for the highest priority implementation of the appropriate factory.
Likewise, the secure random parameter may be null in which case the default implementation will be used.
            */
            ctx.init(null, tmgrs, null);
            return ctx;
        } catch (NoSuchAlgorithmException e) {
            throw new HerokuAPIException("NoSuchAlgorithmException while trying to setup SSLContext", e);