// Path: src/main/java/com/amplitude/util/DoubleCheck.java
// public class DoubleCheck<T> implements Provider<T> {
//     private static final Object UNINITIALIZED = new Object();
// 
//     private volatile Provider<T> provider;
//     private volatile Object instance = UNINITIALIZED;
// 
//     private DoubleCheck(Provider<T> provider) {
//         assert provider != null;
//         this.provider = provider;
//     }
// 
//     @SuppressWarnings("unchecked") // cast only happens when result comes from the provider
//     @Override
//     public T get() {
//         Object result = instance;
//         if (result == UNINITIALIZED) {
//             synchronized (this) {
//                 result = instance;
//                 if (result == UNINITIALIZED) {
//                     result = provider.get();
//                     instance = reentrantCheck(instance, result);
//                     /* Null out the reference to the provider. We are never going to need it again, so we
//                      * can make it eligible for GC. */
//                     provider = null;
//                 }
//             }
//         }
//         return (T) result;
//     }
// 
//     /**
//      * Checks to see if creating the new instance has resulted in a recursive call. If it has, and the
//      * new instance is the same as the current instance, return the instance. However, if the new
//      * instance differs from the current instance, an {@link IllegalStateException} is thrown.
//      */
//     public static Object reentrantCheck(Object currentInstance, Object newInstance) {
//         boolean isReentrant = !(currentInstance == UNINITIALIZED);
// 
//         if (isReentrant && currentInstance != newInstance) {
//             throw new IllegalStateException("Scoped provider was invoked recursively returning "
//                     + "different results: " + currentInstance + " & " + newInstance + ". This is likely "
//                     + "due to a circular dependency.");
//         }
//         return newInstance;
//     }
// 
//     /** Returns a {@link Provider} that caches the value from the given delegate provider. */
//     public static <P extends Provider<T>, T> Provider<T> provider(P delegate) {
//         if (delegate == null) {
//             throw new IllegalArgumentException("delegate cannot be null");
//         }
//         if (delegate instanceof DoubleCheck) {
//             /* This should be a rare case, but if we have a scoped @Binds that delegates to a scoped
//              * binding, we shouldn't cache the value again. */
//             return delegate;
//         }
//         return new DoubleCheck<T>(delegate);
//     }
// }
// 
// Path: src/main/java/com/amplitude/util/Provider.java
// public interface Provider<T> {
//     T get();
// }


import android.content.Context;
import com.amplitude.util.DoubleCheck;
import com.amplitude.util.Provider;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
import okio.Buffer;
import okio.ByteString;
                    SSLSocketFactory factory = getPinnedCertSslSocketFactory();
                    if (factory != null) {
                        try {
                            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                                    TrustManagerFactory.getDefaultAlgorithm());
                            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                            keyStore.load(null, null); // Use a null input stream + password to create an empty key store.

                            List<String> certificateBase64s = new ArrayList<String>();
                            certificateBase64s.add(CERTIFICATE_1);

                            // Decode the certificates and add 'em to the key store.
                            int nextName = 1;
                            for (String certificateBase64 : certificateBase64s) {
                                Buffer certificateBuffer = new Buffer().write(ByteString.decodeBase64(certificateBase64));
                                X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(
                                        certificateBuffer.inputStream());
                                keyStore.setCertificateEntry(Integer.toString(nextName++), certificate);
                            }

                            // Create an SSL context that uses these certificates as its trust store.
                            trustManagerFactory.init(keyStore);

                            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
                            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
                                throw new IllegalStateException("Unexpected default trust managers:"
                                        + Arrays.toString(trustManagers));
                            }
                            X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
// Path: src/main/java/com/amplitude/util/DoubleCheck.java
// public class DoubleCheck<T> implements Provider<T> {
//     private static final Object UNINITIALIZED = new Object();
// 
//     private volatile Provider<T> provider;
//     private volatile Object instance = UNINITIALIZED;
// 
//     private DoubleCheck(Provider<T> provider) {
//         assert provider != null;
//         this.provider = provider;
//     }
// 
//     @SuppressWarnings("unchecked") // cast only happens when result comes from the provider
//     @Override
//     public T get() {
//         Object result = instance;
//         if (result == UNINITIALIZED) {
//             synchronized (this) {
//                 result = instance;
//                 if (result == UNINITIALIZED) {
//                     result = provider.get();
//                     instance = reentrantCheck(instance, result);
//                     /* Null out the reference to the provider. We are never going to need it again, so we
//                      * can make it eligible for GC. */
//                     provider = null;
//                 }
//             }
//         }
//         return (T) result;
//     }
// 
//     /**
//      * Checks to see if creating the new instance has resulted in a recursive call. If it has, and the
//      * new instance is the same as the current instance, return the instance. However, if the new
//      * instance differs from the current instance, an {@link IllegalStateException} is thrown.
//      */
//     public static Object reentrantCheck(Object currentInstance, Object newInstance) {
//         boolean isReentrant = !(currentInstance == UNINITIALIZED);
// 
//         if (isReentrant && currentInstance != newInstance) {
//             throw new IllegalStateException("Scoped provider was invoked recursively returning "
//                     + "different results: " + currentInstance + " & " + newInstance + ". This is likely "
//                     + "due to a circular dependency.");
//         }
//         return newInstance;
//     }
// 
//     /** Returns a {@link Provider} that caches the value from the given delegate provider. */
//     public static <P extends Provider<T>, T> Provider<T> provider(P delegate) {
//         if (delegate == null) {
//             throw new IllegalArgumentException("delegate cannot be null");
//         }
//         if (delegate instanceof DoubleCheck) {
//             /* This should be a rare case, but if we have a scoped @Binds that delegates to a scoped
//              * binding, we shouldn't cache the value again. */
//             return delegate;
//         }
//         return new DoubleCheck<T>(delegate);
//     }
// }
// 
// Path: src/main/java/com/amplitude/util/Provider.java
// public interface Provider<T> {
//     T get();
// }


// Path: src/main/java/com/amplitude/api/PinnedAmplitudeClient.java
import android.content.Context;
import com.amplitude.util.DoubleCheck;
import com.amplitude.util.Provider;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
import okio.Buffer;
import okio.ByteString;

                    SSLSocketFactory factory = getPinnedCertSslSocketFactory();
                    if (factory != null) {
                        try {
                            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                                    TrustManagerFactory.getDefaultAlgorithm());
                            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                            keyStore.load(null, null); // Use a null input stream + password to create an empty key store.

                            List<String> certificateBase64s = new ArrayList<String>();
                            certificateBase64s.add(CERTIFICATE_1);

                            // Decode the certificates and add 'em to the key store.
                            int nextName = 1;
                            for (String certificateBase64 : certificateBase64s) {
                                Buffer certificateBuffer = new Buffer().write(ByteString.decodeBase64(certificateBase64));
                                X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(
                                        certificateBuffer.inputStream());
                                keyStore.setCertificateEntry(Integer.toString(nextName++), certificate);
                            }

                            // Create an SSL context that uses these certificates as its trust store.
                            trustManagerFactory.init(keyStore);

                            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
                            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
                                throw new IllegalStateException("Unexpected default trust managers:"
                                        + Arrays.toString(trustManagers));
                            }
                            X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
                            final Provider<OkHttpClient> finalClientProvider = DoubleCheck.provider(() -> {