[DO NOT MERGE] Fix Conscrypt CTS for sc-v2-dev.

Background: Cherry-picks ag/15934029 and ag/15934004 were not
included in the release Mainline module for sc-v2.  They contain
one required bugfix b/191150645 for Android Auto (which does
not use Mainline) and some unrelated bug fixes which were in
the same upstream merge.  The end result is that sc-v2 CTS
would fail with a prebuilt Mainline Conscrypt module installed.
See b/209335673 for further details.

This change reverts all of ag/15934029 and ag/15934004 except
for the parts relating to b/191150645 and modifies the tests so
they will run with our without the Mainline module installed.
This involves skipping some additional tests added for
b/191150645 but still includes the main tests, i.e. that all
Providers' key factories inter-operate correctly.

Bug: 209335673
Bug: 191150645
Test: atest CtsLibcoreTestCases with and without the module installed.
Change-Id: Ic3a137bbc18429927354cc4094124fa5271d97a9
Merged-In: Ic3a137bbc18429927354cc4094124fa5271d97a9
diff --git a/Android.bp b/Android.bp
index af9e01e..ff3a903 100644
--- a/Android.bp
+++ b/Android.bp
@@ -525,7 +525,7 @@
         ":conscrypt-unbundled_generated_constants",
     ],
     javacflags: ["-XDignore.symbol.file"],
-    java_version: "1.8",
+    java_version: "1.7",
 }
 
 // Static unbundled Conscrypt crypto JNI library
@@ -599,7 +599,7 @@
             enabled: false,
         },
     },
-    java_version: "1.8",
+    java_version: "1.7",
 }
 
 // Make the conscrypt-benchmarks library.
@@ -636,7 +636,7 @@
             enabled: false,
         },
     },
-    java_version: "1.8",
+    java_version: "1.7",
 }
 
 // Device SDK exposed by the Conscrypt module.
diff --git a/android-stub/build.gradle b/android-stub/build.gradle
index 874f599..f1a911f 100644
--- a/android-stub/build.gradle
+++ b/android-stub/build.gradle
@@ -1,5 +1,9 @@
 description = 'Conscrypt: Android-Stub'
 
+// Needs to be binary-compatible with Android minSdkVersion.
+sourceCompatibility = androidMinJavaVersion
+targetCompatibility = androidMinJavaVersion
+
 dependencies {
     compileOnly project(':conscrypt-libcore-stub')
 }
diff --git a/build.gradle b/build.gradle
index 08b9ebd..162c491 100644
--- a/build.gradle
+++ b/build.gradle
@@ -165,8 +165,8 @@
     }
 
     if (!androidProject) {
-        sourceCompatibility = JavaVersion.VERSION_1_8
-        targetCompatibility = JavaVersion.VERSION_1_8
+        sourceCompatibility = JavaVersion.VERSION_1_7
+        targetCompatibility = JavaVersion.VERSION_1_7
 
         [tasks.named("compileJava"), tasks.named("compileTestJava")].forEach { t ->
             t.configure {
diff --git a/common/src/jni/main/cpp/conscrypt/native_crypto.cc b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
index 98d7dbc..5b0acf0 100644
--- a/common/src/jni/main/cpp/conscrypt/native_crypto.cc
+++ b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
@@ -2204,9 +2204,7 @@
     const EC_GROUP* group = fromContextObject<EC_GROUP>(env, groupRef);
     JNI_TRACE("EC_KEY_marshal_curve_name(%p)", group);
     if (group == nullptr) {
-        env->ExceptionClear();
         conscrypt::jniutil::throwIOException(env, "Invalid group pointer");
-        JNI_TRACE("group=%p EC_KEY_marshal_curve_name => Invalid group pointer", group);
         return nullptr;
     }
 
@@ -2233,9 +2231,8 @@
 
     ScopedByteArrayRO bytes(env, curveNameBytes);
     if (bytes.get() == nullptr) {
-        env->ExceptionClear();
-        conscrypt::jniutil::throwIOException(env, "Null EC curve name");
-        JNI_TRACE("bytes=%p EC_KEY_parse_curve_name => curveNameBytes == null ", curveNameBytes);
+        conscrypt::jniutil::throwIOException(env, "Error reading ASN.1 encoding");
+        JNI_TRACE("bytes=%p EC_KEY_parse_curve_name => threw exception", curveNameBytes);
         return 0;
     }
 
@@ -3211,12 +3208,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     JNI_TRACE("EVP_get_cipherbyname(%p)", algorithm);
 
-    if (algorithm == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "algorithm == null");
-        JNI_TRACE("EVP_get_cipherbyname(%p) => algorithm == null", algorithm);
-        return -1;
-    }
-
     ScopedUtfChars scoped_alg(env, algorithm);
     const char* alg = scoped_alg.c_str();
     const EVP_CIPHER* cipher;
@@ -3254,7 +3245,7 @@
     } else if (strcasecmp(alg, "aes-256-gcm") == 0) {
         cipher = EVP_aes_256_gcm();
     } else {
-        JNI_TRACE("NativeCrypto_EVP_get_cipherbyname(%s) => error", alg);
+        JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s) => error", alg);
         return 0;
     }
 
@@ -4387,12 +4378,6 @@
     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
     JNI_TRACE("X509_get_version(%p)", x509);
 
-    if (x509 == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
-        JNI_TRACE("X509_get_version(%p) => x509 == null", x509);
-        return 0;
-    }
-
     // NOLINTNEXTLINE(runtime/int)
     long version = X509_get_version(x509);
     JNI_TRACE("X509_get_version(%p) => %ld", x509, version);
@@ -4432,12 +4417,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
     JNI_TRACE("X509_get_serialNumber(%p)", x509);
-
-    if (x509 == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
-        JNI_TRACE("X509_get_serialNumber(%p) => x509 == null", x509);
-        return nullptr;
-    }
     return get_X509Type_serialNumber<X509>(env, x509, X509_get0_serialNumber);
 }
 
@@ -4446,12 +4425,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
     JNI_TRACE("X509_REVOKED_get_serialNumber(%p)", revoked);
-
-    if (revoked == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "revoked == null");
-        JNI_TRACE("X509_REVOKED_get_serialNumber(%p) => revoked == null", revoked);
-        return 0;
-    }
     return get_X509Type_serialNumber<X509_REVOKED>(env, revoked, X509_REVOKED_get0_serialNumber);
 }
 
@@ -4573,16 +4546,6 @@
     X509* x509_2 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref2));
     JNI_TRACE("X509_check_issued(%p, %p)", x509_1, x509_2);
 
-    if (x509_1 == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "x509Ref1 == null");
-        JNI_TRACE("X509_check_issued(%p, %p) => x509_1 == null", x509_1, x509_2);
-        return 0;
-    }
-    if (x509_2 == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "x509Ref2 == null");
-        JNI_TRACE("X509_check_issued(%p, %p) => x509_2 == null", x509_1, x509_2);
-        return 0;
-    }
     int ret = X509_check_issued(x509_1, x509_2);
     JNI_TRACE("X509_check_issued(%p, %p) => %d", x509_1, x509_2, ret);
     return ret;
@@ -4638,12 +4601,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
     JNI_TRACE("get_X509_signature(%p)", x509);
-
-    if (x509 == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
-        JNI_TRACE("get_X509_signature(%p) => x509 == null", x509);
-        return nullptr;
-    }
     return get_X509Type_signature<X509>(env, x509, get_X509_signature);
 }
 
@@ -4652,12 +4609,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
     JNI_TRACE("get_X509_CRL_signature(%p)", crl);
-
-    if (crl == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "crl == null");
-        JNI_TRACE("X509_CRL_signature(%p) => crl == null", crl);
-        return nullptr;
-    }
     return get_X509Type_signature<X509_CRL>(env, crl, get_X509_CRL_signature);
 }
 
