diff --git a/common/src/test/java/org/conscrypt/ct/CTVerifierTest.java b/common/src/test/java/org/conscrypt/ct/CTVerifierTest.java
deleted file mode 100644
index 9aaf8db..0000000
--- a/common/src/test/java/org/conscrypt/ct/CTVerifierTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt.ct;
-
-import static org.conscrypt.TestUtils.openTestFile;
-import static org.conscrypt.TestUtils.readTestFile;
-import static org.junit.Assert.assertEquals;
-
-import java.security.PublicKey;
-import java.util.Arrays;
-import org.conscrypt.OpenSSLX509Certificate;
-import org.conscrypt.TestUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class CTVerifierTest {
-    private OpenSSLX509Certificate ca;
-    private OpenSSLX509Certificate cert;
-    private OpenSSLX509Certificate certEmbedded;
-    private CTVerifier ctVerifier;
-
-    @Before
-    public void setUp() throws Exception {
-        ca = OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("ca-cert.pem"));
-        cert = OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("cert.pem"));
-        certEmbedded = OpenSSLX509Certificate.fromX509PemInputStream(
-                openTestFile("cert-ct-embedded.pem"));
-
-        PublicKey key = TestUtils.readPublicKeyPemFile("ct-server-key-public.pem");
-
-        final CTLogInfo log = new CTLogInfo(key, "Test Log", "foo");
-        CTLogStore store = new CTLogStore() {
-            @Override
-            public CTLogInfo getKnownLog(byte[] logId) {
-                if (Arrays.equals(logId, log.getID())) {
-                    return log;
-                } else {
-                    return null;
-                }
-            }
-        };
-
-        ctVerifier = new CTVerifier(store);
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withOCSPResponse() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        byte[] ocspResponse = readTestFile("ocsp-response.der");
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, null, ocspResponse);
-        assertEquals(1, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withTLSExtension() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list");
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
-        assertEquals(1, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withEmbeddedExtension() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { certEmbedded, ca };
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, null, null);
-        assertEquals(1, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withoutTimestamp() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, null, null);
-        assertEquals(0, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withInvalidSignature() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list-invalid");
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
-        assertEquals(0, result.getValidSCTs().size());
-        assertEquals(1, result.getInvalidSCTs().size());
-        assertEquals(VerifiedSCT.Status.INVALID_SIGNATURE,
-                     result.getInvalidSCTs().get(0).status);
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withUnknownLog() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list-unknown");
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
-        assertEquals(0, result.getValidSCTs().size());
-        assertEquals(1, result.getInvalidSCTs().size());
-        assertEquals(VerifiedSCT.Status.UNKNOWN_LOG,
-                     result.getInvalidSCTs().get(0).status);
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withInvalidEncoding() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        // Just some garbage data which will fail to deserialize
-        byte[] tlsExtension = new byte[] { 1, 2, 3, 4 };
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
-        assertEquals(0, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withInvalidOCSPResponse() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        // Just some garbage data which will fail to deserialize
-        byte[] ocspResponse = new byte[] { 1, 2, 3, 4 };
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, null, ocspResponse);
-        assertEquals(0, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withMultipleTimestamps() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list-invalid");
-        byte[] ocspResponse = readTestFile("ocsp-response.der");
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, ocspResponse);
-        assertEquals(1, result.getValidSCTs().size());
-        assertEquals(1, result.getInvalidSCTs().size());
-        assertEquals(SignedCertificateTimestamp.Origin.OCSP_RESPONSE,
-                     result.getValidSCTs().get(0).sct.getOrigin());
-        assertEquals(SignedCertificateTimestamp.Origin.TLS_EXTENSION,
-                     result.getInvalidSCTs().get(0).sct.getOrigin());
-    }
-}
-
diff --git a/platform/src/test/java/org/conscrypt/ct/CTLogStoreImplTest.java b/platform/src/test/java/org/conscrypt/ct/CTLogStoreImplTest.java
deleted file mode 100644
index f95a3e6..0000000
--- a/platform/src/test/java/org/conscrypt/ct/CTLogStoreImplTest.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt.ct;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import java.io.BufferedWriter;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.security.PublicKey;
-import junit.framework.TestCase;
-import org.conscrypt.InternalUtil;
-
-public class CTLogStoreImplTest extends TestCase {
-    private static final String[] LOG_KEYS = new String[] {
-        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmXg8sUUzwBYaWrRb+V0IopzQ6o3U" +
-        "yEJ04r5ZrRXGdpYM8K+hB0pXrGRLI0eeWz+3skXrS0IO83AhA3GpRL6s6w==",
-
-        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErEULmlBnX9L/+AK20hLYzPMFozYx" +
-        "pP0Wm1ylqGkPEwuDKn9DSpNSOym49SN77BLGuAXu9twOW/qT+ddIYVBEIw==",
-
-        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEP6PGcXmjlyCBz2ZFUuUjrgbZLaEF" +
-        "gfLUkt2cEqlSbb4vTuB6WWmgC9h0L6PN6JF0CPcajpBKGlTI15242a8d4g==",
-
-        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER3qB0NADsP1szXxe4EagrD/ryPVh" +
-        "Y/azWbKyXcK12zhXnO8WH2U4QROVUMctFXLflIzw0EivdRN9t7UH1Od30w==",
-
-        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEY0ww9JqeJvzVtKNTPVb3JZa7s0ZV" +
-        "duH3PpshpMS5XVoPRSjSQCph6f3HjUcM3c4N2hpa8OFbrFFy37ttUrgD+A=="
-    };
-    private static final String[] LOG_FILENAMES = new String[] {
-        "df1c2ec11500945247a96168325ddc5c7959e8f7c6d388fc002e0bbd3f74d764",
-        "84f8ae3f613b13407a75fa2893b93ab03b18d86c455fe7c241ae020033216446",
-        "89baa01a445100009d8f9a238947115b30702275aafee675a7d94b6b09287619",
-        "57456bffe268e49a190dce4318456034c2b4958f3c0201bed5a366737d1e74ca",
-        "896c898ced4b8e6547fa351266caae4ca304f1c1ec2b623c2ee259c5452147b0"
-    };
-
-    private static final CTLogInfo[] LOGS;
-    private static final String[] LOGS_SERIALIZED;
-
-    static {
-        try {
-            int logCount = LOG_KEYS.length;
-            LOGS = new CTLogInfo[logCount];
-            LOGS_SERIALIZED = new String[logCount];
-            for (int i = 0; i < logCount; i++) {
-                PublicKey key = InternalUtil.readPublicKeyPem(new ByteArrayInputStream(
-                    ("-----BEGIN PUBLIC KEY-----\n" +
-                     LOG_KEYS[i] + "\n" +
-                     "-----END PUBLIC KEY-----\n").getBytes(StandardCharsets.US_ASCII)));
-                String description = String.format("Test Log %d", i);
-                String url = String.format("log%d.example.com", i);
-                LOGS[i] = new CTLogInfo(key, description, url);
-                LOGS_SERIALIZED[i] = String.format("description:%s\nurl:%s\nkey:%s",
-                    description, url, LOG_KEYS[i]);
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /* CTLogStoreImpl loads the list of logs lazily when they are first needed
-     * to avoid any overhead when CT is disabled.
-     * This test simply forces the logs to be loaded to make sure it doesn't
-     * fail, as all of the other tests use a different log store.
-     */
-    public void test_getDefaultFallbackLogs() {
-        CTLogInfo[] knownLogs = CTLogStoreImpl.getDefaultFallbackLogs();
-        assertEquals(KnownLogs.LOG_COUNT, knownLogs.length);
-    }
-
-    public void test_loadLog() throws Exception {
-        CTLogInfo log = CTLogStoreImpl.loadLog(
-                new ByteArrayInputStream(LOGS_SERIALIZED[0].getBytes(StandardCharsets.US_ASCII)));
-        assertEquals(LOGS[0], log);
-
-        File testFile = writeFile(LOGS_SERIALIZED[0]);
-        log = CTLogStoreImpl.loadLog(testFile);
-        assertEquals(LOGS[0], log);
-
-        // Empty log file, used to mask fallback logs
-        assertEquals(null, CTLogStoreImpl.loadLog(new ByteArrayInputStream(new byte[0])));
-        try {
-            CTLogStoreImpl.loadLog(new ByteArrayInputStream(
-                    "randomgarbage".getBytes(StandardCharsets.US_ASCII)));
-            fail("InvalidLogFileException not thrown");
-        } catch (CTLogStoreImpl.InvalidLogFileException e) {}
-
-        try {
-            CTLogStoreImpl.loadLog(new File("/nonexistent"));
-            fail("FileNotFoundException not thrown");
-        } catch (FileNotFoundException e) {}
-    }
-
-    public void test_getKnownLog() throws Exception {
-        File userDir = createTempDirectory();
-        userDir.deleteOnExit();
-
-        File systemDir = createTempDirectory();
-        systemDir.deleteOnExit();
-
-        CTLogInfo[] fallback = new CTLogInfo[] { LOGS[2], LOGS[3] };
-
-        CTLogStore store = new CTLogStoreImpl(userDir, systemDir, fallback);
-
-        /* Add logs 0 and 1 to the user and system directories respectively
-         * Log 2 & 3 are part of the fallbacks
-         * But mask log 3 with an empty file in the user directory.
-         * Log 4 is not in the store
-         */
-        File log0File = new File(userDir, LOG_FILENAMES[0]);
-        File log1File = new File(systemDir, LOG_FILENAMES[1]);
-        File log3File = new File(userDir, LOG_FILENAMES[3]);
-        File log4File = new File(userDir, LOG_FILENAMES[4]);
-
-        writeFile(log0File, LOGS_SERIALIZED[0]);
-        writeFile(log1File, LOGS_SERIALIZED[1]);
-        writeFile(log3File, "");
-
-        // Logs 01 are present, log 2 is in the fallback and unused, log 3 is present but masked,
-        // log 4 is missing
-        assertEquals(LOGS[0], store.getKnownLog(LOGS[0].getID()));
-        assertEquals(LOGS[1], store.getKnownLog(LOGS[1].getID()));
-        // Fallback logs are not used if the userDir is present.
-        assertEquals(null, store.getKnownLog(LOGS[2].getID()));
-        assertEquals(null, store.getKnownLog(LOGS[3].getID()));
-        assertEquals(null, store.getKnownLog(LOGS[4].getID()));
-
-        /* Test whether CTLogStoreImpl caches properly
-         * Modify the files on the disk, the result of the store should not change
-         * Delete log 0, mask log 1, add log 4
-         */
-        log0File.delete();
-        writeFile(log1File, "");
-        writeFile(log4File, LOGS_SERIALIZED[4]);
-
-        assertEquals(LOGS[0], store.getKnownLog(LOGS[0].getID()));
-        assertEquals(LOGS[1], store.getKnownLog(LOGS[1].getID()));
-        assertEquals(null, store.getKnownLog(LOGS[4].getID()));
-
-        // Test that fallback logs are used when the userDir doesn't exist.
-        File doesntExist = new File("/doesnt/exist/");
-        store = new CTLogStoreImpl(doesntExist, doesntExist, fallback);
-        assertEquals(LOGS[2], store.getKnownLog(LOGS[2].getID()));
-        assertEquals(LOGS[3], store.getKnownLog(LOGS[3].getID()));
-    }
-
-    /**
-     * Create a temporary file and write to it.
-     * The file will be deleted on exit.
-     * @param contents The data to be written to the file
-     * @return A reference to the temporary file
-     */
-    private File writeFile(String contents) throws IOException {
-        File file = File.createTempFile("test", null);
-        file.deleteOnExit();
-        writeFile(file, contents);
-        return file;
-    }
-
-    private static void writeFile(File file, String contents) throws FileNotFoundException {
-        PrintWriter writer = new PrintWriter(
-                new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UTF_8)),
-                false);
-        try {
-            writer.write(contents);
-        } finally {
-            writer.close();
-        }
-    }
-
-    /*
-     * This is NOT safe, as another process could create a file between delete() and mkdir()
-     * It should be fine for tests though
-     */
-    private static File createTempDirectory() throws IOException {
-        File folder = File.createTempFile("test", "");
-        folder.delete();
-        folder.mkdir();
-        return folder;
-    }
-}
-
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/ct/CTVerifierTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/ct/CTVerifierTest.java
deleted file mode 100644
index d0d4265..0000000
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/ct/CTVerifierTest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.org.conscrypt.ct;
-
-import static com.android.org.conscrypt.TestUtils.openTestFile;
-import static com.android.org.conscrypt.TestUtils.readTestFile;
-import static org.junit.Assert.assertEquals;
-
-import java.security.PublicKey;
-import java.util.Arrays;
-import com.android.org.conscrypt.OpenSSLX509Certificate;
-import com.android.org.conscrypt.TestUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * @hide This class is not part of the Android public SDK API
- */
-@RunWith(JUnit4.class)
-public class CTVerifierTest {
-    private OpenSSLX509Certificate ca;
-    private OpenSSLX509Certificate cert;
-    private OpenSSLX509Certificate certEmbedded;
-    private CTVerifier ctVerifier;
-
-    @Before
-    public void setUp() throws Exception {
-        ca = OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("ca-cert.pem"));
-        cert = OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("cert.pem"));
-        certEmbedded = OpenSSLX509Certificate.fromX509PemInputStream(
-                openTestFile("cert-ct-embedded.pem"));
-
-        PublicKey key = TestUtils.readPublicKeyPemFile("ct-server-key-public.pem");
-
-        final CTLogInfo log = new CTLogInfo(key, "Test Log", "foo");
-        CTLogStore store = new CTLogStore() {
-            @Override
-            public CTLogInfo getKnownLog(byte[] logId) {
-                if (Arrays.equals(logId, log.getID())) {
-                    return log;
-                } else {
-                    return null;
-                }
-            }
-        };
-
-        ctVerifier = new CTVerifier(store);
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withOCSPResponse() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        byte[] ocspResponse = readTestFile("ocsp-response.der");
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, null, ocspResponse);
-        assertEquals(1, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withTLSExtension() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list");
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
-        assertEquals(1, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withEmbeddedExtension() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { certEmbedded, ca };
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, null, null);
-        assertEquals(1, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withoutTimestamp() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, null, null);
-        assertEquals(0, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withInvalidSignature() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list-invalid");
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
-        assertEquals(0, result.getValidSCTs().size());
-        assertEquals(1, result.getInvalidSCTs().size());
-        assertEquals(VerifiedSCT.Status.INVALID_SIGNATURE,
-                     result.getInvalidSCTs().get(0).status);
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withUnknownLog() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list-unknown");
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
-        assertEquals(0, result.getValidSCTs().size());
-        assertEquals(1, result.getInvalidSCTs().size());
-        assertEquals(VerifiedSCT.Status.UNKNOWN_LOG,
-                     result.getInvalidSCTs().get(0).status);
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withInvalidEncoding() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        // Just some garbage data which will fail to deserialize
-        byte[] tlsExtension = new byte[] { 1, 2, 3, 4 };
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
-        assertEquals(0, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withInvalidOCSPResponse() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        // Just some garbage data which will fail to deserialize
-        byte[] ocspResponse = new byte[] { 1, 2, 3, 4 };
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, null, ocspResponse);
-        assertEquals(0, result.getValidSCTs().size());
-        assertEquals(0, result.getInvalidSCTs().size());
-    }
-
-    @Test
-    public void test_verifySignedCertificateTimestamps_withMultipleTimestamps() throws Exception {
-        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
-
-        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list-invalid");
-        byte[] ocspResponse = readTestFile("ocsp-response.der");
-
-        CTVerificationResult result =
-            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, ocspResponse);
-        assertEquals(1, result.getValidSCTs().size());
-        assertEquals(1, result.getInvalidSCTs().size());
-        assertEquals(SignedCertificateTimestamp.Origin.OCSP_RESPONSE,
-                     result.getValidSCTs().get(0).sct.getOrigin());
-        assertEquals(SignedCertificateTimestamp.Origin.TLS_EXTENSION,
-                     result.getInvalidSCTs().get(0).sct.getOrigin());
-    }
-}
-
diff --git a/repackaged/platform/src/test/java/com/android/org/conscrypt/ct/CTLogStoreImplTest.java b/repackaged/platform/src/test/java/com/android/org/conscrypt/ct/CTLogStoreImplTest.java
deleted file mode 100644
index c7e6efa..0000000
--- a/repackaged/platform/src/test/java/com/android/org/conscrypt/ct/CTLogStoreImplTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.org.conscrypt.ct;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import com.android.org.conscrypt.InternalUtil;
-import java.io.BufferedWriter;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.security.PublicKey;
-import junit.framework.TestCase;
-
-/**
- * @hide This class is not part of the Android public SDK API
- */
-public class CTLogStoreImplTest extends TestCase {
-    private static final String[] LOG_KEYS = new String[] {
-        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmXg8sUUzwBYaWrRb+V0IopzQ6o3U" +
-        "yEJ04r5ZrRXGdpYM8K+hB0pXrGRLI0eeWz+3skXrS0IO83AhA3GpRL6s6w==",
-
-        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErEULmlBnX9L/+AK20hLYzPMFozYx" +
-        "pP0Wm1ylqGkPEwuDKn9DSpNSOym49SN77BLGuAXu9twOW/qT+ddIYVBEIw==",
-
-        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEP6PGcXmjlyCBz2ZFUuUjrgbZLaEF" +
-        "gfLUkt2cEqlSbb4vTuB6WWmgC9h0L6PN6JF0CPcajpBKGlTI15242a8d4g==",
-
-        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER3qB0NADsP1szXxe4EagrD/ryPVh" +
-        "Y/azWbKyXcK12zhXnO8WH2U4QROVUMctFXLflIzw0EivdRN9t7UH1Od30w==",
-
-        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEY0ww9JqeJvzVtKNTPVb3JZa7s0ZV" +
-        "duH3PpshpMS5XVoPRSjSQCph6f3HjUcM3c4N2hpa8OFbrFFy37ttUrgD+A=="
-    };
-    private static final String[] LOG_FILENAMES = new String[] {
-        "df1c2ec11500945247a96168325ddc5c7959e8f7c6d388fc002e0bbd3f74d764",
-        "84f8ae3f613b13407a75fa2893b93ab03b18d86c455fe7c241ae020033216446",
-        "89baa01a445100009d8f9a238947115b30702275aafee675a7d94b6b09287619",
-        "57456bffe268e49a190dce4318456034c2b4958f3c0201bed5a366737d1e74ca",
-        "896c898ced4b8e6547fa351266caae4ca304f1c1ec2b623c2ee259c5452147b0"
-    };
-
-    private static final CTLogInfo[] LOGS;
-    private static final String[] LOGS_SERIALIZED;
-
-    static {
-        try {
-            int logCount = LOG_KEYS.length;
-            LOGS = new CTLogInfo[logCount];
-            LOGS_SERIALIZED = new String[logCount];
-            for (int i = 0; i < logCount; i++) {
-                PublicKey key = InternalUtil.readPublicKeyPem(new ByteArrayInputStream(
-                        ("-----BEGIN PUBLIC KEY-----\n" + LOG_KEYS[i] + "\n"
-                                + "-----END PUBLIC KEY-----\n")
-                                .getBytes(StandardCharsets.US_ASCII)));
-                String description = String.format("Test Log %d", i);
-                String url = String.format("log%d.example.com", i);
-                LOGS[i] = new CTLogInfo(key, description, url);
-                LOGS_SERIALIZED[i] = String.format("description:%s\nurl:%s\nkey:%s",
-                    description, url, LOG_KEYS[i]);
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /* CTLogStoreImpl loads the list of logs lazily when they are first needed
-     * to avoid any overhead when CT is disabled.
-     * This test simply forces the logs to be loaded to make sure it doesn't
-     * fail, as all of the other tests use a different log store.
-     */
-    public void test_getDefaultFallbackLogs() {
-        CTLogInfo[] knownLogs = CTLogStoreImpl.getDefaultFallbackLogs();
-        assertEquals(KnownLogs.LOG_COUNT, knownLogs.length);
-    }
-
-    public void test_loadLog() throws Exception {
-        CTLogInfo log = CTLogStoreImpl.loadLog(
-                new ByteArrayInputStream(LOGS_SERIALIZED[0].getBytes(StandardCharsets.US_ASCII)));
-        assertEquals(LOGS[0], log);
-
-        File testFile = writeFile(LOGS_SERIALIZED[0]);
-        log = CTLogStoreImpl.loadLog(testFile);
-        assertEquals(LOGS[0], log);
-
-        // Empty log file, used to mask fallback logs
-        assertEquals(null, CTLogStoreImpl.loadLog(new ByteArrayInputStream(new byte[0])));
-        try {
-            CTLogStoreImpl.loadLog(
-                    new ByteArrayInputStream("randomgarbage".getBytes(StandardCharsets.US_ASCII)));
-            fail("InvalidLogFileException not thrown");
-        } catch (CTLogStoreImpl.InvalidLogFileException e) {}
-
-        try {
-            CTLogStoreImpl.loadLog(new File("/nonexistent"));
-            fail("FileNotFoundException not thrown");
-        } catch (FileNotFoundException e) {}
-    }
-
-    public void test_getKnownLog() throws Exception {
-        File userDir = createTempDirectory();
-        userDir.deleteOnExit();
-
-        File systemDir = createTempDirectory();
-        systemDir.deleteOnExit();
-
-        CTLogInfo[] fallback = new CTLogInfo[] { LOGS[2], LOGS[3] };
-
-        CTLogStore store = new CTLogStoreImpl(userDir, systemDir, fallback);
-
-        /* Add logs 0 and 1 to the user and system directories respectively
-         * Log 2 & 3 are part of the fallbacks
-         * But mask log 3 with an empty file in the user directory.
-         * Log 4 is not in the store
-         */
-        File log0File = new File(userDir, LOG_FILENAMES[0]);
-        File log1File = new File(systemDir, LOG_FILENAMES[1]);
-        File log3File = new File(userDir, LOG_FILENAMES[3]);
-        File log4File = new File(userDir, LOG_FILENAMES[4]);
-
-        writeFile(log0File, LOGS_SERIALIZED[0]);
-        writeFile(log1File, LOGS_SERIALIZED[1]);
-        writeFile(log3File, "");
-
-        // Logs 01 are present, log 2 is in the fallback and unused, log 3 is present but masked,
-        // log 4 is missing
-        assertEquals(LOGS[0], store.getKnownLog(LOGS[0].getID()));
-        assertEquals(LOGS[1], store.getKnownLog(LOGS[1].getID()));
-        // Fallback logs are not used if the userDir is present.
-        assertEquals(null, store.getKnownLog(LOGS[2].getID()));
-        assertEquals(null, store.getKnownLog(LOGS[3].getID()));
-        assertEquals(null, store.getKnownLog(LOGS[4].getID()));
-
-        /* Test whether CTLogStoreImpl caches properly
-         * Modify the files on the disk, the result of the store should not change
-         * Delete log 0, mask log 1, add log 4
-         */
-        log0File.delete();
-        writeFile(log1File, "");
-        writeFile(log4File, LOGS_SERIALIZED[4]);
-
-        assertEquals(LOGS[0], store.getKnownLog(LOGS[0].getID()));
-        assertEquals(LOGS[1], store.getKnownLog(LOGS[1].getID()));
-        assertEquals(null, store.getKnownLog(LOGS[4].getID()));
-
-        // Test that fallback logs are used when the userDir doesn't exist.
-        File doesntExist = new File("/doesnt/exist/");
-        store = new CTLogStoreImpl(doesntExist, doesntExist, fallback);
-        assertEquals(LOGS[2], store.getKnownLog(LOGS[2].getID()));
-        assertEquals(LOGS[3], store.getKnownLog(LOGS[3].getID()));
-    }
-
-    /**
-     * Create a temporary file and write to it.
-     * The file will be deleted on exit.
-     * @param contents The data to be written to the file
-     * @return A reference to the temporary file
-     */
-    private File writeFile(String contents) throws IOException {
-        File file = File.createTempFile("test", null);
-        file.deleteOnExit();
-        writeFile(file, contents);
-        return file;
-    }
-
-    private static void writeFile(File file, String contents) throws FileNotFoundException {
-        PrintWriter writer = new PrintWriter(
-                new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UTF_8)),
-                false);
-        try {
-            writer.write(contents);
-        } finally {
-            writer.close();
-        }
-    }
-
-    /*
-     * This is NOT safe, as another process could create a file between delete() and mkdir()
-     * It should be fine for tests though
-     */
-    private static File createTempDirectory() throws IOException {
-        File folder = File.createTempFile("test", "");
-        folder.delete();
-        folder.mkdir();
-        return folder;
-    }
-}
-
