// Path: heroku-deploy/src/main/java/com/heroku/sdk/deploy/util/CustomHttpClientBuilder.java
// public class CustomHttpClientBuilder {
// 
//     public static CloseableHttpClient build() {
//         /*
//         Workaround for JDK-8220723 (https://bugs.openjdk.java.net/browse/JDK-8220723)
//         We limit the available protocols to TLS 1.2 to avoid triggering the bug with TLS 1.3.
// 
//         Version 11.0.2 is significant to us as it is the default OpenJDK version on Travis CI for Java 11. Since running
//         on CI/CD is one of the main use-cases for this library, we can justify this workaround for a bug in an older
//         version of the JDK.
// 
//         As soon as 11.0.2 is no longer the default on Travis please consider removing this workaround.
// 
//         Issue: https://github.com/heroku/heroku-maven-plugin/issues/71
//         */
//         if (System.getProperty("java.version").equals("11.0.2")) {
//             final String[] supportedProtocols = new String[] { "TLSv1.2" };
//             final String[] supportedCipherSuites = split(System.getProperty("https.cipherSuites"));
// 
//             LayeredConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
//                     (SSLSocketFactory) SSLSocketFactory.getDefault(),
//                     supportedProtocols, supportedCipherSuites, new DefaultHostnameVerifier(PublicSuffixMatcherLoader.getDefault()));
// 
//             return HttpClientBuilder
//                     .create()
//                     .useSystemProperties()
//                     .setSSLSocketFactory(sslConnectionSocketFactory)
//                     .build();
//         }
// 
//         return HttpClients.createSystem();
//     }
// 
//     private static String[] split(final String s) {
//         if (TextUtils.isBlank(s)) {
//             return null;
//         }
//         return s.split(" *, *");
//     }
// }
// 
// Path: heroku-deploy/src/main/java/com/heroku/sdk/deploy/util/PropertiesUtils.java
// public class PropertiesUtils {
// 
//     public static <T> Properties loadOrEmptyFromClasspath(Class<T> clazz, String name) {
//         final Properties properties = new Properties();
//         try (final InputStream stream = clazz.getResourceAsStream(name)) {
//             if (stream != null) {
//                 properties.load(stream);
//             }
//         } catch (IOException e) {
//             // Ignore exception, this will return empty properties later.
//         }
// 
//         return properties;
//     }
// 
//     /**
//      * Loads the pom.properties for an artifact from classpath.
//      *
//      * @param clazz The class of which classloader should be used to read the pom.properties
//      * @param groupId The groupId for which the pom.properties should be loaded
//      * @param artifactId The artifactId for which the pom.properties should be loaded
//      * @param <T> The type of the class modeled by the given Class object
//      * @return The loaded properties
//      *
//      * @see <a href="http://maven.apache.org/shared/maven-archiver/#class_archive">http://maven.apache.org/shared/maven-archiver/#class_archive</a>
//      */
//     public static <T> Properties loadPomPropertiesOrEmptyFromClasspath(Class<T> clazz, String groupId, String artifactId) {
//         return loadOrEmptyFromClasspath(clazz, String.format("/META-INF/maven/%s/%s/pom.properties", groupId, artifactId));
//     }
// }
// 
// Path: heroku-deploy/src/main/java/com/heroku/sdk/deploy/util/Util.java
// public class Util {
//     public static Stream<String> readLinesFromInputStream(InputStream inputStream) throws IOException {
//         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
// 
//         try {
//             return bufferedReader.lines();
//         } catch (UncheckedIOException e) {
//             throw e.getCause();
//         }
//     }
// }


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.heroku.sdk.deploy.util.CustomHttpClientBuilder;
import com.heroku.sdk.deploy.util.PropertiesUtils;
import com.heroku.sdk.deploy.util.Util;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.eclipse.jgit.util.Base64;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
        HttpPost request = new HttpPost("https://api.heroku.com/apps/" + appName + "/builds");
        httpHeaders.forEach(request::setHeader);
        request.setEntity(apiPayloadEntity);

        CloseableHttpResponse response = client.execute(request);

        return handleBuildInfoResponse(appName, mapper, response);
    }

    public BuildInfo getBuildInfo(String appName, String buildId) throws IOException, HerokuDeployApiException {
        ObjectMapper mapper = new ObjectMapper();
        CloseableHttpClient client = CustomHttpClientBuilder.build();

        HttpUriRequest request = new HttpGet("https://api.heroku.com/apps/" + appName + "/builds/" + buildId);
        httpHeaders.forEach(request::setHeader);

        CloseableHttpResponse response = client.execute(request);

        return handleBuildInfoResponse(appName, mapper, response);
    }

    public Stream<String> followBuildOutputStream(URI buildOutputStreamUri) throws IOException {
        CloseableHttpClient client = CustomHttpClientBuilder.build();

        HttpGet request = new HttpGet(buildOutputStreamUri);
        httpHeaders.forEach(request::setHeader);

        CloseableHttpResponse response = client.execute(request);
        HttpEntity responseEntity = response.getEntity();

// Path: heroku-deploy/src/main/java/com/heroku/sdk/deploy/util/CustomHttpClientBuilder.java
// public class CustomHttpClientBuilder {
// 
//     public static CloseableHttpClient build() {
//         /*
//         Workaround for JDK-8220723 (https://bugs.openjdk.java.net/browse/JDK-8220723)
//         We limit the available protocols to TLS 1.2 to avoid triggering the bug with TLS 1.3.
// 
//         Version 11.0.2 is significant to us as it is the default OpenJDK version on Travis CI for Java 11. Since running
//         on CI/CD is one of the main use-cases for this library, we can justify this workaround for a bug in an older
//         version of the JDK.
// 
//         As soon as 11.0.2 is no longer the default on Travis please consider removing this workaround.
// 
//         Issue: https://github.com/heroku/heroku-maven-plugin/issues/71
//         */
//         if (System.getProperty("java.version").equals("11.0.2")) {
//             final String[] supportedProtocols = new String[] { "TLSv1.2" };
//             final String[] supportedCipherSuites = split(System.getProperty("https.cipherSuites"));
// 
//             LayeredConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
//                     (SSLSocketFactory) SSLSocketFactory.getDefault(),
//                     supportedProtocols, supportedCipherSuites, new DefaultHostnameVerifier(PublicSuffixMatcherLoader.getDefault()));
// 
//             return HttpClientBuilder
//                     .create()
//                     .useSystemProperties()
//                     .setSSLSocketFactory(sslConnectionSocketFactory)
//                     .build();
//         }
// 
//         return HttpClients.createSystem();
//     }
// 
//     private static String[] split(final String s) {
//         if (TextUtils.isBlank(s)) {
//             return null;
//         }
//         return s.split(" *, *");
//     }
// }
// 
// Path: heroku-deploy/src/main/java/com/heroku/sdk/deploy/util/PropertiesUtils.java
// public class PropertiesUtils {
// 
//     public static <T> Properties loadOrEmptyFromClasspath(Class<T> clazz, String name) {
//         final Properties properties = new Properties();
//         try (final InputStream stream = clazz.getResourceAsStream(name)) {
//             if (stream != null) {
//                 properties.load(stream);
//             }
//         } catch (IOException e) {
//             // Ignore exception, this will return empty properties later.
//         }
// 
//         return properties;
//     }
// 
//     /**
//      * Loads the pom.properties for an artifact from classpath.
//      *
//      * @param clazz The class of which classloader should be used to read the pom.properties
//      * @param groupId The groupId for which the pom.properties should be loaded
//      * @param artifactId The artifactId for which the pom.properties should be loaded
//      * @param <T> The type of the class modeled by the given Class object
//      * @return The loaded properties
//      *
//      * @see <a href="http://maven.apache.org/shared/maven-archiver/#class_archive">http://maven.apache.org/shared/maven-archiver/#class_archive</a>
//      */
//     public static <T> Properties loadPomPropertiesOrEmptyFromClasspath(Class<T> clazz, String groupId, String artifactId) {
//         return loadOrEmptyFromClasspath(clazz, String.format("/META-INF/maven/%s/%s/pom.properties", groupId, artifactId));
//     }
// }
// 
// Path: heroku-deploy/src/main/java/com/heroku/sdk/deploy/util/Util.java
// public class Util {
//     public static Stream<String> readLinesFromInputStream(InputStream inputStream) throws IOException {
//         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
// 
//         try {
//             return bufferedReader.lines();
//         } catch (UncheckedIOException e) {
//             throw e.getCause();
//         }
//     }
// }


// Path: heroku-deploy/src/main/java/com/heroku/sdk/deploy/api/HerokuDeployApi.java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.heroku.sdk.deploy.util.CustomHttpClientBuilder;
import com.heroku.sdk.deploy.util.PropertiesUtils;
import com.heroku.sdk.deploy.util.Util;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.eclipse.jgit.util.Base64;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

        HttpPost request = new HttpPost("https://api.heroku.com/apps/" + appName + "/builds");
        httpHeaders.forEach(request::setHeader);
        request.setEntity(apiPayloadEntity);

        CloseableHttpResponse response = client.execute(request);

        return handleBuildInfoResponse(appName, mapper, response);
    }

    public BuildInfo getBuildInfo(String appName, String buildId) throws IOException, HerokuDeployApiException {
        ObjectMapper mapper = new ObjectMapper();
        CloseableHttpClient client = CustomHttpClientBuilder.build();

        HttpUriRequest request = new HttpGet("https://api.heroku.com/apps/" + appName + "/builds/" + buildId);
        httpHeaders.forEach(request::setHeader);

        CloseableHttpResponse response = client.execute(request);

        return handleBuildInfoResponse(appName, mapper, response);
    }

    public Stream<String> followBuildOutputStream(URI buildOutputStreamUri) throws IOException {
        CloseableHttpClient client = CustomHttpClientBuilder.build();

        HttpGet request = new HttpGet(buildOutputStreamUri);
        httpHeaders.forEach(request::setHeader);

        CloseableHttpResponse response = client.execute(request);
        HttpEntity responseEntity = response.getEntity();

        return Util.readLinesFromInputStream(responseEntity.getContent());