@@ -4743,7 +4694,6 @@
 
     if (crl == nullptr) {
         conscrypt::jniutil::throwNullPointerException(env, "crl == null");
-        JNI_TRACE("X509_CRL_get_REVOKED(%p) => crl == null", crl);
         return nullptr;
     }
 
@@ -4771,12 +4721,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
     JNI_TRACE("i2d_X509_CRL(%p)", crl);
-
-    if (crl == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "crl == null");
-        JNI_TRACE("i2d_X509_CRL(%p) => crl == null", crl);
-        return nullptr;
-    }
     return ASN1ToByteArray<X509_CRL>(env, crl, i2d_X509_CRL);
 }
 
@@ -4883,12 +4827,6 @@
                                                         CONSCRYPT_UNUSED jobject holder) {
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
-
-    if (crl == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "crl == null");
-        JNI_TRACE("X509_CRL_get_issuer_name(%p) => crl == null", crl);
-        return nullptr;
-    }
     JNI_TRACE("X509_CRL_get_issuer_name(%p)", crl);
     return ASN1ToByteArray<X509_NAME>(env, X509_CRL_get_issuer(crl), i2d_X509_NAME);
 }
@@ -4900,11 +4838,6 @@
     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
     JNI_TRACE("X509_CRL_get_version(%p)", crl);
 
-    if (crl == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "crl == null");
-        JNI_TRACE("X509_CRL_get_version(%p) => crl == null", crl);
-        return 0;
-    }
     // NOLINTNEXTLINE(runtime/int)
     long version = X509_CRL_get_version(crl);
     JNI_TRACE("X509_CRL_get_version(%p) => %ld", crl, version);
@@ -4965,12 +4898,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
     JNI_TRACE("X509_CRL_get_ext(%p, %p)", crl, oid);
-
-    if (crl == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "crl == null");
-        JNI_TRACE("X509_CRL_get_ext(%p) => crl == null", crl);
-        return 0;
-    }
     X509_EXTENSION* ext =
             X509Type_get_ext<X509_CRL, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext>(env, crl, oid);
     JNI_TRACE("X509_CRL_get_ext(%p, %p) => %p", crl, oid, ext);
@@ -5064,12 +4991,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
     JNI_TRACE("get_X509_CRL_crl_enc(%p)", crl);
-
-    if (crl == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "crl == null");
-        JNI_TRACE("get_X509_CRL_crl_enc(%p) => crl == null", crl);
-        return nullptr;
-    }
     return ASN1ToByteArray<X509_CRL>(env, crl, i2d_X509_CRL_tbs);
 }
 
@@ -5607,12 +5528,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
     JNI_TRACE("i2d_X509(%p)", x509);
-
-    if (x509 == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
-        JNI_TRACE("i2d_X509(%p) => x509 == null", x509);
-        return nullptr;
-    }
     return ASN1ToByteArray<X509>(env, x509, i2d_X509);
 }
 
@@ -5621,12 +5536,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
     JNI_TRACE("i2d_X509_PUBKEY(%p)", x509);
-
-    if (x509 == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
-        JNI_TRACE("i2d_X509_PUBKEY(%p) => x509 == null", x509);
-        return nullptr;
-    }
     return ASN1ToByteArray<X509_PUBKEY>(env, X509_get_X509_PUBKEY(x509), i2d_X509_PUBKEY);
 }
 
@@ -6040,12 +5949,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
     JNI_TRACE("X509_get_issuer_name(%p)", x509);
-
-    if (x509 == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
-        JNI_TRACE("X509_get_issuer_name(%p) => x509 == null", x509);
-        return nullptr;
-    }
     return ASN1ToByteArray<X509_NAME>(env, X509_get_issuer_name(x509), i2d_X509_NAME);
 }
 
@@ -6054,12 +5957,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
     JNI_TRACE("X509_get_subject_name(%p)", x509);
-
-    if (x509 == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
-        JNI_TRACE("X509_get_subject_name(%p) => x509 == null", x509);
-        return nullptr;
-    }
     return ASN1ToByteArray<X509_NAME>(env, X509_get_subject_name(x509), i2d_X509_NAME);
 }
 
@@ -6302,12 +6199,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
     JNI_TRACE("X509_CRL_get_ext_oid(%p, %p)", crl, oidString);
-
-    if (crl == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "crl == null");
-        JNI_TRACE("X509_CRL_get_ext_oid(%p) => crl == null", crl);
-        return nullptr;
-    }
     return X509Type_get_ext_oid<X509_CRL, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext>(env, crl,
                                                                                      oidString);
 }
@@ -6317,12 +6208,6 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
     JNI_TRACE("X509_REVOKED_get_ext_oid(%p, %p)", revoked, oidString);
-
-    if (revoked == nullptr) {
-        conscrypt::jniutil::throwNullPointerException(env, "revoked == null");
-        JNI_TRACE("X509_REVOKED_get_ext_oid(%p) => revoked == null", revoked);
-        return nullptr;
-    }
     return X509Type_get_ext_oid<X509_REVOKED, X509_REVOKED_get_ext_by_OBJ, X509_REVOKED_get_ext>(
             env, revoked, oidString);
 }
@@ -7260,7 +7145,8 @@
 }
 
 static void NativeCrypto_SSL_enable_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address,
-                                                   CONSCRYPT_UNUSED jobject ssl_holder) {
+                                                   CONSCRYPT_UNUSED CONSCRYPT_UNUSED jobject
+                                                           ssl_holder) {
     CHECK_ERROR_QUEUE_ON_RETURN;
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_enable_tls_channel_id", ssl);
diff --git a/common/src/test/java/org/conscrypt/ConscryptSuite.java b/common/src/test/java/org/conscrypt/ConscryptSuite.java
index cce41d5..263afcd 100644
--- a/common/src/test/java/org/conscrypt/ConscryptSuite.java
+++ b/common/src/test/java/org/conscrypt/ConscryptSuite.java
@@ -35,7 +35,6 @@
 import org.conscrypt.java.security.KeyFactoryTestDSA;
 import org.conscrypt.java.security.KeyFactoryTestEC;
 import org.conscrypt.java.security.KeyFactoryTestRSA;
-import org.conscrypt.java.security.KeyFactoryTestRSACrt;
 import org.conscrypt.java.security.KeyPairGeneratorTest;
 import org.conscrypt.java.security.KeyPairGeneratorTestDH;
 import org.conscrypt.java.security.KeyPairGeneratorTestDSA;
@@ -81,9 +80,8 @@
         // org.conscrypt tests
         CertPinManagerTest.class,
         ChainStrengthAnalyzerTest.class,
-        HostnameVerifierTest.class,
-        NativeCryptoArgTest.class,
         TrustManagerImplTest.class,
+        HostnameVerifierTest.class,
         // org.conscrypt.ct tests
         CTVerifierTest.class,
         SerializationTest.class,
@@ -108,7 +106,6 @@
         KeyFactoryTestDSA.class,
         KeyFactoryTestEC.class,
         KeyFactoryTestRSA.class,
-        KeyFactoryTestRSACrt.class,
         KeyPairGeneratorTest.class,
         KeyPairGeneratorTestDH.class,
         KeyPairGeneratorTestDSA.class,
diff --git a/common/src/test/java/org/conscrypt/NativeCryptoArgTest.java b/common/src/test/java/org/conscrypt/NativeCryptoArgTest.java
deleted file mode 100644
index 76e8beb..0000000
--- a/common/src/test/java/org/conscrypt/NativeCryptoArgTest.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2020 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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.junit.AfterClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class NativeCryptoArgTest {
-    // Null value passed in for a long which represents a native address
-    private static final long NULL = 0L;
-    /*
-     * Non-null value passed in for a long which represents a native address. Shouldn't
-     * ever get de-referenced but we make it a multiple of 4 to avoid any alignment errors.
-     * Used in the case where there are multiple checks we want to test in a native method,
-     * so we can get past the first check and test the second one.
-     */
-    private static final long NOT_NULL = 4L;
-    private static final String CONSCRYPT_PACKAGE = NativeCryptoArgTest.class.getCanonicalName()
-            .substring(0, NativeCryptoArgTest.class.getCanonicalName().lastIndexOf('.') + 1);
-    private static final Set<String> testedMethods = new HashSet<>();
-    private final Map<String, Class<?>> classCache = new HashMap<>();
-    private final Map<String, Method> methodMap = buildMethodMap();
-
-    @AfterClass
-    public static void after() {
-        // TODO(prb): Temporary hacky check - remove
-        assertTrue(testedMethods.size() >= 190);
-    }
-
-    @Test
-    public void ecMethods() throws Throwable {
-        String[] illegalArgMethods = new String[] {
-                "EC_GROUP_new_arbitrary"
-        };
-        String[] ioExMethods = new String[] {
-                "EC_KEY_parse_curve_name",
-                "EC_KEY_marshal_curve_name"
-        };
-
-        // All of the EC_* methods apart from the exceptions below throw NPE if their
-        // first argument is null.
-        MethodFilter filter = MethodFilter.newBuilder("EC_ methods")
-                .hasPrefix("EC_")
-                .except(illegalArgMethods)
-                .except(ioExMethods)
-                .expectSize(16)
-                .build();
-        testMethods(filter, NullPointerException.class);
-
-        filter = MethodFilter.nameFilter("EC_ methods (IllegalArgument)", illegalArgMethods);
-        testMethods(filter, IllegalArgumentException.class);
-
-        filter = MethodFilter.nameFilter("EC_ methods (IOException)", ioExMethods);
-        testMethods(filter, IOException.class);
-    }
-
-    @Test
-    public void macMethods() throws Throwable {
-        // All of the non-void HMAC and CMAC methods throw NPE when passed a null pointer
-        MethodFilter filter = MethodFilter.newBuilder("HMAC methods")
-                .hasPrefix("HMAC_")
-                .takesArguments()
-                .expectSize(5)
-                .build();
-        testMethods(filter, NullPointerException.class);
-
-        filter = MethodFilter.newBuilder("CMAC methods")
-                .hasPrefix("CMAC_")
-                .takesArguments()
-                .expectSize(5)
-                .build();
-        testMethods(filter, NullPointerException.class);
-    }
-
-    @Test
-    public void sslMethods() throws Throwable {
-        // These methods don't throw on a null first arg as they can get called before the
-        // connection is fully initialised. However if the first arg is non-NULL, any subsequent
-        // null args should throw NPE.
-        String[] nonThrowingMethods = new String[] {
-                "SSL_interrupt",
-                "SSL_shutdown",
-                "ENGINE_SSL_shutdown",
-        };
-
-        // Most of the NativeSsl methods take a long holding a pointer to the native
-        // object followed by a {@code NativeSsl} holder object. However the second arg
-        // is unused(!) so we don't need to test it.
-        MethodFilter filter = MethodFilter.newBuilder("NativeSsl methods")
-                .hasArg(0, long.class)
-                .hasArg(1, conscryptClass("NativeSsl"))
-                .except(nonThrowingMethods)
-                .expectSize(60)
-                .build();
-
-        testMethods(filter, NullPointerException.class);
-
-        // Many of the SSL_* methods take a single long which points
-        // to a native object.
-        filter = MethodFilter.newBuilder("1-arg SSL methods")
-                .hasPrefix("SSL_")
-                .hasArgLength(1)
-                .hasArg(0, long.class)
-                .expectSize(10)
-                .build();
-
-        testMethods(filter, NullPointerException.class);
-
-        filter = MethodFilter.nameFilter("Non throwing NativeSsl methods", nonThrowingMethods);
-        testMethods(filter, null);
-
-        expectVoid("SSL_shutdown", NOT_NULL, null, null, null);
-        expectNPE("SSL_shutdown", NOT_NULL, null, new FileDescriptor(), null);
-        expectNPE("ENGINE_SSL_shutdown", NOT_NULL, null, null);
-        expectVoid("SSL_set_session", NOT_NULL, null, NULL);
-    }
-
-    @Test
-    public void evpMethods() throws Throwable {
-        String[] illegalArgMethods = new String[] {
-                "EVP_AEAD_CTX_open_buf",
-                "EVP_AEAD_CTX_seal_buf",
-                "EVP_PKEY_new_RSA"
-        };
-        String[] nonThrowingMethods = new String[] {
-                "EVP_MD_CTX_destroy",
-                "EVP_PKEY_CTX_free",
-                "EVP_PKEY_free",
-                "EVP_CIPHER_CTX_free"
-        };
-
-        // All of the non-void EVP_ methods apart from the above should throw on a null
-        // first argument.
-        MethodFilter filter = MethodFilter.newBuilder("EVP methods")
-                .hasPrefix("EVP_")
-                .takesArguments()
-                .except(illegalArgMethods)
-                .except(nonThrowingMethods)
-                .expectSize(45)
-                .build();
-
-        testMethods(filter, NullPointerException.class);
-
-        filter = MethodFilter.nameFilter("EVP methods (IllegalArgument)", illegalArgMethods);
-        testMethods(filter, IllegalArgumentException.class);
-
-        filter = MethodFilter.nameFilter("EVP methods (non-throwing)", nonThrowingMethods);
-        testMethods(filter, null);
-    }
-
-    @Test
-    public void x509Methods() throws Throwable {
-        // A number of X509 methods have a native pointer as arg 0 and an
-        // OpenSSLX509Certificate or OpenSSLX509CRL as arg 1.
-        MethodFilter filter = MethodFilter.newBuilder("X509 methods")
-                .hasArgLength(2)
-                .hasArg(0, long.class)
-                .hasArg(1, conscryptClass("OpenSSLX509Certificate"),
-                        conscryptClass("OpenSSLX509CRL"))
-                .expectSize(32)
-                .build();
-        // TODO(prb): test null second argument
-        testMethods(filter, NullPointerException.class);
-
-        // The rest of the X509 methods are somewhat ad hoc.
-        expectNPE("d2i_X509", (Object) null);
-
-        invokeAndExpect( conscryptThrowable("OpenSSLX509CertificateFactory$ParsingException"),
-                 "d2i_X509", new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0});
-
-        expectNPE("d2i_X509_bio", NULL);
-        expectNPE("PEM_read_bio_X509", NULL);
-        expectNPE("ASN1_seq_pack_X509", (Object) null);
-
-        // TODO(prb): Check what this should really throw
-        // expectNPE("ASN1_seq_pack_X509", (Object) new long[] { NULL });
-
-        expectNPE("ASN1_seq_unpack_X509_bio", NULL);
-
-        //
-        expectNPE("X509_cmp", NULL, null, NULL, null);
-        expectNPE("X509_cmp", NOT_NULL, null, NULL, null);
-        expectNPE("X509_cmp", NULL, null, NOT_NULL, null);
-
-        expectNPE("X509_print_ex", NULL, NULL, null, NULL, NULL);
-        expectNPE("X509_print_ex", NOT_NULL, NULL, null, NULL, NULL);
-        expectNPE("X509_print_ex", NULL, NOT_NULL, null, NULL, NULL);
-    }
-
-    private void testMethods(MethodFilter filter, Class<? extends Throwable> exceptionClass)
-            throws Throwable {
-        List<Method> methods = filter.filter(methodMap.values());
-
-        for (Method method : methods) {
-            List<Object[]> argsLists = permuteArgs(method);
-            for (Object[] args : argsLists) {
-                invokeAndExpect(exceptionClass, method, args);
-            }
-        }
-    }
-
-    private List<Object[]> permuteArgs(Method method) {
-        // For now just supply 0 for integral types and null for everything else
-        // TODO: allow user defined strategy, e.g. if two longs passed as native refs,
-        // generate {NULL,NULL}, {NULL,NOT_NULL}, {NOT_NULL,NULL} to test both null checks
-        List<Object[]> result = new ArrayList<>(1);
-
-        Class<?>[] argTypes = method.getParameterTypes();
-
-        int argCount = argTypes.length;
-        assertTrue(argCount > 0);
-        Object[] args = new Object[argCount];
-
-        for (int arg = 0; arg < argCount; arg++) {
-            if (argTypes[arg] == int.class) {
-                args[arg] = 0;
-            } else if (argTypes[arg] == long.class) {
-                args[arg] = NULL;
-            } else if (argTypes[arg] == boolean.class) {
-                args[arg] = false;
-            } else {
-                args[arg] = null;
-            }
-        }
-        result.add(args);
-        return result;
-    }
-
-    private void expectVoid(String methodName, Object... args) throws Throwable {
-        invokeAndExpect(null, methodName, args);
-    }
-
-    private void expectNPE(String methodName, Object... args) throws Throwable {
-        invokeAndExpect(NullPointerException.class, methodName, args);
-    }
-
-    private void invokeAndExpect(Class<? extends Throwable> expectedThrowable, String methodName,
-                                   Object... args) throws Throwable {
-        Method method = methodMap.get(methodName);
-        assertNotNull(method);
-        assertEquals(methodName, method.getName());
-        invokeAndExpect(expectedThrowable, method, args);
-    }
-
-    private void invokeAndExpect(Class<? extends Throwable> expectedThrowable, Method method,
-                                   Object... args) throws Throwable {
-        try {
-            method.invoke(null, args);
-            if (expectedThrowable != null) {
-                fail("No exception thrown by method " + method.getName());
-            }
-        } catch (IllegalAccessException e) {
-            throw new AssertionError("Illegal access", e);
-        } catch (InvocationTargetException e) {
-            Throwable cause = e.getCause();
-            if (expectedThrowable != null) {
-                assertEquals("Method: " + method.getName(), expectedThrowable, cause.getClass());
-            } else {
-                throw cause;
-            }
-        }
-        testedMethods.add(method.getName());
-    }
-
-    @SuppressWarnings("unchecked")
-    private Class<? extends Throwable> conscryptThrowable(String name) {
-        Class<?> klass = conscryptClass(name);
-        assertNotNull(klass);
-        assertTrue(Throwable.class.isAssignableFrom(klass));
-        return (Class<? extends Throwable>) klass;
-    }
-
-    private Class<?> conscryptClass(String className) {
-        return classCache.computeIfAbsent(className, s -> {
-            try {
-                return Class.forName(CONSCRYPT_PACKAGE + className);
-            } catch (ClassNotFoundException e) {
-                return null;
-            }
-        });
-    }
-
-    private Map<String, Method> buildMethodMap() {
-        Map<String, Method> classMap = new HashMap<>();
-        assertNotNull(classMap);
-        Class<?> nativeCryptoClass = conscryptClass("NativeCrypto");
-        assertNotNull(nativeCryptoClass);
-        for (Method method : nativeCryptoClass.getDeclaredMethods()) {
-            int modifiers = method.getModifiers();
-            if (!Modifier.isNative(modifiers)) {
-                continue;
-            }
-            method.setAccessible(true);
-            classMap.put(method.getName(), method);
-        }
-        return classMap;
-    }
-}
diff --git a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java
index 571c1a7..ff9be81 100644
--- a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java
+++ b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java
@@ -42,6 +42,7 @@
 import java.util.Arrays;
 import java.util.List;
 import org.junit.ClassRule;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
@@ -68,6 +69,7 @@
     }
 
     @Test
+    @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
     public void getEncodedFailsWhenCrtValuesMissing() throws Exception {
         PrivateKey privateKey = getPrivateKey();
         try {
@@ -119,6 +121,7 @@
     }
 
     @Test
+    @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
     public void javaSerialization() throws Exception{
         PrivateKey privatekey = getPrivateKey();
 
@@ -133,12 +136,13 @@
         assertEquals(privatekey, copy);
     }
 
-    @Override
-    protected List<KeyPair> getKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
-        return Arrays.asList(
-                new KeyPair(DefaultKeys.getPublicKey(algorithmName), getPrivateKey())
-        );
-    }
+    // b/209335673 Base image has fix for b/191150645 but release version of module does not,
+    // @Override
+    // protected List<KeyPair> getKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
+    //     return Arrays.asList(
+    //             new KeyPair(DefaultKeys.getPublicKey(algorithmName), getPrivateKey())
+    //     );
+    // }
 
     // The private RSA key returned by DefaultKeys.getPrivateKey() is built from a PKCS#8
     // KeySpec and so will be an instance of RSAPrivateCrtKey, but we want to test RSAPrivateKey
diff --git a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
index bddd898..3afa73f 100644
--- a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
+++ b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
@@ -30,6 +30,7 @@
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.RSAPrivateCrtKeySpec;
 import java.security.spec.RSAPublicKeySpec;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -59,7 +60,8 @@
   @Test
   public void testExtraBufferSpace_Private() throws Exception {
     PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
-    assertTrue(privateKey instanceof RSAPrivateCrtKey);
+    // b/209335673 Base image has fix for b/191150645 but release version of module does not
+    // assertTrue(privateKey instanceof RSAPrivateCrtKey);
 
     byte[] encoded = privateKey.getEncoded();
     byte[] longBuffer = new byte[encoded.length + 147];
@@ -70,6 +72,7 @@
   }
 
   @Test
+  @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
   public void javaSerialization() throws Exception{
     PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
     assertTrue(privateKey instanceof RSAPrivateCrtKey);
diff --git a/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java b/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
index ad5b52a..439b554 100644
--- a/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
+++ b/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
@@ -147,33 +147,6 @@
              || algorithm.equals("AES/OFB/PKCS7PADDING"))) {
             return false;
         }
-
-        if (provider.equals("BC")) {
-            return isSupportedByBC(algorithm);
-        }
-
-        return true;
-    }
-
-    /**
-     * Checks for algorithms removed from BC in Android 12 and so not usable for these
-     * tests.
-     *
-     * TODO(prb): make this version aware, as this test runs against BC on older Android
-     * versions via MTS and should continue to test these algorithms there.
-     *
-     */
-    private static boolean isSupportedByBC(String algorithm) {
-        String[] removedBcPrefices = new String[]{
-            "AES/ECB",
-            "AES/CBC",
-            "AES/GCM"
-        };
-        for (String prefix : removedBcPrefices) {
-            if (algorithm.startsWith(prefix)) {
-                return false;
-            }
-        }
         return true;
     }
 
@@ -1106,9 +1079,7 @@
                             for (String padding : paddings) {
                                 final String algorithmName = algorithm + "/" + mode + "/" + padding;
                                 try {
-                                    if (isSupported(algorithmName, provider.getName())) {
-                                        test_Cipher_Algorithm(provider, algorithmName);
-                                    }
+                                    test_Cipher_Algorithm(provider, algorithmName);
                                 } catch (Throwable e) {
                                     out.append("Error encountered checking " + algorithmName
                                                + " with provider " + provider.getName() + "\n");
@@ -3503,9 +3474,6 @@
             if (provider.equals("SunJCE") && transformation.endsWith("/PKCS7PADDING")) {
                 return false;
             }
-            if (provider.equals("BC")) {
-                return isSupportedByBC(transformation);
-            }
             return true;
         }
     }
@@ -4133,9 +4101,6 @@
         final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
         PrintStream out = new PrintStream(errBuffer);
         for (CipherTestParam p : CIPHER_TEST_PARAMS) {
-            if (!p.compatibleWith(provider)) {
-                continue;
-            }
             try {
                 checkCipher_ShortBlock_Failure(p, provider);
             } catch (Exception e) {
@@ -4335,6 +4300,32 @@
         }
     }
 
+    // Test that when reading GCM parameters encoded using ASN1, a value for the tag size
+    // not present indicates a value of 12.
+    // https://b/29876633
+    @Test
+    public void test_DefaultGCMTagSizeAlgorithmParameterSpec() throws Exception {
+        Assume.assumeNotNull(Security.getProvider("BC"));
+        final String AES = "AES";
+        final String AES_GCM = "AES/GCM/NoPadding";
+        byte[] input = new byte[16];
+        byte[] key = new byte[16];
+        Cipher cipher = Cipher.getInstance(AES_GCM, "BC");
+        AlgorithmParameters param = AlgorithmParameters.getInstance("GCM");
+        param.init(new byte[] {
+            (byte) 48,    // DER encoding : tag_Sequence
+            (byte) 14,    // DER encoding : total length
+            (byte) 4,     // DER encoding : tag_OctetString
+            (byte) 12,    // DER encoding : counter length
+            (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+            (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 });
+        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, AES), param);
+        byte[] ciphertext = cipher.update(input);
+        assertEquals(16, ciphertext.length);
+        byte[] tag = cipher.doFinal();
+        assertEquals(12, tag.length);
+    }
+
     @Test
     public void testAES_ECB_PKCS5Padding_ShortBuffer_Failure() throws Exception {
         for (String provider : AES_PROVIDERS) {
@@ -4397,11 +4388,7 @@
     }
 
     private void testAES_ECB_NoPadding_IncrementalUpdate_Success(String provider) throws Exception {
-        String algorithm = "AES/ECB/NoPadding";
-        if (!isSupported(algorithm, provider)) {
-            return;
-        }
-        Cipher c = Cipher.getInstance(algorithm, provider);
+        Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
         assertEquals(provider, c.getProvider().getName());
         c.init(Cipher.ENCRYPT_MODE, AES_128_KEY);
 
@@ -4435,11 +4422,7 @@
     }
 
     private void testAES_ECB_NoPadding_IvParameters_Failure(String provider) throws Exception {
-        String algorithm = "AES/ECB/NoPadding";
-        if (!isSupported(algorithm, provider)) {
-            return;
-        }
-        Cipher c = Cipher.getInstance(algorithm, provider);
+        Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
 
         AlgorithmParameterSpec spec = new IvParameterSpec(AES_IV_ZEROES);
         try {
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/NativeCryptoArgTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/NativeCryptoArgTest.java
deleted file mode 100644
index db096a0..0000000
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/NativeCryptoArgTest.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-/*
- * Copyright (C) 2020 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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.junit.AfterClass;
-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 NativeCryptoArgTest {
-    // Null value passed in for a long which represents a native address
-    private static final long NULL = 0L;
-    /*
-     * Non-null value passed in for a long which represents a native address. Shouldn't
-     * ever get de-referenced but we make it a multiple of 4 to avoid any alignment errors.
-     * Used in the case where there are multiple checks we want to test in a native method,
-     * so we can get past the first check and test the second one.
-     */
-    private static final long NOT_NULL = 4L;
-    private static final String CONSCRYPT_PACKAGE = NativeCryptoArgTest.class.getCanonicalName()
-            .substring(0, NativeCryptoArgTest.class.getCanonicalName().lastIndexOf('.') + 1);
-    private static final Set<String> testedMethods = new HashSet<>();
-    private final Map<String, Class<?>> classCache = new HashMap<>();
-    private final Map<String, Method> methodMap = buildMethodMap();
-
-    @AfterClass
-    public static void after() {
-        // TODO(prb): Temporary hacky check - remove
-        assertTrue(testedMethods.size() >= 190);
-    }
-
-    @Test
-    public void ecMethods() throws Throwable {
-        String[] illegalArgMethods = new String[] {
-                "EC_GROUP_new_arbitrary"
-        };
-        String[] ioExMethods = new String[] {
-                "EC_KEY_parse_curve_name",
-                "EC_KEY_marshal_curve_name"
-        };
-
-        // All of the EC_* methods apart from the exceptions below throw NPE if their
-        // first argument is null.
-        MethodFilter filter = MethodFilter.newBuilder("EC_ methods")
-                .hasPrefix("EC_")
-                .except(illegalArgMethods)
-                .except(ioExMethods)
-                .expectSize(16)
-                .build();
-        testMethods(filter, NullPointerException.class);
-
-        filter = MethodFilter.nameFilter("EC_ methods (IllegalArgument)", illegalArgMethods);
-        testMethods(filter, IllegalArgumentException.class);
-
-        filter = MethodFilter.nameFilter("EC_ methods (IOException)", ioExMethods);
-        testMethods(filter, IOException.class);
-    }
-
-    @Test
-    public void macMethods() throws Throwable {
-        // All of the non-void HMAC and CMAC methods throw NPE when passed a null pointer
-        MethodFilter filter = MethodFilter.newBuilder("HMAC methods")
-                .hasPrefix("HMAC_")
-                .takesArguments()
-                .expectSize(5)
-                .build();
-        testMethods(filter, NullPointerException.class);
-
-        filter = MethodFilter.newBuilder("CMAC methods")
-                .hasPrefix("CMAC_")
-                .takesArguments()
-                .expectSize(5)
-                .build();
-        testMethods(filter, NullPointerException.class);
-    }
-
-    @Test
-    public void sslMethods() throws Throwable {
-        // These methods don't throw on a null first arg as they can get called before the
-        // connection is fully initialised. However if the first arg is non-NULL, any subsequent
-        // null args should throw NPE.
-        String[] nonThrowingMethods = new String[] {
-                "SSL_interrupt",
-                "SSL_shutdown",
-                "ENGINE_SSL_shutdown",
-        };
-
-        // Most of the NativeSsl methods take a long holding a pointer to the native
-        // object followed by a {@code NativeSsl} holder object. However the second arg
-        // is unused(!) so we don't need to test it.
-        MethodFilter filter = MethodFilter.newBuilder("NativeSsl methods")
-                .hasArg(0, long.class)
-                .hasArg(1, conscryptClass("NativeSsl"))
-                .except(nonThrowingMethods)
-                .expectSize(60)
-                .build();
-
-        testMethods(filter, NullPointerException.class);
-
-        // Many of the SSL_* methods take a single long which points
-        // to a native object.
-        filter = MethodFilter.newBuilder("1-arg SSL methods")
-                .hasPrefix("SSL_")
-                .hasArgLength(1)
-                .hasArg(0, long.class)
-                .expectSize(10)
-                .build();
-
-        testMethods(filter, NullPointerException.class);
-
-        filter = MethodFilter.nameFilter("Non throwing NativeSsl methods", nonThrowingMethods);
-        testMethods(filter, null);
-
-        expectVoid("SSL_shutdown", NOT_NULL, null, null, null);
-        expectNPE("SSL_shutdown", NOT_NULL, null, new FileDescriptor(), null);
-        expectNPE("ENGINE_SSL_shutdown", NOT_NULL, null, null);
-        expectVoid("SSL_set_session", NOT_NULL, null, NULL);
-    }
-
-    @Test
-    public void evpMethods() throws Throwable {
-        String[] illegalArgMethods = new String[] {
-                "EVP_AEAD_CTX_open_buf",
-                "EVP_AEAD_CTX_seal_buf",
-                "EVP_PKEY_new_RSA"
-        };
-        String[] nonThrowingMethods = new String[] {
-                "EVP_MD_CTX_destroy",
-                "EVP_PKEY_CTX_free",
-                "EVP_PKEY_free",
-                "EVP_CIPHER_CTX_free"
-        };
-
-        // All of the non-void EVP_ methods apart from the above should throw on a null
-        // first argument.
-        MethodFilter filter = MethodFilter.newBuilder("EVP methods")
-                .hasPrefix("EVP_")
-                .takesArguments()
-                .except(illegalArgMethods)
-                .except(nonThrowingMethods)
-                .expectSize(45)
-                .build();
-
-        testMethods(filter, NullPointerException.class);
-
-        filter = MethodFilter.nameFilter("EVP methods (IllegalArgument)", illegalArgMethods);
-        testMethods(filter, IllegalArgumentException.class);
-
-        filter = MethodFilter.nameFilter("EVP methods (non-throwing)", nonThrowingMethods);
-        testMethods(filter, null);
-    }
-
-    @Test
-    public void x509Methods() throws Throwable {
-        // A number of X509 methods have a native pointer as arg 0 and an
-        // OpenSSLX509Certificate or OpenSSLX509CRL as arg 1.
-        MethodFilter filter = MethodFilter.newBuilder("X509 methods")
-                .hasArgLength(2)
-                .hasArg(0, long.class)
-                .hasArg(1, conscryptClass("OpenSSLX509Certificate"),
-                        conscryptClass("OpenSSLX509CRL"))
-                .expectSize(32)
-                .build();
-        // TODO(prb): test null second argument
-        testMethods(filter, NullPointerException.class);
-
-        // The rest of the X509 methods are somewhat ad hoc.
-        expectNPE("d2i_X509", (Object) null);
-
-        invokeAndExpect( conscryptThrowable("OpenSSLX509CertificateFactory$ParsingException"),
-                 "d2i_X509", new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0});
-
-        expectNPE("d2i_X509_bio", NULL);
-        expectNPE("PEM_read_bio_X509", NULL);
-        expectNPE("ASN1_seq_pack_X509", (Object) null);
-
-        // TODO(prb): Check what this should really throw
-        // expectNPE("ASN1_seq_pack_X509", (Object) new long[] { NULL });
-
-        expectNPE("ASN1_seq_unpack_X509_bio", NULL);
-
-        //
-        expectNPE("X509_cmp", NULL, null, NULL, null);
-        expectNPE("X509_cmp", NOT_NULL, null, NULL, null);
-        expectNPE("X509_cmp", NULL, null, NOT_NULL, null);
-
-        expectNPE("X509_print_ex", NULL, NULL, null, NULL, NULL);
-        expectNPE("X509_print_ex", NOT_NULL, NULL, null, NULL, NULL);
-        expectNPE("X509_print_ex", NULL, NOT_NULL, null, NULL, NULL);
-    }
-
-    private void testMethods(MethodFilter filter, Class<? extends Throwable> exceptionClass)
-            throws Throwable {
-        List<Method> methods = filter.filter(methodMap.values());
-
-        for (Method method : methods) {
-            List<Object[]> argsLists = permuteArgs(method);
-            for (Object[] args : argsLists) {
-                invokeAndExpect(exceptionClass, method, args);
-            }
-        }
-    }
-
-    private List<Object[]> permuteArgs(Method method) {
-        // For now just supply 0 for integral types and null for everything else
-        // TODO: allow user defined strategy, e.g. if two longs passed as native refs,
-        // generate {NULL,NULL}, {NULL,NOT_NULL}, {NOT_NULL,NULL} to test both null checks
-        List<Object[]> result = new ArrayList<>(1);
-
-        Class<?>[] argTypes = method.getParameterTypes();
-
-        int argCount = argTypes.length;
-        assertTrue(argCount > 0);
-        Object[] args = new Object[argCount];
-
-        for (int arg = 0; arg < argCount; arg++) {
-            if (argTypes[arg] == int.class) {
-                args[arg] = 0;
-            } else if (argTypes[arg] == long.class) {
-                args[arg] = NULL;
-            } else if (argTypes[arg] == boolean.class) {
-                args[arg] = false;
-            } else {
-                args[arg] = null;
-            }
-        }
-        result.add(args);
-        return result;
-    }
-
-    private void expectVoid(String methodName, Object... args) throws Throwable {
-        invokeAndExpect(null, methodName, args);
-    }
-
-    private void expectNPE(String methodName, Object... args) throws Throwable {
-        invokeAndExpect(NullPointerException.class, methodName, args);
-    }
-
-    private void invokeAndExpect(Class<? extends Throwable> expectedThrowable, String methodName,
-                                   Object... args) throws Throwable {
-        Method method = methodMap.get(methodName);
-        assertNotNull(method);
-        assertEquals(methodName, method.getName());
-        invokeAndExpect(expectedThrowable, method, args);
-    }
-
-    private void invokeAndExpect(Class<? extends Throwable> expectedThrowable, Method method,
-                                   Object... args) throws Throwable {
-        try {
-            method.invoke(null, args);
-            if (expectedThrowable != null) {
-                fail("No exception thrown by method " + method.getName());
-            }
-        } catch (IllegalAccessException e) {
-            throw new AssertionError("Illegal access", e);
-        } catch (InvocationTargetException e) {
-            Throwable cause = e.getCause();
-            if (expectedThrowable != null) {
-                assertEquals("Method: " + method.getName(), expectedThrowable, cause.getClass());
-            } else {
-                throw cause;
-            }
-        }
-        testedMethods.add(method.getName());
-    }
-
-    @SuppressWarnings("unchecked")
-    private Class<? extends Throwable> conscryptThrowable(String name) {
-        Class<?> klass = conscryptClass(name);
-        assertNotNull(klass);
-        assertTrue(Throwable.class.isAssignableFrom(klass));
-        return (Class<? extends Throwable>) klass;
-    }
-
-    private Class<?> conscryptClass(String className) {
-        return classCache.computeIfAbsent(className, s -> {
-            try {
-                return Class.forName(CONSCRYPT_PACKAGE + className);
-            } catch (ClassNotFoundException e) {
-                return null;
-            }
-        });
-    }
-
-    private Map<String, Method> buildMethodMap() {
-        Map<String, Method> classMap = new HashMap<>();
-        assertNotNull(classMap);
-        Class<?> nativeCryptoClass = conscryptClass("NativeCrypto");
-        assertNotNull(nativeCryptoClass);
-        for (Method method : nativeCryptoClass.getDeclaredMethods()) {
-            int modifiers = method.getModifiers();
-            if (!Modifier.isNative(modifiers)) {
-                continue;
-            }
-            method.setAccessible(true);
-            classMap.put(method.getName(), method);
-        }
-        return classMap;
-    }
-}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
index b4287f9..1c51b59 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
@@ -43,6 +43,7 @@
 import java.util.List;
 import libcore.junit.util.EnableDeprecatedBouncyCastleAlgorithmsRule;
 import org.junit.ClassRule;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
@@ -71,6 +72,7 @@
     }
 
     @Test
+    @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
     public void getEncodedFailsWhenCrtValuesMissing() throws Exception {
         PrivateKey privateKey = getPrivateKey();
         try {
@@ -122,6 +124,7 @@
     }
 
     @Test
+    @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
     public void javaSerialization() throws Exception {
         PrivateKey privatekey = getPrivateKey();
 
@@ -136,10 +139,13 @@
         assertEquals(privatekey, copy);
     }
 
-    @Override
-    protected List<KeyPair> getKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
-        return Arrays.asList(new KeyPair(DefaultKeys.getPublicKey(algorithmName), getPrivateKey()));
-    }
+    // b/209335673 Base image has fix for b/191150645 but release version of module does not,
+    // @Override
+    // protected List<KeyPair> getKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
+    //     return Arrays.asList(
+    //             new KeyPair(DefaultKeys.getPublicKey(algorithmName), getPrivateKey())
+    //     );
+    // }
 
     // The private RSA key returned by DefaultKeys.getPrivateKey() is built from a PKCS#8
     // KeySpec and so will be an instance of RSAPrivateCrtKey, but we want to test RSAPrivateKey
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
index 5e84e7c..d8d8ebe 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
@@ -31,6 +31,7 @@
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.RSAPrivateCrtKeySpec;
 import java.security.spec.RSAPublicKeySpec;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -63,7 +64,8 @@
   @Test
   public void testExtraBufferSpace_Private() throws Exception {
       PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
-      assertTrue(privateKey instanceof RSAPrivateCrtKey);
+      // b/209335673 Base image has fix for b/191150645 but release version of module does not
+      // assertTrue(privateKey instanceof RSAPrivateCrtKey);
 
       byte[] encoded = privateKey.getEncoded();
       byte[] longBuffer = new byte[encoded.length + 147];
@@ -74,6 +76,7 @@
   }
 
   @Test
+  @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
   public void javaSerialization() throws Exception {
       PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
       assertTrue(privateKey instanceof RSAPrivateCrtKey);
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
index 37c702b..a418d67 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
@@ -151,29 +151,6 @@
              || algorithm.equals("AES/OFB/PKCS7PADDING"))) {
             return false;
         }
-
-        if (provider.equals("BC")) {
-            return isSupportedByBC(algorithm);
-        }
-
-        return true;
-    }
-
-    /**
-     * Checks for algorithms removed from BC in Android 12 and so not usable for these
-     * tests.
-     *
-     * TODO(prb): make this version aware, as this test runs against BC on older Android
-     * versions via MTS and should continue to test these algorithms there.
-     *
-     */
-    private static boolean isSupportedByBC(String algorithm) {
-        String[] removedBcPrefices = new String[] {"AES/ECB", "AES/CBC", "AES/GCM"};
-        for (String prefix : removedBcPrefices) {
-            if (algorithm.startsWith(prefix)) {
-                return false;
-            }
-        }
         return true;
     }
 
@@ -1106,9 +1083,7 @@
                             for (String padding : paddings) {
                                 final String algorithmName = algorithm + "/" + mode + "/" + padding;
                                 try {
-                                    if (isSupported(algorithmName, provider.getName())) {
-                                        test_Cipher_Algorithm(provider, algorithmName);
-                                    }
+                                    test_Cipher_Algorithm(provider, algorithmName);
                                 } catch (Throwable e) {
                                     out.append("Error encountered checking " + algorithmName
                                                + " with provider " + provider.getName() + "\n");
@@ -3494,9 +3469,6 @@
             if (provider.equals("SunJCE") && transformation.endsWith("/PKCS7PADDING")) {
                 return false;
             }
-            if (provider.equals("BC")) {
-                return isSupportedByBC(transformation);
-            }
             return true;
         }
     }
@@ -4125,9 +4097,6 @@
         final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
         PrintStream out = new PrintStream(errBuffer);
         for (CipherTestParam p : CIPHER_TEST_PARAMS) {
-            if (!p.compatibleWith(provider)) {
-                continue;
-            }
             try {
                 checkCipher_ShortBlock_Failure(p, provider);
             } catch (Exception e) {
@@ -4327,6 +4296,32 @@
         }
     }
 
+    // Test that when reading GCM parameters encoded using ASN1, a value for the tag size
+    // not present indicates a value of 12.
+    // https://b/29876633
+    @Test
+    public void test_DefaultGCMTagSizeAlgorithmParameterSpec() throws Exception {
+        Assume.assumeNotNull(Security.getProvider("BC"));
+        final String AES = "AES";
+        final String AES_GCM = "AES/GCM/NoPadding";
+        byte[] input = new byte[16];
+        byte[] key = new byte[16];
+        Cipher cipher = Cipher.getInstance(AES_GCM, "BC");
+        AlgorithmParameters param = AlgorithmParameters.getInstance("GCM");
+        param.init(new byte[] {
+            (byte) 48,    // DER encoding : tag_Sequence
+            (byte) 14,    // DER encoding : total length
+            (byte) 4,     // DER encoding : tag_OctetString
+            (byte) 12,    // DER encoding : counter length
+            (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+            (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 });
+        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, AES), param);
+        byte[] ciphertext = cipher.update(input);
+        assertEquals(16, ciphertext.length);
+        byte[] tag = cipher.doFinal();
+        assertEquals(12, tag.length);
+    }
+
     @Test
     public void testAES_ECB_PKCS5Padding_ShortBuffer_Failure() throws Exception {
         for (String provider : AES_PROVIDERS) {
@@ -4389,11 +4384,7 @@
     }
 
     private void testAES_ECB_NoPadding_IncrementalUpdate_Success(String provider) throws Exception {
-        String algorithm = "AES/ECB/NoPadding";
-        if (!isSupported(algorithm, provider)) {
-            return;
-        }
-        Cipher c = Cipher.getInstance(algorithm, provider);
+        Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
         assertEquals(provider, c.getProvider().getName());
         c.init(Cipher.ENCRYPT_MODE, AES_128_KEY);
 
@@ -4427,11 +4418,7 @@
     }
 
     private void testAES_ECB_NoPadding_IvParameters_Failure(String provider) throws Exception {
-        String algorithm = "AES/ECB/NoPadding";
-        if (!isSupported(algorithm, provider)) {
-            return;
-        }
-        Cipher c = Cipher.getInstance(algorithm, provider);
+        Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
 
         AlgorithmParameterSpec spec = new IvParameterSpec(AES_IV_ZEROES);
         try {
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/MethodFilter.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/MethodFilter.java
deleted file mode 100644
index 680abd7..0000000
--- a/repackaged/testing/src/main/java/com/android/org/conscrypt/MethodFilter.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.conscrypt;
-
-import static org.junit.Assert.assertTrue;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Predicate;
-
-
-/**
- * Test support class for filtering collections of {@link Method}.  Each filter is a list of
- * predicates which must all be true for a Method in order for it to be included it the output.
- * @hide This class is not part of the Android public SDK API
- */
-public class MethodFilter {
-    private final String name;
-    private final CompoundMethodPredicate predicates = new CompoundMethodPredicate();
-    private int expectedSize = 0;
-
-    public MethodFilter(String name) {
-        this.name = name;
-    }
-
-    public List<Method> filter(Iterable<Method> input) {
-        List<Method> result = new ArrayList<>();
-        for (Method method : input) {
-            if (predicates.test(method)) {
-                result.add(method);
-            }
-        }
-        if (expectedSize != 0) {
-            assertTrue(String.format("Filter %s only returned %d methods, expected at least %d",
-                    name, result.size(), expectedSize), result.size() >= expectedSize);
-        }
-        return result;
-    }
-
-    /** Returns a new {@link Builder} */
-    public static Builder newBuilder(String name) {
-        return new Builder(name);
-    }
-
-    /** Returns a filter which selects only methods named in {@code methodNames} */
-    public static MethodFilter nameFilter(String name, String... methodNames) {
-        return newBuilder(name)
-                .named(methodNames)
-                .expectSize(methodNames.length)
-                .build();
-    }
-
-    private void addPredicate(Predicate<Method> predicate) {
-        predicates.add(predicate);
-    }
-
-    /**
-     * @hide This class is not part of the Android public SDK API
-     */
-    public static class Builder {
-        private final MethodFilter filter;
-
-        private Builder(String name) {
-            filter = new MethodFilter(name);
-        }
-
-        /** Method's simple name must start with {@code prefix}.  */
-        public Builder hasPrefix(String prefix) {
-            filter.addPredicate(new MethodNamePrefixPredicate(prefix));
-            return this;
-        }
-
-        /** Argument at {@code position} must be one of the supplied {@code classes}. */
-        public Builder hasArg(int position, Class<?>... classes) {
-            filter.addPredicate(new MethodArgPredicate(position, classes));
-            return this;
-        }
-
-        /** Method must take exactly {@code length} args. */
-        public Builder hasArgLength(int length) {
-            filter.addPredicate(new MethodArgLengthPredicate(length));
-            return this;
-        }
-
-        /* Method must take one or more arguments, i.e. not void. */
-        public Builder takesArguments() {
-            filter.addPredicate(new MethodArgLengthPredicate(0).negate());
-            return this;
-        }
-
-        /** Method's simple name is in the list of {@code names} provided. */
-        public Builder named(String... names) {
-            filter.addPredicate(new MethodNamePredicate(names));
-            return this;
-        }
-
-        /** Method's simple name is NOT in the list of {@code names} provided. */
-        public Builder except(String... names) {
-            filter.addPredicate(new MethodNamePredicate(names).negate());
-            return this;
-        }
-
-        /** Expect at least {@code size} matching methods when filtering, otherwise filter()
-         * will throw {@code AssertionError} */
-        public Builder expectSize(int size) {
-            filter.expectedSize = size;
-            return this;
-        }
-
-        public MethodFilter build() {
-            return filter;
-        }
-    }
-
-    // Implements Builder.hasPrefix()
-    private static class MethodNamePrefixPredicate implements Predicate<Method> {
-        private final String prefix;
-
-        public MethodNamePrefixPredicate(String prefix) {
-            this.prefix = prefix;
-        }
-
-        @Override
-        public boolean test(Method method) {
-            return method.getName().startsWith(prefix);
-        }
-    }
-
-    // Implements Builder.named()
-    private static class MethodNamePredicate implements Predicate<Method> {
-        private final List<String> names;
-
-        public MethodNamePredicate(String... names) {
-            this.names = Arrays.asList(names);
-        }
-
-        @Override
-        public boolean test(Method method) {
-            return names.contains(method.getName());
-        }
-    }
-
-    // Implements Builder.hasArg()
-    private static class MethodArgPredicate implements Predicate<Method> {
-        private final int position;
-        private final List<Class<?>> allowedClasses;
-
-        public MethodArgPredicate(int position, Class<?>... classes) {
-            this.position = position;
-            allowedClasses = Arrays.asList(classes);
-        }
-
-        @Override
-        public boolean test(Method method) {
-            Class<?>[] argTypes = method.getParameterTypes();
-            if (argTypes.length > position) {
-                for (Class<?> c : allowedClasses) {
-                    if (argTypes[position] == c) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-    }
-
-    // Implements Builder.hasArgLength()
-    private static class MethodArgLengthPredicate implements Predicate<Method> {
-        private final int length;
-
-        public MethodArgLengthPredicate(int length) {
-            this.length = length;
-        }
-
-        @Override
-        public boolean test(Method method) {
-            return method.getParameterCount() == length;
-        }
-    }
-
-    // A Predicate which contains a list of sub-Predicates, all of which must be true
-    // for this one to be true.
-    private static class CompoundMethodPredicate implements Predicate<Method> {
-        private final List<Predicate<Method>> predicates = new ArrayList<>();
-
-        @Override
-        public boolean test(Method method) {
-            for (Predicate<Method> p : predicates) {
-                if (!p.test(method)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        public void add(Predicate<Method> predicate) {
-            predicates.add(predicate);
-        }
-    }
-}
\ No newline at end of file
diff --git a/testing/src/main/java/org/conscrypt/MethodFilter.java b/testing/src/main/java/org/conscrypt/MethodFilter.java
deleted file mode 100644
index 0939d4b..0000000
--- a/testing/src/main/java/org/conscrypt/MethodFilter.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package org.conscrypt;
-
-import static org.junit.Assert.assertTrue;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Predicate;
-
-
-/**
- * Test support class for filtering collections of {@link Method}.  Each filter is a list of
- * predicates which must all be true for a Method in order for it to be included it the output.
- */
-public class MethodFilter {
-    private final String name;
-    private final CompoundMethodPredicate predicates = new CompoundMethodPredicate();
-    private int expectedSize = 0;
-
-    public MethodFilter(String name) {
-        this.name = name;
-    }
-
-    public List<Method> filter(Iterable<Method> input) {
-        List<Method> result = new ArrayList<>();
-        for (Method method : input) {
-            if (predicates.test(method)) {
-                result.add(method);
-            }
-        }
-        if (expectedSize != 0) {
-            assertTrue(String.format("Filter %s only returned %d methods, expected at least %d",
-                    name, result.size(), expectedSize), result.size() >= expectedSize);
-        }
-        return result;
-    }
-
-    /** Returns a new {@link Builder} */
-    public static Builder newBuilder(String name) {
-        return new Builder(name);
-    }
-
-    /** Returns a filter which selects only methods named in {@code methodNames} */
-    public static MethodFilter nameFilter(String name, String... methodNames) {
-        return newBuilder(name)
-                .named(methodNames)
-                .expectSize(methodNames.length)
-                .build();
-    }
-
-    private void addPredicate(Predicate<Method> predicate) {
-        predicates.add(predicate);
-    }
-
-    public static class Builder {
-        private final MethodFilter filter;
-
-        private Builder(String name) {
-            filter = new MethodFilter(name);
-        }
-
-        /** Method's simple name must start with {@code prefix}.  */
-        public Builder hasPrefix(String prefix) {
-            filter.addPredicate(new MethodNamePrefixPredicate(prefix));
-            return this;
-        }
-
-        /** Argument at {@code position} must be one of the supplied {@code classes}. */
-        public Builder hasArg(int position, Class<?>... classes) {
-            filter.addPredicate(new MethodArgPredicate(position, classes));
-            return this;
-        }
-
-        /** Method must take exactly {@code length} args. */
-        public Builder hasArgLength(int length) {
-            filter.addPredicate(new MethodArgLengthPredicate(length));
-            return this;
-        }
-
-        /* Method must take one or more arguments, i.e. not void. */
-        public Builder takesArguments() {
-            filter.addPredicate(new MethodArgLengthPredicate(0).negate());
-            return this;
-        }
-
-        /** Method's simple name is in the list of {@code names} provided. */
-        public Builder named(String... names) {
-            filter.addPredicate(new MethodNamePredicate(names));
-            return this;
-        }
-
-        /** Method's simple name is NOT in the list of {@code names} provided. */
-        public Builder except(String... names) {
-            filter.addPredicate(new MethodNamePredicate(names).negate());
-            return this;
-        }
-
-        /** Expect at least {@code size} matching methods when filtering, otherwise filter()
-         * will throw {@code AssertionError} */
-        public Builder expectSize(int size) {
-            filter.expectedSize = size;
-            return this;
-        }
-
-        public MethodFilter build() {
-            return filter;
-        }
-    }
-
-    // Implements Builder.hasPrefix()
-    private static class MethodNamePrefixPredicate implements Predicate<Method> {
-        private final String prefix;
-
-        public MethodNamePrefixPredicate(String prefix) {
-            this.prefix = prefix;
-        }
-
-        @Override
-        public boolean test(Method method) {
-            return method.getName().startsWith(prefix);
-        }
-    }
-
-    // Implements Builder.named()
-    private static class MethodNamePredicate implements Predicate<Method> {
-        private final List<String> names;
-
-        public MethodNamePredicate(String... names) {
-            this.names = Arrays.asList(names);
-        }
-
-        @Override
-        public boolean test(Method method) {
-            return names.contains(method.getName());
-        }
-    }
-
-    // Implements Builder.hasArg()
-    private static class MethodArgPredicate implements Predicate<Method> {
-        private final int position;
-        private final List<Class<?>> allowedClasses;
-
-        public MethodArgPredicate(int position, Class<?>... classes) {
-            this.position = position;
-            allowedClasses = Arrays.asList(classes);
-        }
-
-        @Override
-        public boolean test(Method method) {
-            Class<?>[] argTypes = method.getParameterTypes();
-            if (argTypes.length > position) {
-                for (Class<?> c : allowedClasses) {
-                    if (argTypes[position] == c) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-    }
-
-    // Implements Builder.hasArgLength()
-    private static class MethodArgLengthPredicate implements Predicate<Method> {
-        private final int length;
-
-        public MethodArgLengthPredicate(int length) {
-            this.length = length;
-        }
-
-        @Override
-        public boolean test(Method method) {
-            return method.getParameterCount() == length;
-        }
-    }
-
-    // A Predicate which contains a list of sub-Predicates, all of which must be true
-    // for this one to be true.
-    private static class CompoundMethodPredicate implements Predicate<Method> {
-        private final List<Predicate<Method>> predicates = new ArrayList<>();
-
-        @Override
-        public boolean test(Method method) {
-            for (Predicate<Method> p : predicates) {
-                if (!p.test(method)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        public void add(Predicate<Method> predicate) {
-            predicates.add(predicate);
-        }
-    }
-}
\ No newline at end of file